VRFS-1654 issue fixed without test
This commit is contained in:
commit
6ecb7abcad
|
|
@ -6,4 +6,3 @@
|
|||
HTML
|
||||
.DS_Store
|
||||
coverage
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
source 'http://rubygems.org'
|
||||
|
||||
source 'https://jamjam:blueberryjam@int.jamkazam.com/gems/'
|
||||
devenv = ENV["BUILD_NUMBER"].nil? # Jenkins sets a build number environment variable
|
||||
devenv = ENV["BUILD_NUMBER"].nil? || ENV["TEST_WWW"] == "1"
|
||||
|
||||
if devenv
|
||||
gem 'jam_db', :path=> "../db/target/ruby_package"
|
||||
|
|
@ -102,7 +102,6 @@ group :development, :test do
|
|||
gem 'rspec-rails'
|
||||
gem 'guard-rspec', '0.5.5'
|
||||
gem 'jasmine', '1.3.1'
|
||||
# gem 'pry'
|
||||
gem 'execjs', '1.4.0'
|
||||
gem 'therubyracer' #, '0.11.0beta8'
|
||||
gem 'factory_girl_rails', '4.1.0'
|
||||
|
|
@ -114,6 +113,9 @@ end
|
|||
group :test do
|
||||
gem 'simplecov', '~> 0.7.1'
|
||||
gem 'simplecov-rcov'
|
||||
gem 'capybara-webkit'
|
||||
gem 'capybara-screenshot'
|
||||
gem 'poltergeist'
|
||||
end
|
||||
|
||||
gem 'pry'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ ActiveAdmin.register_page "Dashboard" do
|
|||
column do
|
||||
panel "Recent Sessions" do
|
||||
ul do
|
||||
MusicSessionHistory.order('created_at desc').limit(5).map do |music_session|
|
||||
MusicSession.order('created_at desc').limit(5).map do |music_session|
|
||||
li do
|
||||
text_node "'#{music_session.description}' created by #{User.find(music_session.user_id).name} at #{music_session.created_at}, "
|
||||
text_node " members: "
|
||||
|
|
@ -38,7 +38,7 @@ ActiveAdmin.register_page "Dashboard" do
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# column do
|
||||
|
|
|
|||
|
|
@ -3,36 +3,58 @@ ActiveAdmin.register_page 'Feed' do
|
|||
|
||||
# get user information via params
|
||||
user_id = nil
|
||||
user_id = params[:feed][:user_id] if params[:feed]
|
||||
user_name = User.find(user_id).name if user_id
|
||||
user_name = "All" unless user_id
|
||||
user_id = params[:feed][:user_id] if params[:feed] && params[:feed][:user_id] != ''
|
||||
user_name = 'All'
|
||||
user_name = User.find(user_id).to_label if user_id
|
||||
|
||||
render :partial => 'form', :locals => {param: params}
|
||||
render :partial => 'form', locals: {user_name: user_name, user_id: user_id }
|
||||
|
||||
offset = 0
|
||||
limit = 10
|
||||
page = (params[:page] ||= 1).to_i
|
||||
per_page = 10
|
||||
offset = (page - 1) * per_page
|
||||
|
||||
# get feed ids
|
||||
where_sql = ''
|
||||
where_sql = "where user_id = '#{user_id}'" if user_id
|
||||
sql_feed_ids = "SELECT id, 'music_session_histories' as type, created_at FROM music_sessions_history #{where_sql}
|
||||
sql_feed_ids = "SELECT id, 'music_sessions' as type, created_at FROM music_sessions #{where_sql}
|
||||
UNION ALL
|
||||
SELECT DISTINCT recording_id as id, 'recordings' as type, created_at FROM recorded_tracks #{where_sql}
|
||||
UNION ALL
|
||||
SELECT id, 'diagnostics' as type, created_at FROM diagnostics #{where_sql}
|
||||
ORDER BY created_at DESC
|
||||
OFFSET #{offset}
|
||||
LIMIT #{limit};"
|
||||
LIMIT #{per_page};"
|
||||
|
||||
models = []
|
||||
sql_feed_count = "SELECT COUNT(*) FROM (
|
||||
SELECT id, 'music_sessions' as type, created_at FROM music_sessions #{where_sql}
|
||||
UNION ALL
|
||||
SELECT DISTINCT recording_id as id, 'recordings' as type, created_at FROM recorded_tracks #{where_sql}
|
||||
UNION ALL
|
||||
SELECT id, 'diagnostics' as type, created_at FROM diagnostics #{where_sql}
|
||||
ORDER BY created_at DESC
|
||||
) AS IDS;"
|
||||
feed_count = ActiveRecord::Base.connection.execute(sql_feed_count).values[0][0].to_i
|
||||
id_types = ActiveRecord::Base.connection.execute(sql_feed_ids).values
|
||||
|
||||
@feed_pages = WillPaginate::Collection.create(page, per_page) do |pager|
|
||||
pager.total_entries = feed_count
|
||||
pager.replace(id_types)
|
||||
end
|
||||
|
||||
div class: 'feed-pagination' do
|
||||
will_paginate @feed_pages
|
||||
end
|
||||
|
||||
recordings = []
|
||||
sessions = []
|
||||
diagnostics = []
|
||||
id_types.each do |id_and_type|
|
||||
if id_and_type[1] == "music_session_histories"
|
||||
models << JamRuby::MusicSessionHistory.find(id_and_type[0])
|
||||
# elsif id_and_type[1] == "recordings"
|
||||
# models << JamRuby::Recording.find(id_and_type[0])
|
||||
if id_and_type[1] == "music_sessions"
|
||||
sessions << JamRuby::MusicSession.find(id_and_type[0])
|
||||
elsif id_and_type[1] == "recordings"
|
||||
models << JamRuby::Diagnostics.find(id_and_type[0])
|
||||
recordings << JamRuby::Recording.find(id_and_type[0])
|
||||
elsif id_and_type[1] == "diagnostics"
|
||||
diagnostics << JamRuby::Diagnostic.find(id_and_type[0])
|
||||
else
|
||||
raise "Unknown type returned from feed ids"
|
||||
end
|
||||
|
|
@ -40,22 +62,160 @@ ActiveAdmin.register_page 'Feed' do
|
|||
|
||||
columns do
|
||||
column do
|
||||
panel "Activity - #{user_name}" do
|
||||
para id_types.inspect
|
||||
ul do
|
||||
models.each do |model|
|
||||
li do
|
||||
text_node model.inspect
|
||||
panel "Music Sessions - #{user_name}" do
|
||||
if sessions.count > 0
|
||||
table_for(sessions) do
|
||||
column :creator do |msh|
|
||||
link_to msh.creator.to_label, admin_feed_path({feed: {user_id: msh.creator.id}})
|
||||
end
|
||||
column :created_at do |msh| msh.created_at.strftime('%b %d %Y, %H:%M') end
|
||||
column :duration do |msh| "#{msh.duration_minutes.round(2)} minutes" end
|
||||
column :members do |msh|
|
||||
uu = msh.unique_users
|
||||
if uu.length > 0
|
||||
uu.each do |u|
|
||||
span link_to u.to_label + ', ', admin_feed_path({feed: {user_id: u.id}})
|
||||
end
|
||||
else
|
||||
span para 'No members'
|
||||
end
|
||||
end
|
||||
|
||||
column :band do |msh| auto_link(msh.band, msh.band.try(:name)) end
|
||||
column :fan_access do |msh| msh.fan_access end
|
||||
column :plays do |msh| msh.plays.count end
|
||||
column :likes do |msh| msh.likes.count end
|
||||
column :comments do |msh|
|
||||
if msh.comment_count > 0
|
||||
text_node "(#{msh.comment_count}) "
|
||||
msh.comments.each do |comment|
|
||||
text_node comment.user.to_label + ', '
|
||||
end
|
||||
else
|
||||
span para 'No comments'
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
span class: 'text-center' do
|
||||
para 'No session activities.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
panel "Recordings - #{user_name}" do
|
||||
if recordings.count > 0
|
||||
table_for(recordings) do
|
||||
column :starter do |rec|
|
||||
link_to rec.owner.to_label, admin_feed_path({feed: {user_id: rec.owner.id}})
|
||||
end
|
||||
column :mixes do |rec|
|
||||
ul do
|
||||
mixes = rec.mixes
|
||||
if mixes.count > 0
|
||||
mixes.each do |mix|
|
||||
li do
|
||||
text_node "Created At: #{mix.created_at.strftime('%b %d %Y, %H:%M')}, "
|
||||
text_node "Started At: #{mix.started_at.strftime('%b %d %Y, %H:%M')}, "
|
||||
text_node "Completed At: #{mix.completed_at.strftime('%b %d %Y, %H:%M')}, "
|
||||
text_node "Error Count: #{mix.error_count}, "
|
||||
text_node "Error Reason: #{mix.error_reason}, "
|
||||
text_node "Error Detail: #{mix.error_detail}, "
|
||||
text_node "Download Count: #{mix.download_count}, "
|
||||
if !mix.nil? && !mix[:ogg_url].nil?
|
||||
span link_to 'Download OGG', mix.sign_url(3600, 'ogg')
|
||||
else
|
||||
text_node 'OGG download not available'
|
||||
end
|
||||
if !mix.nil? && !mix[:mp3_url].nil?
|
||||
span link_to 'Download MP3', mix.sign_url(3600, 'mp3')
|
||||
else
|
||||
text_node 'MP3 download not available'
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
span para 'No mixes'
|
||||
end
|
||||
end
|
||||
end
|
||||
column :recorded_tracks do |rec|
|
||||
ul do
|
||||
rts = rec.recorded_tracks
|
||||
if rts.count > 0
|
||||
rts.each do |gt|
|
||||
li do
|
||||
span link_to gt.musician.to_label, admin_feed_path({feed: {user_id: gt.musician.id}})
|
||||
span ", #{gt.instrument_id}, "
|
||||
span "Download Count: #{gt.download_count}, "
|
||||
span "Fully uploaded: #{gt.fully_uploaded}, "
|
||||
span "Upload failures: #{gt.upload_failures}, "
|
||||
span "Part failures: #{gt.part_failures}, "
|
||||
if gt[:url]
|
||||
# span link_to 'Download', gt.sign_url(3600)
|
||||
else
|
||||
span 'No track available'
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
span para 'No recorded tracks'
|
||||
end
|
||||
end
|
||||
end
|
||||
column :claimed_recordings do |rec|
|
||||
ul do
|
||||
crs = rec.claimed_recordings
|
||||
if crs.count > 0
|
||||
crs.each do |cr|
|
||||
li do
|
||||
span cr.name
|
||||
span link_to cr.user.to_label, admin_feed_path({feed: {user_id: cr.user.id}})
|
||||
span ", Public: #{cr.is_public}"
|
||||
end
|
||||
end
|
||||
else
|
||||
span para 'No claimed recordings'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
span class: 'text-center' do
|
||||
para 'No recording activities.'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
panel "Diagnostics - #{user_name}" do
|
||||
if diagnostics.count > 0 then
|
||||
table_for(diagnostics) do
|
||||
column :user do |d|
|
||||
span link_to d.user.to_label, admin_feed_path({feed: {user_id: d.user.id}})
|
||||
end
|
||||
column :created_at do |d| d.created_at.strftime('%b %d %Y, %H:%M') end
|
||||
column :type
|
||||
column :creator
|
||||
column :data do |d|
|
||||
span style: "white-space: pre;" do
|
||||
if JSON.parse(d.data).all?
|
||||
JSON.pretty_generate(JSON.parse(d.data))
|
||||
else
|
||||
d.data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
span class: 'text-center' do
|
||||
para 'No diagnostic activities.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
controller do
|
||||
def index
|
||||
div class: 'feed-pagination' do
|
||||
will_paginate @feed_pages
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -24,8 +24,8 @@ ActiveAdmin.register JamRuby::Mix, :as => 'Mixes' do
|
|||
attributes_table_for(mix) do
|
||||
row :recording do |mix| auto_link(mix.recording, mix.recording.id) end
|
||||
row :created_at do |mix| mix.created_at.strftime('%b %d %Y, %H:%M') end
|
||||
# row :s3_url do |mix| mix.url end
|
||||
# row :manifest do |mix| mix.manifest end
|
||||
row :s3_url do |mix| mix.sign_url end
|
||||
row :manifest do |mix| mix.manifest end
|
||||
row :completed do |mix| "#{mix.completed ? "finished" : "not finished"}" end
|
||||
if mix.completed
|
||||
row :completed_at do |mix| mix.completed_at.strftime('%b %d %Y, %H:%M') end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History' do
|
||||
ActiveAdmin.register JamRuby::MusicSession, :as => 'Music Session' do
|
||||
|
||||
config.filters = false
|
||||
config.per_page = 50
|
||||
|
|
@ -9,14 +9,14 @@ ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History
|
|||
controller do
|
||||
def scoped_collection
|
||||
if params['admin'].blank? || '1' == params['admin']
|
||||
@music_session_histories ||= end_of_association_chain
|
||||
.includes([:user, :band])
|
||||
@music_sessions ||= end_of_association_chain
|
||||
.includes([:creator, :band])
|
||||
.order('created_at DESC')
|
||||
else
|
||||
@music_session_histories ||= end_of_association_chain
|
||||
.joins('INNER JOIN users AS uu ON uu.id = music_sessions_history.user_id')
|
||||
@music_sessions ||= end_of_association_chain
|
||||
.joins('INNER JOIN users AS uu ON uu.id = music_sessions.user_id')
|
||||
.where(['uu.admin = ?','f'])
|
||||
.includes([:user, :band])
|
||||
.includes([:creator, :band])
|
||||
.order('created_at DESC')
|
||||
end
|
||||
end
|
||||
|
|
@ -33,9 +33,9 @@ ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History
|
|||
row :description
|
||||
row :duration do |msh| "#{msh.duration_minutes} minutes" end
|
||||
row :active do |msh| msh.session_removed_at.nil? end
|
||||
row :creator do |msh| auto_link(msh.user, msh.user.try(:email)) end
|
||||
row :creator do |msh| auto_link(msh.creator, msh.creator.try(:email)) end
|
||||
row :band do |msh| auto_link(msh.band, msh.band.try(:name)) end
|
||||
row :genres
|
||||
row :genre
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,8 +4,13 @@
|
|||
color:lightgray;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feed-pagination {
|
||||
height: 20px;
|
||||
margin-bottom: 15px;
|
||||
.pagination {
|
||||
float: left !important;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<%= semantic_form_for :feed, url: admin_feed_path, method: :get do |f| %>
|
||||
<%= f.inputs do %>
|
||||
<%= f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { :id_element => "#feed_user_id" }%>
|
||||
<%= f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { :id_element => "#feed_user_id" } %>
|
||||
<%= f.input :user_id, :as => :hidden %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<table class="index_table index">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>User Name - <%= @user_id %></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @users.each do |user| %>
|
||||
<tr class="odd">
|
||||
<td>
|
||||
<p>
|
||||
<%= link_to admin_feed_path(feed: {user_id: user.id}) do %>
|
||||
<%= user.name %>
|
||||
<% end %></p>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="feed-pagination">
|
||||
<%= will_paginate @users %>
|
||||
</div>
|
||||
|
|
@ -23,7 +23,7 @@ FactoryGirl.define do
|
|||
|
||||
factory :single_user_session do
|
||||
after(:create) do |user, evaluator|
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user)
|
||||
connection = FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
end
|
||||
end
|
||||
|
|
@ -46,4 +46,131 @@ FactoryGirl.define do
|
|||
description { |n| "Instrument #{n}" }
|
||||
end
|
||||
|
||||
factory :genre, :class => JamRuby::Genre do
|
||||
description { |n| "Genre #{n}" }
|
||||
end
|
||||
|
||||
factory :music_session, :class => JamRuby::MusicSession do
|
||||
sequence(:name) { |n| "Music Session #{n}" }
|
||||
sequence(:description) { |n| "Music Session Description #{n}" }
|
||||
fan_chat true
|
||||
fan_access true
|
||||
approval_required false
|
||||
musician_access true
|
||||
legal_terms true
|
||||
language 'english'
|
||||
legal_policy 'standard'
|
||||
genre JamRuby::Genre.first
|
||||
association :creator, :factory => :user
|
||||
end
|
||||
|
||||
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
|
||||
ignore do
|
||||
history nil
|
||||
user nil
|
||||
end
|
||||
|
||||
music_session_id { history.id }
|
||||
user_id { user.id }
|
||||
sequence(:client_id) { |n| "Connection #{n}" }
|
||||
end
|
||||
|
||||
factory :recorded_track, :class => JamRuby::RecordedTrack do
|
||||
instrument JamRuby::Instrument.first
|
||||
sound 'stereo'
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:track_id) { |n| "track_id-#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}"}
|
||||
md5 'abc'
|
||||
length 1
|
||||
fully_uploaded true
|
||||
association :user, factory: :user
|
||||
association :recording, factory: :recording
|
||||
end
|
||||
|
||||
factory :recording, :class => JamRuby::Recording do
|
||||
|
||||
association :owner, factory: :user
|
||||
association :music_session, factory: :active_music_session
|
||||
|
||||
factory :recording_with_track do
|
||||
before(:create) { |recording|
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
factory :claimed_recording, :class => JamRuby::ClaimedRecording do
|
||||
sequence(:name) { |n| "name-#{n}" }
|
||||
sequence(:description) { |n| "description-#{n}" }
|
||||
is_public true
|
||||
association :genre, factory: :genre
|
||||
association :user, factory: :user
|
||||
|
||||
before(:create) { |claimed_recording|
|
||||
claimed_recording.recording = FactoryGirl.create(:recording_with_track, owner: claimed_recording.user)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
factory :mix, :class => JamRuby::Mix do
|
||||
started_at Time.now
|
||||
completed_at Time.now
|
||||
ogg_md5 'abc'
|
||||
ogg_length 1
|
||||
sequence(:ogg_url) { |n| "recordings/ogg/#{n}" }
|
||||
mp3_md5 'abc'
|
||||
mp3_length 1
|
||||
sequence(:mp3_url) { |n| "recordings/mp3/#{n}" }
|
||||
completed true
|
||||
|
||||
before(:create) {|mix|
|
||||
user = FactoryGirl.create(:user)
|
||||
mix.recording = FactoryGirl.create(:recording_with_track, owner: user)
|
||||
mix.recording.claimed_recordings << FactoryGirl.create(:claimed_recording, user: user, recording: mix.recording)
|
||||
}
|
||||
end
|
||||
|
||||
factory :diagnostic, :class => JamRuby::Diagnostic do
|
||||
type JamRuby::Diagnostic::NO_HEARTBEAT_ACK
|
||||
creator JamRuby::Diagnostic::CLIENT
|
||||
data Faker::Lorem.sentence
|
||||
association :user, factory: :user
|
||||
end
|
||||
|
||||
factory :active_music_session_no_user_history, :class => JamRuby::ActiveMusicSession do
|
||||
|
||||
association :creator, factory: :user
|
||||
|
||||
ignore do
|
||||
name "My Music Session"
|
||||
description "Come Music Session"
|
||||
fan_chat true
|
||||
fan_access true
|
||||
approval_required false
|
||||
musician_access true
|
||||
legal_terms true
|
||||
genre JamRuby::Genre.first
|
||||
band nil
|
||||
end
|
||||
|
||||
|
||||
before(:create) do |session, evaluator|
|
||||
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,
|
||||
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band)
|
||||
session.id = music_session.id
|
||||
end
|
||||
|
||||
factory :active_music_session do
|
||||
after(:create) { |session|
|
||||
FactoryGirl.create(:music_session_user_history, :history => session.music_session, :user => session.creator)
|
||||
}
|
||||
|
||||
factory :music_session_with_mount do
|
||||
association :mount, :factory => :icecast_mount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe 'Feeds' do
|
||||
|
||||
subject { page }
|
||||
|
||||
before do
|
||||
MusicSession.delete_all
|
||||
Recording.delete_all
|
||||
Diagnostic.delete_all
|
||||
User.delete_all
|
||||
end
|
||||
|
||||
let(:admin) { FactoryGirl.create(:admin) }
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
|
||||
let(:music_session) { FactoryGirl.create(:music_session, :creator => user) }
|
||||
let(:recording) { FactoryGirl.create(:recording, :owner => user) }
|
||||
let(:diagnostic) { FactoryGirl.create(:diagnostic, :user => user) }
|
||||
|
||||
describe 'empty dashboard' do
|
||||
before do
|
||||
visit admin_feed_path
|
||||
end
|
||||
|
||||
it { should have_selector('h2', text: 'Feed') }
|
||||
|
||||
it 'has no feeds' do
|
||||
should have_selector('p', text: 'No session activities.')
|
||||
should have_selector('p', text: 'No recording activities.')
|
||||
should have_selector('p', text: 'No diagnostic activities.')
|
||||
end
|
||||
|
||||
describe 'admin enters user name' do
|
||||
it 'auto-completes with email + full name', :js => true do
|
||||
within('form.feed') do
|
||||
fill_in 'feed_user', with: user.email[0..3]
|
||||
end
|
||||
|
||||
page.execute_script %Q{ $('form.feed input#feed_user').trigger('focus') }
|
||||
page.execute_script %Q{ $('form.feed input#feed_user').trigger('keydown') }
|
||||
sleep 5
|
||||
find('a.ui-corner-all', text: user.to_label).trigger(:click)
|
||||
should have_selector('form.feed #feed_user', user.to_label)
|
||||
should have_selector('form.feed #feed_user_id', user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'activities' do
|
||||
before do
|
||||
|
||||
visit admin_feed_path
|
||||
end
|
||||
|
||||
it 'shows session, recording, diagnostic' do
|
||||
should have_selector("tr#jam_ruby_music_session_#{music_session.id}")
|
||||
should have_selector("tr#jam_ruby_recording_#{recording.id}")
|
||||
should have_selector("tr#jam_ruby_diagnostic_#{diagnostic.id}")
|
||||
end
|
||||
|
||||
it 'shows activities for one user', :js => true do
|
||||
within('form.feed') do
|
||||
fill_in 'feed_user', with: user.email[0..3]
|
||||
end
|
||||
|
||||
page.execute_script %Q{ $('form.feed input#feed_user').trigger('focus') }
|
||||
page.execute_script %Q{ $('form.feed input#feed_user').trigger('keydown') }
|
||||
sleep 5
|
||||
find('a.ui-corner-all', text: user.to_label).trigger(:click)
|
||||
should have_selector('form.feed #feed_user', user.to_label)
|
||||
should have_selector('form.feed #feed_user_id', user.id)
|
||||
|
||||
find('form.feed').trigger(:submit)
|
||||
|
||||
should have_selector("tr#jam_ruby_music_session_#{music_session.id}")
|
||||
should have_selector("tr#jam_ruby_recording_#{recording.id}")
|
||||
should have_selector("tr#jam_ruby_diagnostic_#{diagnostic.id}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -22,6 +22,9 @@ require 'rspec/autorun'
|
|||
|
||||
# load capybara
|
||||
require 'capybara/rails'
|
||||
require 'capybara/rspec'
|
||||
require 'capybara-screenshot/rspec'
|
||||
require 'capybara/poltergeist'
|
||||
|
||||
#include Rails.application.routes.url_helpers
|
||||
|
||||
|
|
@ -30,6 +33,11 @@ require 'capybara/rails'
|
|||
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
||||
|
||||
|
||||
Capybara.register_driver :poltergeist do |app|
|
||||
driver = Capybara::Poltergeist::Driver.new(app, { debug: false, phantomjs_logger: File.open('log/phantomjs.out', 'w') })
|
||||
end
|
||||
Capybara.javascript_driver = :poltergeist
|
||||
Capybara.default_wait_time = 10
|
||||
|
||||
RSpec.configure do |config|
|
||||
# ## Mock Framework
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
module Snapshot
|
||||
|
||||
SS_PATH = 'snapshots.html'
|
||||
|
||||
def set_up_snapshot(filepath = SS_PATH)
|
||||
@size = [1280, 720] #arbitrary
|
||||
@file = File.new(filepath, "w+")
|
||||
@file.puts "<HTML><BODY BGCOLOR=grey>"
|
||||
@file.puts "<H1>Snapshot #{ENV["BUILD_NUMBER"]} - #{@size[0]}x#{@size[1]}</H1>"
|
||||
end
|
||||
|
||||
def snapshot_example
|
||||
page.driver.resize(@size[0], @size[1])
|
||||
@file.puts "<H3>Example name: #{get_description}</H3><BR><BR>"
|
||||
end
|
||||
|
||||
def snap!(title = get_description)
|
||||
base64 = page.driver.render_base64(:png)
|
||||
@file.puts '<H3>' + title + '</H3>'
|
||||
@file.puts '<img alt="' + title +'" src="data:image/png;base64,' + base64 + '" />'
|
||||
@file.puts '<BR><BR><BR>'
|
||||
end
|
||||
|
||||
def tear_down_snapshot
|
||||
@file.puts "</BODY></HTML>"
|
||||
@file.close()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -151,3 +151,5 @@ user_mods.sql
|
|||
connection_stale_expire.sql
|
||||
rename_chat_messages.sql
|
||||
fix_connection_fields.sql
|
||||
session_ratings.sql
|
||||
scheduled_sessions.sql
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
-- track the last measured audio gear latency
|
||||
ALTER TABLE users ADD COLUMN audio_latency double precision;
|
||||
|
||||
-- begin moving all the fields traditionally on music_sessions to music_sessions_history
|
||||
ALTER TABLE music_sessions_history ADD COLUMN scheduled_start TIMESTAMP WITH TIME ZONE;
|
||||
ALTER TABLE music_sessions_history ADD COLUMN scheduled_duration INTERVAL;
|
||||
ALTER TABLE music_sessions_history ADD COLUMN musician_access BOOLEAN NOT NULL DEFAULT TRUE;
|
||||
ALTER TABLE music_sessions_history ADD COLUMN approval_required BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
ALTER TABLE music_sessions_history ADD COLUMN fan_chat BOOLEAN NOT NULL DEFAULT TRUE;
|
||||
ALTER TABLE music_sessions_history ADD COLUMN genre_id VARCHAR(64) REFERENCES genres(id);
|
||||
ALTER TABLE music_sessions_history ADD COLUMN legal_policy VARCHAR(255) NOT NULL DEFAULT 'standard';
|
||||
ALTER TABLE music_sessions_history ADD COLUMN language VARCHAR(255) NOT NULL DEFAULT 'en';
|
||||
ALTER TABLE music_sessions_history ADD COLUMN name TEXT;
|
||||
|
||||
-- get rid of genres in favor of just genre_id (no more multi-genres for a session)
|
||||
UPDATE music_sessions_history SET name = description;
|
||||
ALTER TABLE music_sessions_history ALTER COLUMN name SET NOT NULL;
|
||||
-- production db has some null genres on older sessions
|
||||
UPDATE music_sessions_history SET genres = 'rock' where genres = '';
|
||||
UPDATE music_sessions_history SET genre_id = genres;
|
||||
ALTER TABLE music_sessions_history ALTER COLUMN genre_id SET NOT NULL;
|
||||
ALTER TABLE music_sessions_history DROP COLUMN genres;
|
||||
|
||||
-- likers should refer to id field of music_sessions_history (not music_session_id)
|
||||
ALTER TABLE music_sessions_likers ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
-- production db has some bad data
|
||||
DELETE from music_sessions_likers where music_session_id NOT IN (select id from music_sessions_history);
|
||||
UPDATE music_sessions_likers SET music_session_id2 = music_session_id;
|
||||
ALTER TABLE music_sessions_likers DROP COLUMN music_session_id;
|
||||
ALTER TABLE music_sessions_likers RENAME COLUMN music_session_id2 to music_session_id;
|
||||
|
||||
-- comments should refer to id field of music_sessions_history (not music_session_id)
|
||||
ALTER TABLE music_sessions_comments ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
-- production db has some bad data
|
||||
DELETE from music_sessions_comments where music_session_id NOT IN (select id from music_sessions_history);
|
||||
UPDATE music_sessions_comments SET music_session_id2 = music_session_id;
|
||||
ALTER TABLE music_sessions_comments DROP COLUMN music_session_id;
|
||||
ALTER TABLE music_sessions_comments RENAME COLUMN music_session_id2 to music_session_id;
|
||||
|
||||
-- user_history should refer to id field of music_sessions_history (not music_session_id)
|
||||
ALTER TABLE music_sessions_user_history ADD COLUMN music_session_id2 VARCHAR(64) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
-- production db has some bad data
|
||||
DELETE from music_sessions_user_history where music_session_id NOT IN (select id from music_sessions_history);
|
||||
UPDATE music_sessions_user_history SET music_session_id2 = music_session_id;
|
||||
ALTER TABLE music_sessions_user_history DROP COLUMN music_session_id;
|
||||
ALTER TABLE music_sessions_user_history RENAME COLUMN music_session_id2 to music_session_id;
|
||||
|
||||
-- get rid of display fields on music_sessions
|
||||
ALTER TABLE music_sessions DROP COLUMN musician_access;
|
||||
ALTER TABLE music_sessions DROP COLUMN fan_access;
|
||||
ALTER TABLE music_sessions DROP COLUMN description;
|
||||
ALTER TABLE music_sessions DROP COLUMN fan_chat;
|
||||
ALTER TABLE music_sessions DROP COLUMN approval_required;
|
||||
ALTER TABLE music_sessions DROP COLUMN band_id;
|
||||
|
||||
ALTER TABLE music_sessions_history ALTER COLUMN music_session_id DROP NOT NULL;
|
||||
|
||||
-- create RSVP slots
|
||||
CREATE TABLE rsvp_slots (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
instrument_id VARCHAR(64) REFERENCES instruments (id),
|
||||
proficiency_level VARCHAR(255) NOT NULL,
|
||||
music_session_id VARCHAR(64) NOT NULL REFERENCES music_sessions_history (id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL
|
||||
);
|
||||
|
||||
-- create RSVP requests
|
||||
CREATE TABLE rsvp_requests (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
user_id VARCHAR(64) NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
rsvp_slot_id VARCHAR(64) NOT NULL REFERENCES rsvp_slots(id) ON DELETE CASCADE,
|
||||
message TEXT,
|
||||
chosen BOOLEAN DEFAULT FALSE,
|
||||
canceled BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE recurring_sessions (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
description VARCHAR(8000),
|
||||
scheduled_start TIMESTAMP WITH TIME ZONE,
|
||||
scheduled_duration INTERVAL,
|
||||
musician_access BOOLEAN NOT NULL,
|
||||
approval_required BOOLEAN NOT NULL,
|
||||
fan_chat BOOLEAN NOT NULL,
|
||||
genre_id VARCHAR(64) REFERENCES genres(id),
|
||||
legal_policy VARCHAR(255) NOT NULL DEFAULT 'standard',
|
||||
language VARCHAR(255) NOT NULL DEFAULT 'en',
|
||||
name TEXT,
|
||||
user_id VARCHAR(64) NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
band_id VARCHAR(64) REFERENCES bands(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE music_sessions_history ADD COLUMN recurring_session_id VARCHAR(64) REFERENCES recurring_sessions(id);
|
||||
|
||||
-- make these 3 tables be LOGGED, and refer to music_sessions_history instead of music_sessions
|
||||
DROP TABLE fan_invitations;
|
||||
DROP TABLE invitations;
|
||||
DROP TABLE join_requests;
|
||||
|
||||
|
||||
CREATE TABLE fan_invitations (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
sender_id VARCHAR(64),
|
||||
receiver_id VARCHAR(64),
|
||||
music_session_id VARCHAR(64),
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL
|
||||
);
|
||||
ALTER TABLE ONLY fan_invitations ADD CONSTRAINT fan_invitations_music_session_id_fkey FOREIGN KEY (music_session_id) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
|
||||
CREATE UNLOGGED TABLE join_requests (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
user_id VARCHAR(64),
|
||||
music_session_id VARCHAR(64),
|
||||
text VARCHAR(2000),
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL
|
||||
);
|
||||
ALTER TABLE ONLY join_requests ADD CONSTRAINT user_music_session_uniqkey UNIQUE (user_id, music_session_id);
|
||||
ALTER TABLE ONLY join_requests ADD CONSTRAINT join_requests_music_session_id_fkey FOREIGN KEY (music_session_id) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
|
||||
-- INVITATIONS
|
||||
--------------
|
||||
CREATE UNLOGGED TABLE invitations (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4() NOT NULL,
|
||||
sender_id VARCHAR(64),
|
||||
receiver_id VARCHAR(64),
|
||||
music_session_id VARCHAR(64),
|
||||
created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
||||
join_request_id VARCHAR(64)
|
||||
);
|
||||
ALTER TABLE ONLY invitations ADD CONSTRAINT invitations_uniqkey UNIQUE (sender_id, receiver_id, music_session_id);
|
||||
ALTER TABLE ONLY invitations ADD CONSTRAINT invitations_join_request_id_fkey FOREIGN KEY (join_request_id) REFERENCES join_requests(id) ON DELETE CASCADE;
|
||||
ALTER TABLE ONLY invitations ADD CONSTRAINT invitations_music_session_id_fkey FOREIGN KEY (music_session_id) REFERENCES music_sessions_history(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
-- finally, rename music_sessions and music_sessions_history to reflect true nature better
|
||||
ALTER TABLE music_sessions RENAME TO active_music_sessions;
|
||||
ALTER TABLE music_sessions_history RENAME TO music_sessions;
|
||||
|
||||
-- add fk to chat_messages so they delete cleanly when users are deleted
|
||||
ALTER TABLE ONLY chat_messages ADD CONSTRAINT chat_messages_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
-- fix any promotionals
|
||||
UPDATE promotionals SET latest_type = 'JamRuby::MusicSession' WHERE latest_type = 'JamRuby::MusicSessionHistory';
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE music_sessions_user_history ADD COLUMN rating_comment TEXT;
|
||||
|
|
@ -186,6 +186,7 @@ message LoginAck {
|
|||
optional string music_session_id = 5; // the music session that the user was in very recently (likely due to dropped connection)
|
||||
optional bool reconnected = 6; // if reconnect_music_session_id is specified, and the server could log the user into that session, then true is returned.
|
||||
optional string user_id = 7; // the database user id
|
||||
optional int32 connection_expire_time = 8; // this is how long the server gives you before killing your connection entirely after missing heartbeats
|
||||
}
|
||||
|
||||
// route_to: server
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ unless ENV["LOCAL_DEV"] == "1"
|
|||
source 'https://jamjam:blueberryjam@int.jamkazam.com/gems/'
|
||||
end
|
||||
|
||||
devenv = ENV["BUILD_NUMBER"].nil? # Jenkins sets a build number environment variable
|
||||
devenv = ENV["BUILD_NUMBER"].nil? || ENV["TEST_WWW"] == "1"
|
||||
|
||||
if devenv
|
||||
gem 'jam_db', :path=> "../db/target/ruby_package"
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ require "jam_ruby/lib/module_overrides"
|
|||
require "jam_ruby/lib/s3_util"
|
||||
require "jam_ruby/lib/s3_manager"
|
||||
require "jam_ruby/lib/profanity"
|
||||
require "jam_ruby/lib/json_validator"
|
||||
require "jam_ruby/lib/em_helper.rb"
|
||||
require "jam_ruby/lib/nav.rb"
|
||||
require "jam_ruby/resque/audiomixer"
|
||||
|
|
@ -75,10 +76,11 @@ require "jam_ruby/models/artifact_update"
|
|||
require "jam_ruby/models/band_invitation"
|
||||
require "jam_ruby/models/band_musician"
|
||||
require "jam_ruby/models/connection"
|
||||
require "jam_ruby/models/diagnostic"
|
||||
require "jam_ruby/models/friendship"
|
||||
require "jam_ruby/models/music_session"
|
||||
require "jam_ruby/models/active_music_session"
|
||||
require "jam_ruby/models/music_session_comment"
|
||||
require "jam_ruby/models/music_session_history"
|
||||
require "jam_ruby/models/music_session"
|
||||
require "jam_ruby/models/music_session_liker"
|
||||
require "jam_ruby/models/music_session_user_history"
|
||||
require "jam_ruby/models/music_session_perf_data"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ module JamRuby
|
|||
|
||||
batch.did_send(emails)
|
||||
|
||||
mail(:to => emails,
|
||||
mail(:to => emails,
|
||||
:from => batch.from_email,
|
||||
:subject => batch.subject) do |format|
|
||||
format.text
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ module JamRuby
|
|||
|
||||
# this simulates music_session destroy callbacks with activerecord
|
||||
def before_destroy_music_session(music_session_id)
|
||||
music_session = MusicSession.find_by_id(music_session_id)
|
||||
music_session = ActiveMusicSession.find_by_id(music_session_id)
|
||||
music_session.before_destroy if music_session
|
||||
end
|
||||
|
||||
# reclaim the existing connection, if ip_address is not nil then perhaps a new address as well
|
||||
def reconnect(conn, reconnect_music_session_id, ip_address)
|
||||
def reconnect(conn, reconnect_music_session_id, ip_address, connection_stale_time, connection_expire_time)
|
||||
music_session_id = nil
|
||||
reconnected = false
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
sql =<<SQL
|
||||
UPDATE connections SET (aasm_state, updated_at, music_session_id, joined_session_at) = ('#{Connection::CONNECT_STATE.to_s}', NOW(), #{music_session_id_expression}, #{joined_session_at_expression})
|
||||
UPDATE connections SET (aasm_state, updated_at, music_session_id, joined_session_at, stale_time, expire_time) = ('#{Connection::CONNECT_STATE.to_s}', NOW(), #{music_session_id_expression}, #{joined_session_at_expression}, #{connection_stale_time}, #{connection_expire_time})
|
||||
WHERE
|
||||
client_id = '#{conn.client_id}'
|
||||
RETURNING music_session_id
|
||||
|
|
@ -114,7 +114,6 @@ WHERE
|
|||
aasm_state = '#{Connection::CONNECT_STATE.to_s}'
|
||||
RETURNING music_session_id
|
||||
SQL
|
||||
# @log.info("*** flag_connection_stale_with_client_id: client_id = #{client_id}; sql = #{sql}")
|
||||
self.pg_conn.exec(sql) do |result|
|
||||
|
||||
# if we did update a client to stale, retriee music_session_id
|
||||
|
|
@ -127,24 +126,22 @@ SQL
|
|||
end
|
||||
|
||||
# flag connections as stale
|
||||
def flag_stale_connections(max_seconds)
|
||||
def flag_stale_connections()
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
conn = connection_manager.pg_conn
|
||||
sql =<<SQL
|
||||
SELECT count(user_id) FROM connections
|
||||
WHERE
|
||||
updated_at < (NOW() - interval '#{max_seconds} second') AND
|
||||
updated_at < (NOW() - (interval '1 second' * stale_time))AND
|
||||
aasm_state = '#{Connection::CONNECT_STATE.to_s}'
|
||||
SQL
|
||||
conn.exec(sql) do |result|
|
||||
count = result.getvalue(0, 0)
|
||||
# @log.info("flag_stale_connections: flagging #{count} stale connections")
|
||||
if 0 < count.to_i
|
||||
# @log.info("flag_stale_connections: flagging #{count} stale connections")
|
||||
sql =<<SQL
|
||||
UPDATE connections SET aasm_state = '#{Connection::STALE_STATE.to_s}'
|
||||
WHERE
|
||||
updated_at < (NOW() - interval '#{max_seconds} second') AND
|
||||
updated_at < (NOW() - (interval '1 second' * stale_time)) AND
|
||||
aasm_state = '#{Connection::CONNECT_STATE.to_s}'
|
||||
SQL
|
||||
conn.exec(sql)
|
||||
|
|
@ -155,33 +152,31 @@ SQL
|
|||
|
||||
# NOTE this is only used for testing purposes;
|
||||
# actual deletes will be processed in the websocket context which cleans up dependencies
|
||||
def expire_stale_connections(max_seconds)
|
||||
self.stale_connection_client_ids(max_seconds).each { |cid| self.delete_connection(cid) }
|
||||
def expire_stale_connections()
|
||||
self.stale_connection_client_ids().each { |client| self.delete_connection(client[:client_id]) }
|
||||
end
|
||||
|
||||
# expiring connections in stale state, which deletes them
|
||||
def stale_connection_client_ids(max_seconds)
|
||||
client_ids = []
|
||||
def stale_connection_client_ids()
|
||||
clients = []
|
||||
ConnectionManager.active_record_transaction do |connection_manager|
|
||||
conn = connection_manager.pg_conn
|
||||
sql =<<SQL
|
||||
SELECT client_id, music_session_id, user_id FROM connections
|
||||
SELECT client_id, music_session_id, user_id, client_type FROM connections
|
||||
WHERE
|
||||
updated_at < (NOW() - interval '#{max_seconds} second') AND
|
||||
aasm_state = '#{Connection::STALE_STATE.to_s}'
|
||||
updated_at < (NOW() - (interval '1 second' * expire_time))
|
||||
SQL
|
||||
conn.exec(sql) do |result|
|
||||
result.each { |row|
|
||||
client_id = row['client_id']
|
||||
music_session_id = row['music_session_id']
|
||||
user_id = row['user_id']
|
||||
|
||||
client_ids << client_id
|
||||
|
||||
client_type = row['client_type']
|
||||
clients << {client_id: client_id, music_session_id: music_session_id, client_type: client_type, user_id: user_id}
|
||||
}
|
||||
end
|
||||
end
|
||||
client_ids
|
||||
clients
|
||||
end
|
||||
|
||||
|
||||
|
|
@ -189,7 +184,7 @@ SQL
|
|||
# this number is used by notification logic elsewhere to know
|
||||
# 'oh the user joined for the 1st time, so send a friend update', or
|
||||
# 'don't bother because the user has connected somewhere else already'
|
||||
def create_connection(user_id, client_id, ip_address, client_type, &blk)
|
||||
def create_connection(user_id, client_id, ip_address, client_type, connection_stale_time, connection_expire_time, &blk)
|
||||
|
||||
# validate client_type
|
||||
raise "invalid client_type: #{client_type}" if client_type != 'client' && client_type != 'browser'
|
||||
|
|
@ -221,8 +216,8 @@ SQL
|
|||
|
||||
lock_connections(conn)
|
||||
|
||||
conn.exec("INSERT INTO connections (user_id, client_id, ip_address, client_type, addr, locidispid, aasm_state) VALUES ($1, $2, $3, $4, $5, $6, $7)",
|
||||
[user_id, client_id, ip_address, client_type, addr, locidispid, Connection::CONNECT_STATE.to_s]).clear
|
||||
conn.exec("INSERT INTO connections (user_id, client_id, ip_address, client_type, addr, locidispid, aasm_state, stale_time, expire_time) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
[user_id, client_id, ip_address, client_type, addr, locidispid, Connection::CONNECT_STATE.to_s, connection_stale_time, connection_expire_time]).clear
|
||||
|
||||
# we just created a new connection-if this is the first time the user has shown up, we need to send out a message to his friends
|
||||
conn.exec("SELECT count(user_id) FROM connections WHERE user_id = $1", [user_id]) do |result|
|
||||
|
|
@ -280,7 +275,7 @@ SQL
|
|||
# same for session-if we are down to the last participant, delete the session
|
||||
unless music_session_id.nil?
|
||||
before_destroy_music_session(music_session_id)
|
||||
result = conn.exec("DELETE FROM music_sessions WHERE id = $1 AND 0 = (select count(music_session_id) FROM connections where music_session_id = $1)", [music_session_id])
|
||||
result = conn.exec("DELETE FROM active_music_sessions WHERE id = $1 AND 0 = (select count(music_session_id) FROM connections where music_session_id = $1)", [music_session_id])
|
||||
if result.cmd_tuples == 1
|
||||
music_session_id = nil
|
||||
end
|
||||
|
|
@ -321,12 +316,12 @@ SQL
|
|||
if num_participants == 0
|
||||
# delete the music_session
|
||||
before_destroy_music_session(previous_music_session_id)
|
||||
conn.exec("DELETE from music_sessions WHERE id = $1",
|
||||
conn.exec("DELETE from active_music_sessions WHERE id = $1",
|
||||
[previous_music_session_id]) do |result|
|
||||
if result.cmd_tuples == 1
|
||||
# music session deleted!
|
||||
@log.debug("deleted music session #{previous_music_session_id}")
|
||||
JamRuby::MusicSessionHistory.removed_music_session(previous_music_session_id)
|
||||
JamRuby::MusicSession.removed_music_session(previous_music_session_id)
|
||||
elsif 1 < result.cmd_tuples
|
||||
msg = "music_sessions table data integrity violation; multiple rows found with music_session_id=#{previous_music_session_id}"
|
||||
@log.error(msg)
|
||||
|
|
@ -337,7 +332,7 @@ SQL
|
|||
# there are still people in the session
|
||||
|
||||
#ensure that there is no active claimed recording if the owner of that recording left the session
|
||||
conn.exec("UPDATE music_sessions set claimed_recording_id = NULL, claimed_recording_initiator_id = NULL where claimed_recording_initiator_id = $1 and id = $2",
|
||||
conn.exec("UPDATE active_music_sessions set claimed_recording_id = NULL, claimed_recording_initiator_id = NULL where claimed_recording_initiator_id = $1 and id = $2",
|
||||
[user_id, previous_music_session_id])
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
# This needs to be outside the module to work.
|
||||
class JsonValidator < ActiveModel::EachValidator
|
||||
# implement the method called during validation
|
||||
def is_json?(value)
|
||||
begin
|
||||
!!JSON.parse(value)
|
||||
rescue
|
||||
false
|
||||
end
|
||||
end
|
||||
def validate_each(record, attribute, value)
|
||||
record.errors[attribute] << 'must be JSON' unless value.nil? || is_json?(value)
|
||||
end
|
||||
end
|
||||
|
|
@ -33,7 +33,7 @@ end
|
|||
class NoProfanityValidator < ActiveModel::EachValidator
|
||||
# implement the method called during validation
|
||||
def validate_each(record, attribute, value)
|
||||
record.errors[attribute] << 'cannot contain profanity' if Profanity.is_profane?(value)
|
||||
record.errors[attribute] << 'cannot contain profanity' if JamRuby::Profanity.is_profane?(value)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# create a login ack (login was successful)
|
||||
def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected, user_id)
|
||||
def login_ack(public_ip, client_id, token, heartbeat_interval, music_session_id, reconnected, user_id, connection_expire_time)
|
||||
login_ack = Jampb::LoginAck.new(
|
||||
:public_ip => public_ip,
|
||||
:client_id => client_id,
|
||||
|
|
@ -61,7 +61,8 @@ module JamRuby
|
|||
:heartbeat_interval => heartbeat_interval,
|
||||
:music_session_id => music_session_id,
|
||||
:reconnected => reconnected,
|
||||
:user_id => user_id
|
||||
:user_id => user_id,
|
||||
:connection_expire_time => connection_expire_time
|
||||
)
|
||||
|
||||
Jampb::ClientMessage.new(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,482 @@
|
|||
module JamRuby
|
||||
class ActiveMusicSession < ActiveRecord::Base
|
||||
self.primary_key = 'id'
|
||||
|
||||
self.table_name = 'active_music_sessions'
|
||||
|
||||
attr_accessor :legal_terms, :max_score
|
||||
|
||||
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id", :inverse_of => :playing_sessions
|
||||
belongs_to :claimed_recording_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_claimed_recordings, :foreign_key => "claimed_recording_initiator_id"
|
||||
|
||||
has_one :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => 'music_session_id'
|
||||
has_one :mount, :class_name => "JamRuby::IcecastMount", :inverse_of => :music_session, :foreign_key => 'music_session_id'
|
||||
belongs_to :creator, :class_name => 'JamRuby::User', :foreign_key => :user_id
|
||||
|
||||
has_many :connections, :class_name => "JamRuby::Connection", foreign_key: :music_session_id
|
||||
has_many :users, :through => :connections, :class_name => "JamRuby::User"
|
||||
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session, foreign_key: :music_session_id
|
||||
has_many :chats, :class_name => "JamRuby::ChatMessages", :foreign_key => "session_id"
|
||||
validates :creator, :presence => true
|
||||
validate :creator_is_musician
|
||||
validate :no_new_playback_while_playing
|
||||
|
||||
after_create :started_session
|
||||
|
||||
after_destroy do |obj|
|
||||
JamRuby::MusicSession.removed_music_session(obj.id)
|
||||
end
|
||||
|
||||
#default_scope :select => "*, 0 as score"
|
||||
|
||||
def attributes
|
||||
super.merge('max_score' => self.max_score)
|
||||
end
|
||||
|
||||
def max_score
|
||||
nil unless has_attribute?(:max_score)
|
||||
read_attribute(:max_score).to_i
|
||||
end
|
||||
|
||||
before_create :create_uuid
|
||||
def create_uuid
|
||||
#self.id = SecureRandom.uuid
|
||||
end
|
||||
|
||||
def before_destroy
|
||||
self.mount.destroy if self.mount
|
||||
end
|
||||
|
||||
def creator_is_musician
|
||||
unless creator.musician?
|
||||
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
|
||||
end
|
||||
end
|
||||
|
||||
def no_new_playback_while_playing
|
||||
# if we previous had a claimed recording and are trying to set one
|
||||
# and if also the previous initiator is different than the current one... it's a no go
|
||||
if !claimed_recording_id_was.nil? && !claimed_recording_id.nil? &&
|
||||
claimed_recording_initiator_id_was != claimed_recording_initiator_id
|
||||
errors.add(:claimed_recording, ValidationMessages::CLAIMED_RECORDING_ALREADY_IN_PROGRESS)
|
||||
end
|
||||
end
|
||||
|
||||
# returns an array of client_id's that are in this session
|
||||
# if as_musician is nil, all connections in the session ,regardless if it's a musician or not or not
|
||||
# you can also exclude a client_id from the returned set by setting exclude_client_id
|
||||
def get_connection_ids(options = {})
|
||||
as_musician = options[:as_musician]
|
||||
exclude_client_id = options[:exclude_client_id]
|
||||
|
||||
where = { :music_session_id => self.id }
|
||||
where[:as_musician] = as_musician unless as_musician.nil?
|
||||
|
||||
exclude = "client_id != '#{exclude_client_id}'"unless exclude_client_id.nil?
|
||||
|
||||
Connection.select(:client_id).where(where).where(exclude).map(&:client_id)
|
||||
end
|
||||
|
||||
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
|
||||
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
|
||||
def self.index(current_user, options = {})
|
||||
participants = options[:participants]
|
||||
genres = options[:genres]
|
||||
keyword = options[:keyword]
|
||||
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
|
||||
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
|
||||
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
|
||||
|
||||
query = ActiveMusicSession
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
music_sessions
|
||||
ON
|
||||
active_music_sessions.id = music_sessions.id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
connections
|
||||
ON
|
||||
active_music_sessions.id = connections.music_session_id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
friendships
|
||||
ON
|
||||
connections.user_id = friendships.user_id
|
||||
AND
|
||||
friendships.friend_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
invitations
|
||||
ON
|
||||
invitations.music_session_id = active_music_sessions.id
|
||||
AND
|
||||
invitations.receiver_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.group(
|
||||
%Q{
|
||||
active_music_sessions.id
|
||||
}
|
||||
)
|
||||
.order(
|
||||
%Q{
|
||||
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
active_music_sessions.created_at DESC
|
||||
}
|
||||
)
|
||||
|
||||
if as_musician
|
||||
query = query.where(
|
||||
%Q{
|
||||
musician_access = true
|
||||
OR
|
||||
invitations.id IS NOT NULL
|
||||
}
|
||||
)
|
||||
else
|
||||
# if you are trying to join the session as a fan/listener,
|
||||
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
|
||||
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = active_music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
|
||||
query = query.where('music_sessions.fan_access = true')
|
||||
query = query.where("(active_music_sessions.created_at < icecast_servers.config_updated_at)")
|
||||
end
|
||||
|
||||
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
|
||||
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
|
||||
query = query.where("music_sessions.genre_id in (?)", genres) unless genres.nil?
|
||||
|
||||
if my_bands_only
|
||||
query = query.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
bands_musicians
|
||||
ON
|
||||
bands_musicians.user_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
if my_bands_only || friends_only
|
||||
query = query.where(
|
||||
%Q{
|
||||
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
|
||||
OR
|
||||
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
|
||||
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
|
||||
# note, this is mostly the same as above but includes paging through the result and and scores.
|
||||
# thus it needs the client_id...
|
||||
def self.nindex(current_user, options = {})
|
||||
client_id = options[:client_id]
|
||||
participants = options[:participants]
|
||||
genres = options[:genres]
|
||||
keyword = options[:keyword]
|
||||
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
|
||||
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
|
||||
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
|
||||
offset = options[:offset]
|
||||
limit = options[:limit]
|
||||
|
||||
connection = Connection.where(client_id: client_id).first!
|
||||
locidispid = connection.locidispid
|
||||
|
||||
query = ActiveMusicSession
|
||||
.select("active_music_sessions.*, max(coalesce(current_scores.score, 1000)) as max_score") # 1000 is higher than the allowed max of 999
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
music_sessions
|
||||
ON
|
||||
active_music_sessions.id = music_sessions.id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
connections
|
||||
ON
|
||||
active_music_sessions.id = connections.music_session_id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
current_scores
|
||||
ON
|
||||
current_scores.alocidispid = connections.locidispid
|
||||
AND
|
||||
current_scores.blocidispid = #{locidispid}
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
friendships
|
||||
ON
|
||||
connections.user_id = friendships.user_id
|
||||
AND
|
||||
friendships.friend_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
invitations
|
||||
ON
|
||||
invitations.music_session_id = active_music_sessions.id
|
||||
AND
|
||||
invitations.receiver_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.group(
|
||||
%Q{
|
||||
active_music_sessions.id
|
||||
}
|
||||
)
|
||||
.order(
|
||||
%Q{
|
||||
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
active_music_sessions.created_at DESC
|
||||
}
|
||||
)
|
||||
|
||||
if (offset)
|
||||
query = query.offset(offset)
|
||||
end
|
||||
|
||||
if (limit)
|
||||
query = query.limit(limit)
|
||||
end
|
||||
|
||||
if as_musician
|
||||
query = query.where(
|
||||
%Q{
|
||||
musician_access = true
|
||||
OR
|
||||
music_sessions.user_id = '#{current_user.id}'
|
||||
OR
|
||||
invitations.id IS NOT NULL
|
||||
}
|
||||
)
|
||||
else
|
||||
# if you are trying to join the session as a fan/listener,
|
||||
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
|
||||
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = active_music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
|
||||
query = query.where('music_sessions.fan_access = true')
|
||||
query = query.where("(active_music_sessions.created_at < icecast_servers.config_updated_at)")
|
||||
end
|
||||
|
||||
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
|
||||
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
|
||||
query = query.where("music_sessions.genre_id in (?)", genres) unless genres.nil?
|
||||
|
||||
if my_bands_only
|
||||
query = query.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
bands_musicians
|
||||
ON
|
||||
bands_musicians.user_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
if my_bands_only || friends_only
|
||||
query = query.where(
|
||||
%Q{
|
||||
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
|
||||
OR
|
||||
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
# Verifies that the specified user can join this music session
|
||||
def can_join? user, as_musician
|
||||
if as_musician
|
||||
if !user.musician
|
||||
return false # "a fan can not join a music session as a musician"
|
||||
raise PermissionError, "a fan can not join a music session as a musician"
|
||||
end
|
||||
|
||||
if self.musician_access
|
||||
if self.approval_required
|
||||
return self.invited_musicians.exists?(user)
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
||||
else
|
||||
# the creator can always join, and the invited users can join
|
||||
return self.creator == user || self.invited_musicians.exists?(user)
|
||||
end
|
||||
else
|
||||
# it's a fan, and the only way a fan can join is if fan_access is true
|
||||
return self.fan_access
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Verifies that the specified user can see this music session
|
||||
def can_see? user
|
||||
if self.musician_access || self.fan_access
|
||||
true
|
||||
else
|
||||
self.creator == user || self.invited_musicians.exists?(user)
|
||||
end
|
||||
end
|
||||
|
||||
# Verifies that the specified user can delete this music session
|
||||
def can_delete? user
|
||||
# the creator can delete
|
||||
self.creator == user
|
||||
end
|
||||
|
||||
def access? user
|
||||
music_session.part_of_session? user
|
||||
end
|
||||
|
||||
def most_recent_recording
|
||||
recordings.where(:music_session_id => self.id).order('created_at desc').limit(1).first
|
||||
end
|
||||
|
||||
# is this music session currently recording?
|
||||
def is_recording?
|
||||
recordings.where(:duration => nil).count > 0
|
||||
end
|
||||
|
||||
def is_playing_recording?
|
||||
!self.claimed_recording.nil?
|
||||
end
|
||||
|
||||
def recording
|
||||
recordings.where(:duration => nil).first
|
||||
end
|
||||
|
||||
# stops any active recording
|
||||
def stop_recording
|
||||
current_recording = self.recording
|
||||
current_recording.stop unless current_recording.nil?
|
||||
end
|
||||
|
||||
def claimed_recording_start(owner, claimed_recording)
|
||||
self.claimed_recording = claimed_recording
|
||||
self.claimed_recording_initiator = owner
|
||||
self.save
|
||||
end
|
||||
|
||||
def claimed_recording_stop
|
||||
self.claimed_recording = nil
|
||||
self.claimed_recording_initiator = nil
|
||||
self.save
|
||||
end
|
||||
|
||||
def invitations
|
||||
music_session.invitations
|
||||
end
|
||||
|
||||
def invited_musicians
|
||||
music_session.invited_musicians
|
||||
end
|
||||
|
||||
def join_requests
|
||||
music_session.join_requests
|
||||
end
|
||||
|
||||
def fan_invitations
|
||||
music_session.fan_invitations
|
||||
end
|
||||
|
||||
def to_s
|
||||
description
|
||||
end
|
||||
|
||||
def musician_access
|
||||
music_session.musician_access
|
||||
end
|
||||
|
||||
def fan_access
|
||||
music_session.fan_access
|
||||
end
|
||||
|
||||
def description
|
||||
music_session.description
|
||||
end
|
||||
|
||||
def genre
|
||||
music_session.genre
|
||||
end
|
||||
|
||||
def fan_chat
|
||||
music_session.fan_chat
|
||||
end
|
||||
|
||||
def band
|
||||
music_session.band
|
||||
end
|
||||
|
||||
def approval_required
|
||||
music_session.approval_required
|
||||
end
|
||||
|
||||
def tick_track_changes
|
||||
self.track_changes_counter += 1
|
||||
self.save!(:validate => false)
|
||||
end
|
||||
|
||||
def connected_participant_count
|
||||
Connection.where(:music_session_id => self.id,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:as_musician => true)
|
||||
.count
|
||||
end
|
||||
|
||||
def started_session
|
||||
raise "active_music_sessions.id must be set by caller" unless self.id
|
||||
# associate this active_music_session with the music_session formally
|
||||
session = MusicSession.find(self.id)
|
||||
session.active_music_session = self
|
||||
session.save!
|
||||
|
||||
GoogleAnalyticsEvent.track_session_duration(self)
|
||||
GoogleAnalyticsEvent.track_band_real_session(self)
|
||||
end
|
||||
|
||||
|
||||
def self.sync(session_history)
|
||||
music_session = MusicSession.find_by_id(session_history.id)
|
||||
|
||||
if music_session.nil?
|
||||
music_session = MusicSession.new
|
||||
music_session.id = session_history.id
|
||||
end
|
||||
|
||||
music_session.user_id = session_history.creator.id
|
||||
music_session.band_id = session_history.band.id unless session_history.band.nil?
|
||||
session_history.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -44,8 +44,7 @@ module JamRuby
|
|||
has_many :invitations, :inverse_of => :band, :class_name => "JamRuby::BandInvitation", :foreign_key => "band_id"
|
||||
|
||||
# music_sessions
|
||||
has_many :music_sessions, :class_name => "JamRuby::MusicSession", :foreign_key => "band_id"
|
||||
has_many :music_session_history, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "band_id", :inverse_of => :band
|
||||
has_many :music_sessions, :class_name => "JamRuby::MusicSession", foreign_key: :band_id, :inverse_of => :band
|
||||
|
||||
# events
|
||||
has_many :event_sessions, :class_name => "JamRuby::EventSession"
|
||||
|
|
@ -54,19 +53,19 @@ module JamRuby
|
|||
acts_as_mappable
|
||||
|
||||
def liker_count
|
||||
return self.likers.size
|
||||
self.likers.size
|
||||
end
|
||||
|
||||
def follower_count
|
||||
return self.followers.size
|
||||
self.followers.size
|
||||
end
|
||||
|
||||
def recording_count
|
||||
return self.recordings.size
|
||||
self.recordings.size
|
||||
end
|
||||
|
||||
def session_count
|
||||
return self.music_sessions.size
|
||||
self.music_sessions.size
|
||||
end
|
||||
|
||||
def recent_history
|
||||
|
|
@ -74,7 +73,7 @@ module JamRuby
|
|||
.order('created_at DESC')
|
||||
.limit(10)
|
||||
|
||||
msh = MusicSessionHistory.where(:band_id => self.id)
|
||||
msh = MusicSession.where(:band_id => self.id)
|
||||
.order('created_at DESC')
|
||||
.limit(10)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ module JamRuby
|
|||
belongs_to :user
|
||||
belongs_to :music_session
|
||||
|
||||
validates :user, presence: true
|
||||
validates :message, length: {minimum: 1, maximum: 255}, no_profanity: true
|
||||
|
||||
class << self
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module JamRuby
|
|||
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
|
||||
belongs_to :genre, :class_name => "JamRuby::Genre"
|
||||
has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
|
||||
has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
|
||||
has_many :playing_sessions, :class_name => "JamRuby::ActiveMusicSession"
|
||||
has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "claimed_recording_id"
|
||||
has_many :plays, :class_name => "JamRuby::PlayablePlay", :foreign_key => "claimed_recording_id", :dependent => :destroy
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
|
|
|
|||
|
|
@ -3,18 +3,20 @@ require 'aasm'
|
|||
module JamRuby
|
||||
class Connection < ActiveRecord::Base
|
||||
|
||||
# client_types
|
||||
TYPE_CLIENT = 'client'
|
||||
TYPE_BROWSER = 'browser'
|
||||
|
||||
attr_accessor :joining_session
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :user, :class_name => "JamRuby::User"
|
||||
belongs_to :music_session, :class_name => "JamRuby::MusicSession"
|
||||
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", foreign_key: :music_session_id
|
||||
has_many :tracks, :class_name => "JamRuby::Track", :inverse_of => :connection, :foreign_key => 'connection_id', :dependent => :delete_all
|
||||
|
||||
|
||||
validates :as_musician, :inclusion => {:in => [true, false]}
|
||||
validates :client_type, :inclusion => {:in => ['client', 'browser']}
|
||||
validates :client_type, :inclusion => {:in => [TYPE_CLIENT, TYPE_BROWSER]}
|
||||
validate :can_join_music_session, :if => :joining_session?
|
||||
after_save :require_at_least_one_track_when_in_session, :if => :joining_session?
|
||||
after_create :did_create
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
module JamRuby
|
||||
class Diagnostic < ActiveRecord::Base
|
||||
|
||||
# occurs when the client does not see a heartbeat from the server in a while
|
||||
NO_HEARTBEAT_ACK = 'NO_HEARTBEAT_ACK'
|
||||
|
||||
# occurs when the client sees the socket go down
|
||||
WEBSOCKET_CLOSED_REMOTELY = 'WEBSOCKET_CLOSED_REMOTELY'
|
||||
|
||||
# occurs when the client makes the socket go down
|
||||
WEBSOCKET_CLOSED_LOCALLY = 'WEBSOCKET_CLOSED_LOCALLY'
|
||||
|
||||
# occurs when the websocket-gateway has finally given up entirely on a connection with no heartbeats seen in a while
|
||||
EXPIRED_STALE_CONNECTION = 'EXPIRED_STALE_CONNECTION'
|
||||
|
||||
# occurs when the websocket-gateway is trying to handle a heartbeat, but can't find any state for the user.
|
||||
# this implies a coding error
|
||||
MISSING_CLIENT_STATE = 'MISSING_CLIENT_STATE'
|
||||
|
||||
# websocket gateway did not recognize message. indicates out-of-date websocket-gateway
|
||||
UNKNOWN_MESSAGE_TYPE = 'UNKNOWN_MESSAGE_TYPE'
|
||||
|
||||
# empty route_to in message; which is invalid. indicates programming error
|
||||
MISSING_ROUTE_TO = 'MISSING_ROUTE_TO'
|
||||
|
||||
# websocket gateway got a client with the same client_id as an already-connected client
|
||||
DUPLICATE_CLIENT = 'DUPLICATE_CLIENT'
|
||||
|
||||
DIAGNOSTIC_TYPES = [NO_HEARTBEAT_ACK, WEBSOCKET_CLOSED_REMOTELY, EXPIRED_STALE_CONNECTION,
|
||||
MISSING_CLIENT_STATE, UNKNOWN_MESSAGE_TYPE, MISSING_ROUTE_TO,
|
||||
DUPLICATE_CLIENT, WEBSOCKET_CLOSED_LOCALLY]
|
||||
|
||||
# creator types #
|
||||
CLIENT = 'client'
|
||||
WEBSOCKET_GATEWAY = 'websocket-gateway'
|
||||
CREATORS = [CLIENT, WEBSOCKET_GATEWAY]
|
||||
|
||||
self.primary_key = 'id'
|
||||
self.inheritance_column = 'nothing'
|
||||
|
||||
belongs_to :user, :inverse_of => :diagnostics, :class_name => "JamRuby::User", :foreign_key => "user_id"
|
||||
|
||||
validates :user, :presence => true
|
||||
validates :type, :inclusion => {:in => DIAGNOSTIC_TYPES}
|
||||
validates :creator, :inclusion => {:in => CREATORS}
|
||||
validates :data, length: {maximum: 100000}
|
||||
|
||||
|
||||
def self.expired_stale_connection(user, context)
|
||||
Diagnostic.save(EXPIRED_STALE_CONNECTION, user, WEBSOCKET_GATEWAY, context.to_json) if user
|
||||
end
|
||||
|
||||
def self.missing_client_state(user, context)
|
||||
Diagnostic.save(MISSING_CLIENT_STATE, user, WEBSOCKET_GATEWAY, context.to_json) if user
|
||||
end
|
||||
|
||||
def self.missing_connection(user, context)
|
||||
Diagnostic.save(MISSING_CONNECTION, user, WEBSOCKET_GATEWAY, context.to_json) if user
|
||||
end
|
||||
|
||||
def self.duplicate_client(user, context)
|
||||
Diagnostic.save(DUPLICATE_CLIENT, user, WEBSOCKET_GATEWAY, context.to_json) if user
|
||||
end
|
||||
|
||||
def self.unknown_message_type(user, client_msg)
|
||||
Diagnostic.save(UNKNOWN_MESSAGE_TYPE, user, WEBSOCKET_GATEWAY, client_msg.to_json) if user
|
||||
end
|
||||
|
||||
def self.missing_route_to(user, client_msg)
|
||||
Diagnostic.save(MISSING_ROUTE_TO, user, WEBSOCKET_GATEWAY, client_msg.to_json) if user
|
||||
end
|
||||
|
||||
|
||||
def self.save(type, user, creator, data)
|
||||
diagnostic = Diagnostic.new
|
||||
if user.class == String
|
||||
diagnostic.user_id = user
|
||||
else
|
||||
diagnostic.user = user
|
||||
end
|
||||
|
||||
diagnostic.data = data
|
||||
diagnostic.type = type
|
||||
diagnostic.creator = creator
|
||||
diagnostic.save
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -13,7 +13,7 @@ module JamRuby
|
|||
VAR_LAST_NAME = '@LASTNAME'
|
||||
|
||||
DEFAULT_SENDER = "noreply@jamkazam.com"
|
||||
BATCH_SIZE = 1000
|
||||
BATCH_SIZE = 5
|
||||
|
||||
BODY_TEMPLATE =<<FOO
|
||||
Hello #{VAR_FIRST_NAME},
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class JamRuby::EventSession < ActiveRecord::Base
|
|||
# ideally this is based on some proper association with the event, not such a slushy time grab
|
||||
def sessions
|
||||
if ready_display
|
||||
query = MusicSessionHistory.where(fan_access: true).where(created_at: (self.starts_at - 12.hours)..(self.ends_at + 12.hours))
|
||||
query = MusicSession.where(fan_access: true).where(created_at: (self.starts_at - 12.hours)..(self.ends_at + 12.hours))
|
||||
if self.user_id
|
||||
query = query.where(user_id: self.user_id)
|
||||
elsif self.band_id
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
belongs_to :sender, :inverse_of => :sent_fan_invitations, :class_name => "JamRuby::User", :foreign_key => "sender_id"
|
||||
belongs_to :receiver, :inverse_of => :received_fan_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id"
|
||||
belongs_to :music_session, :inverse_of => :fan_invitations, :class_name => "JamRuby::MusicSession"
|
||||
belongs_to :music_session, :inverse_of => :fan_invitations, :class_name => "JamRuby::MusicSession", :foreign_key => "music_session_id"
|
||||
|
||||
validates :sender, :presence => true
|
||||
validates :receiver, :presence => true
|
||||
|
|
@ -18,7 +18,7 @@ module JamRuby
|
|||
private
|
||||
|
||||
def require_sender_in_music_session
|
||||
unless music_session.users.exists? sender
|
||||
unless music_session.part_of_session? sender
|
||||
errors.add(:music_session, MEMBERSHIP_REQUIRED_OF_MUSIC_SESSION)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ module JamRuby
|
|||
class Feed < ActiveRecord::Base
|
||||
|
||||
belongs_to :recording, class_name: "JamRuby::Recording", inverse_of: :feed, foreign_key: 'recording_id'
|
||||
belongs_to :music_session_history, class_name: "JamRuby::MusicSessionHistory", inverse_of: :feed, foreign_key: 'music_session_id'
|
||||
belongs_to :music_session, class_name: "JamRuby::MusicSession", inverse_of: :feed, foreign_key: 'music_session_id'
|
||||
|
||||
FIXNUM_MAX = (2**(0.size * 8 -2) -1)
|
||||
SORT_TYPES = ['date', 'plays', 'likes']
|
||||
TIME_RANGES = { "today" => 1 , "week" => 7, "month" => 30, "all" => 0}
|
||||
TYPE_FILTERS = ['music_session_history', 'recording', 'all']
|
||||
TYPE_FILTERS = ['music_session', 'recording', 'all']
|
||||
|
||||
def self.index(user, params = {})
|
||||
limit = params[:limit]
|
||||
|
|
@ -39,9 +39,9 @@ module JamRuby
|
|||
target_user = params[:user]
|
||||
target_band = params[:band]
|
||||
|
||||
#query = Feed.includes([:recording]).includes([:music_session_history]).limit(limit)
|
||||
#query = Feed.includes([:recording]).includes([:music_session]).limit(limit)
|
||||
query = Feed.joins("LEFT OUTER JOIN recordings ON recordings.id = feeds.recording_id")
|
||||
.joins("LEFT OUTER JOIN music_sessions_history ON music_sessions_history.id = feeds.music_session_id")
|
||||
.joins("LEFT OUTER JOIN music_sessions ON music_sessions.id = feeds.music_session_id")
|
||||
.limit(limit)
|
||||
|
||||
# handle sort
|
||||
|
|
@ -50,10 +50,10 @@ module JamRuby
|
|||
query = query.order('feeds.id DESC')
|
||||
elsif sort == 'plays'
|
||||
query = query.offset(start)
|
||||
query = query.order("COALESCE(recordings.play_count, music_sessions_history.play_count) DESC ")
|
||||
query = query.order("COALESCE(recordings.play_count, music_sessions.play_count) DESC ")
|
||||
elsif sort == 'likes'
|
||||
query = query.offset(start)
|
||||
query = query.order("COALESCE(recordings.like_count, music_sessions_history.like_count) DESC ")
|
||||
query = query.order("COALESCE(recordings.like_count, music_sessions.like_count) DESC ")
|
||||
else
|
||||
raise "sort not implemented: #{sort}"
|
||||
end
|
||||
|
|
@ -65,7 +65,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# handle type filters
|
||||
if type_filter == 'music_session_history'
|
||||
if type_filter == 'music_session'
|
||||
query = query.where('feeds.music_session_id is not NULL')
|
||||
elsif type_filter == 'recording'
|
||||
query = query.where('feeds.recording_id is not NULL')
|
||||
|
|
@ -76,48 +76,48 @@ module JamRuby
|
|||
|
||||
if target_user != user.id
|
||||
require_public_recordings = "claimed_recordings.is_public = TRUE AND"
|
||||
require_public_sessions = "music_sessions_history.fan_access = TRUE AND"
|
||||
require_public_sessions = "music_sessions.fan_access = TRUE AND"
|
||||
end
|
||||
|
||||
query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND #{require_public_recordings} (claimed_recordings.user_id = '#{target_user}' OR (recordings.band_id IN (SELECT band_id FROM bands_musicians where user_id='#{target_user}')))")
|
||||
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions_history.id = music_sessions_user_history.music_session_id AND #{require_public_sessions} music_sessions_user_history.user_id = '#{target_user}'")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id")
|
||||
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND #{require_public_sessions} music_sessions_user_history.user_id = '#{target_user}'")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
||||
if sort == 'plays'
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)")
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
||||
elsif sort == 'likes'
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)")
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
||||
end
|
||||
query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL')
|
||||
query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
|
||||
elsif target_band
|
||||
|
||||
unless Band.find(target_band).users.include?(user)
|
||||
require_public_recordings = "claimed_recordings.is_public = TRUE AND"
|
||||
require_public_sessions = "music_sessions_history.fan_access = TRUE AND"
|
||||
require_public_sessions = "music_sessions.fan_access = TRUE AND"
|
||||
end
|
||||
|
||||
query = query.joins("LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND #{require_public_recordings} recordings.band_id = '#{target_band}'")
|
||||
query = query.where("music_sessions_history IS NULL OR #{require_public_sessions} music_sessions_history.band_id = '#{target_band}'")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id")
|
||||
query = query.where("music_sessions IS NULL OR #{require_public_sessions} music_sessions.band_id = '#{target_band}'")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
||||
if sort == 'plays'
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)")
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
||||
elsif sort == 'likes'
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)")
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
||||
end
|
||||
query = query.where('recordings.id is NULL OR claimed_recordings.id IS NOT NULL')
|
||||
#query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
#query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
else
|
||||
query = query.joins('LEFT OUTER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id AND claimed_recordings.is_public = TRUE')
|
||||
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions_history.id = music_sessions_user_history.music_session_id AND music_sessions_history.fan_access = TRUE")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions_history.id")
|
||||
query = query.joins("LEFT OUTER JOIN music_sessions_user_history ON music_sessions.id = music_sessions_user_history.music_session_id AND music_sessions.fan_access = TRUE")
|
||||
query = query.group("feeds.id, feeds.recording_id, feeds.music_session_id, feeds.created_at, feeds.updated_at, recordings.id, music_sessions.id")
|
||||
if sort == 'plays'
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions_history.play_count)")
|
||||
query = query.group("COALESCE(recordings.play_count, music_sessions.play_count)")
|
||||
elsif sort == 'likes'
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions_history.like_count)")
|
||||
query = query.group("COALESCE(recordings.like_count, music_sessions.like_count)")
|
||||
end
|
||||
query = query.where('recordings.id is NULL OR claimed_recordings.is_public = TRUE')
|
||||
query = query.where('music_sessions_history.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
query = query.where('music_sessions.id is NULL OR music_sessions_user_history.id IS NOT NULL')
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ module JamRuby
|
|||
ActiveRecord::Base.transaction do
|
||||
friend_request = FriendRequest.find(id)
|
||||
friend_request.status = status
|
||||
friend_request.updated_at = Time.now.getutc
|
||||
friend_request.updated_at = Time.now
|
||||
friend_request.save
|
||||
|
||||
# create both records for this friendship
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ module JamRuby
|
|||
has_many :band_genres, class_name: "JamRuby::BandGenre"
|
||||
has_many :bands, class_name: "JamRuby::Band", :through => :band_genres
|
||||
|
||||
|
||||
# music sessions
|
||||
has_many :music_sessions, :class_name => "JamRuby::MusicSession"
|
||||
|
||||
# genres
|
||||
has_and_belongs_to_many :recordings, :class_name => "JamRuby::Recording", :join_table => "recordings_genres"
|
||||
|
||||
# music sessions
|
||||
has_and_belongs_to_many :music_sessions, :class_name => "JamRuby::MusicSession", :join_table => "genres_music_sessions"
|
||||
|
||||
def to_s
|
||||
description
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module JamRuby
|
|||
:sourced_needs_changing_at, as: :admin
|
||||
|
||||
belongs_to :authentication, class_name: "JamRuby::IcecastUserAuthentication", inverse_of: :mount, :foreign_key => 'authentication_id'
|
||||
belongs_to :music_session, class_name: "JamRuby::MusicSession", inverse_of: :mount, foreign_key: 'music_session_id'
|
||||
belongs_to :music_session, class_name: "JamRuby::ActiveMusicSession", inverse_of: :mount, foreign_key: 'music_session_id'
|
||||
|
||||
belongs_to :server, class_name: "JamRuby::IcecastServer", inverse_of: :mounts, foreign_key: 'icecast_server_id'
|
||||
belongs_to :mount_template, class_name: "JamRuby::IcecastMountTemplate", inverse_of: :mounts, foreign_key: 'icecast_mount_template_id'
|
||||
|
|
@ -76,7 +76,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# creates a templated
|
||||
def self.build_session_mount(music_session, icecast_server)
|
||||
def self.build_session_mount(music_session, active_music_session, icecast_server)
|
||||
|
||||
# only public sessions get mounts currently
|
||||
return nil unless music_session.fan_access
|
||||
|
|
@ -84,7 +84,7 @@ module JamRuby
|
|||
mount = nil
|
||||
if icecast_server && icecast_server.mount_template_id
|
||||
# we have a server with an associated mount_template; we can create a mount automatically
|
||||
mount = icecast_server.mount_template.build_session_mount(music_session)
|
||||
mount = icecast_server.mount_template.build_session_mount(music_session, active_music_session)
|
||||
mount.server = icecast_server
|
||||
end
|
||||
mount
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# pick a server that's in the same group as the user that is under the least load
|
||||
def build_session_mount(music_session)
|
||||
def build_session_mount(music_session, active_music_session)
|
||||
mount = IcecastMount.new
|
||||
mount.authentication = authentication
|
||||
mount.mount_template = self
|
||||
|
|
@ -55,7 +55,7 @@ module JamRuby
|
|||
mount.stream_name = "JamKazam music session created by #{music_session.creator.name}"
|
||||
mount.stream_description = music_session.description
|
||||
mount.stream_url = "http://www.jamkazam.com" ## TODO/XXX, the jamkazam url should be the page hosting the widget
|
||||
mount.genre = music_session.genres.map {|genre| genre.description}.join(',')
|
||||
mount.genre = music_session.genre.description
|
||||
mount
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ module JamRuby
|
|||
has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :inverse_of => :instrument
|
||||
|
||||
# music sessions
|
||||
has_and_belongs_to_many :music_sessions, :class_name => "JamRuby::MusicSession", :join_table => "genres_music_sessions"
|
||||
has_and_belongs_to_many :music_sessions, :class_name => "JamRuby::ActiveMusicSession", :join_table => "genres_music_sessions"
|
||||
|
||||
def self.standard_list
|
||||
return Instrument.where('instruments.popularity > 0').order('instruments.popularity DESC, instruments.description ASC')
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
belongs_to :sender, :inverse_of => :sent_invitations, :class_name => "JamRuby::User", :foreign_key => "sender_id"
|
||||
belongs_to :receiver, :inverse_of => :received_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id"
|
||||
belongs_to :music_session, :inverse_of => :invitations, :class_name => "JamRuby::MusicSession"
|
||||
belongs_to :music_session, :inverse_of => :invitations, :class_name => "JamRuby::MusicSession", :foreign_key => "music_session_id"
|
||||
belongs_to :join_request, :inverse_of => :invitations, :class_name => "JamRuby::JoinRequest"
|
||||
|
||||
validates :sender, :presence => true
|
||||
|
|
@ -20,7 +20,7 @@ module JamRuby
|
|||
private
|
||||
|
||||
def require_sender_in_music_session
|
||||
unless music_session.users.exists? sender
|
||||
unless music_session.part_of_session? sender
|
||||
errors.add(:music_session, MEMBERSHIP_REQUIRED_OF_MUSIC_SESSION)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :user, :class_name => "JamRuby::User"
|
||||
belongs_to :music_session, :class_name => "JamRuby::MusicSession"
|
||||
belongs_to :music_session, :class_name => "JamRuby::MusicSession", :foreign_key => "music_session_id"
|
||||
has_many :invitations, :inverse_of => :join_request, :class_name => "JamRuby::Invitation"
|
||||
|
||||
validates :user, :presence => true
|
||||
|
|
|
|||
|
|
@ -1,39 +1,32 @@
|
|||
module JamRuby
|
||||
class MusicSession < ActiveRecord::Base
|
||||
|
||||
attr_accessor :legal_terms
|
||||
|
||||
self.table_name = "music_sessions"
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessor :legal_terms, :skip_genre_validation, :max_score
|
||||
attr_accessible :creator, :description, :musician_access, :approval_required, :fan_chat, :fan_access, :genres
|
||||
belongs_to :creator,:class_name => 'JamRuby::User', :foreign_key => :user_id, :inverse_of => :music_session_histories
|
||||
|
||||
belongs_to :creator, :inverse_of => :music_sessions, :class_name => "JamRuby::User", :foreign_key => "user_id"
|
||||
belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id", :inverse_of => :playing_sessions
|
||||
belongs_to :claimed_recording_initiator, :class_name => "JamRuby::User", :inverse_of => :playing_claimed_recordings, :foreign_key => "claimed_recording_initiator_id"
|
||||
belongs_to :band, :class_name => 'JamRuby::Band', :foreign_key => :band_id, :inverse_of => :music_sessions
|
||||
|
||||
has_one :music_session_history, :class_name => "JamRuby::MusicSessionHistory"
|
||||
has_one :mount, :class_name => "JamRuby::IcecastMount", :inverse_of => :music_session, :foreign_key => 'music_session_id'
|
||||
belongs_to :active_music_session, :class_name => 'JamRuby::ActiveMusicSession', foreign_key: :music_session_id
|
||||
|
||||
has_many :connections, :class_name => "JamRuby::Connection"
|
||||
has_many :users, :through => :connections, :class_name => "JamRuby::User"
|
||||
has_and_belongs_to_many :genres, :class_name => "::JamRuby::Genre", :join_table => "genres_music_sessions"
|
||||
has_many :join_requests, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::JoinRequest"
|
||||
has_many :invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::Invitation"
|
||||
has_many :music_session_user_histories, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id", :dependent => :delete_all
|
||||
has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
|
||||
has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "session_id"
|
||||
has_many :plays, :class_name => "JamRuby::PlayablePlay", :as => :playable, :dependent => :destroy
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
has_one :feed, :class_name => "JamRuby::Feed", :inverse_of => :music_session, :foreign_key => 'music_session_id', :dependent => :destroy
|
||||
belongs_to :genre, :class_name => "JamRuby::Genre", :inverse_of => :music_sessions, :foreign_key => 'genre_id'
|
||||
has_many :join_requests, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::JoinRequest", :foreign_key => "music_session_id"
|
||||
has_many :invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::Invitation", :foreign_key => "music_session_id"
|
||||
has_many :invited_musicians, :through => :invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver
|
||||
|
||||
has_many :fan_invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::FanInvitation"
|
||||
has_many :fan_invitations, :foreign_key => "music_session_id", :inverse_of => :music_session, :class_name => "JamRuby::FanInvitation", :foreign_key => "music_session_id"
|
||||
has_many :invited_fans, :through => :fan_invitations, :class_name => "JamRuby::User", :foreign_key => "receiver_id", :source => :receiver
|
||||
has_many :recordings, :class_name => "JamRuby::Recording", :inverse_of => :music_session
|
||||
has_many :chats, :class_name => "JamRuby::ChatMessages", :foreign_key => "session_id"
|
||||
belongs_to :band, :inverse_of => :music_sessions, :class_name => "JamRuby::Band", :foreign_key => "band_id"
|
||||
|
||||
after_create :started_session
|
||||
|
||||
validate :require_at_least_one_genre, :limit_max_genres
|
||||
after_save :sync_music_session_history
|
||||
|
||||
after_destroy do |obj|
|
||||
JamRuby::MusicSessionHistory.removed_music_session(obj.id)
|
||||
end
|
||||
|
||||
validates :genre, :presence => true
|
||||
validates :description, :presence => true, :no_profanity => true
|
||||
validates :fan_chat, :inclusion => {:in => [true, false]}
|
||||
validates :fan_access, :inclusion => {:in => [true, false]}
|
||||
|
|
@ -42,400 +35,184 @@ module JamRuby
|
|||
validates :legal_terms, :inclusion => {:in => [true]}, :on => :create
|
||||
validates :creator, :presence => true
|
||||
validate :creator_is_musician
|
||||
validate :no_new_playback_while_playing
|
||||
|
||||
#default_scope :select => "*, 0 as score"
|
||||
before_create :generate_share_token
|
||||
before_create :add_to_feed
|
||||
|
||||
def attributes
|
||||
super.merge('max_score' => self.max_score)
|
||||
SHARE_TOKEN_LENGTH = 8
|
||||
|
||||
SEPARATOR = '|'
|
||||
|
||||
def add_to_feed
|
||||
feed = Feed.new
|
||||
feed.music_session = self
|
||||
end
|
||||
|
||||
def max_score
|
||||
nil unless has_attribute?(:max_score)
|
||||
read_attribute(:max_score).to_i
|
||||
def comment_count
|
||||
self.comments.size
|
||||
end
|
||||
|
||||
before_create :create_uuid
|
||||
def create_uuid
|
||||
#self.id = SecureRandom.uuid
|
||||
end
|
||||
|
||||
def before_destroy
|
||||
self.mount.destroy if self.mount
|
||||
end
|
||||
|
||||
def creator_is_musician
|
||||
unless creator.musician?
|
||||
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
|
||||
end
|
||||
end
|
||||
|
||||
def no_new_playback_while_playing
|
||||
# if we previous had a claimed recording and are trying to set one
|
||||
# and if also the previous initiator is different than the current one... it's a no go
|
||||
if !claimed_recording_id_was.nil? && !claimed_recording_id.nil? &&
|
||||
claimed_recording_initiator_id_was != claimed_recording_initiator_id
|
||||
errors.add(:claimed_recording, ValidationMessages::CLAIMED_RECORDING_ALREADY_IN_PROGRESS)
|
||||
end
|
||||
end
|
||||
|
||||
# returns an array of client_id's that are in this session
|
||||
# if as_musician is nil, all connections in the session ,regardless if it's a musician or not or not
|
||||
# you can also exclude a client_id from the returned set by setting exclude_client_id
|
||||
def get_connection_ids(options = {})
|
||||
as_musician = options[:as_musician]
|
||||
exclude_client_id = options[:exclude_client_id]
|
||||
|
||||
where = { :music_session_id => self.id }
|
||||
where[:as_musician] = as_musician unless as_musician.nil?
|
||||
|
||||
exclude = "client_id != '#{exclude_client_id}'"unless exclude_client_id.nil?
|
||||
|
||||
Connection.select(:client_id).where(where).where(exclude).map(&:client_id)
|
||||
end
|
||||
|
||||
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
|
||||
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
|
||||
def self.index(current_user, options = {})
|
||||
participants = options[:participants]
|
||||
genres = options[:genres]
|
||||
keyword = options[:keyword]
|
||||
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
|
||||
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
|
||||
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
|
||||
|
||||
query = MusicSession
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
connections
|
||||
ON
|
||||
music_sessions.id = connections.music_session_id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
friendships
|
||||
ON
|
||||
connections.user_id = friendships.user_id
|
||||
AND
|
||||
friendships.friend_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
invitations
|
||||
ON
|
||||
invitations.music_session_id = music_sessions.id
|
||||
AND
|
||||
invitations.receiver_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.group(
|
||||
%Q{
|
||||
music_sessions.id
|
||||
}
|
||||
)
|
||||
.order(
|
||||
%Q{
|
||||
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
music_sessions.created_at DESC
|
||||
}
|
||||
)
|
||||
|
||||
if as_musician
|
||||
query = query.where(
|
||||
%Q{
|
||||
musician_access = true
|
||||
OR
|
||||
invitations.id IS NOT NULL
|
||||
}
|
||||
)
|
||||
else
|
||||
# if you are trying to join the session as a fan/listener,
|
||||
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
|
||||
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
|
||||
query = query.where(:fan_access => true)
|
||||
query = query.where("(music_sessions.created_at < icecast_servers.config_updated_at)")
|
||||
end
|
||||
|
||||
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
|
||||
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
|
||||
query = query.joins(:genres).where("genres.id" => genres.split(',')) unless genres.nil?
|
||||
|
||||
if my_bands_only
|
||||
query = query.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
bands_musicians
|
||||
ON
|
||||
bands_musicians.user_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
if my_bands_only || friends_only
|
||||
query = query.where(
|
||||
%Q{
|
||||
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
|
||||
OR
|
||||
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
# This is a little confusing. You can specify *BOTH* friends_only and my_bands_only to be true
|
||||
# If so, then it's an OR condition. If both are false, you can get sessions with anyone.
|
||||
# note, this is mostly the same as above but includes paging through the result and and scores.
|
||||
# thus it needs the client_id...
|
||||
def self.nindex(current_user, options = {})
|
||||
client_id = options[:client_id]
|
||||
participants = options[:participants]
|
||||
genres = options[:genres]
|
||||
keyword = options[:keyword]
|
||||
friends_only = options[:friends_only].nil? ? false : options[:friends_only]
|
||||
my_bands_only = options[:my_bands_only].nil? ? false : options[:my_bands_only]
|
||||
as_musician = options[:as_musician].nil? ? true : options[:as_musician]
|
||||
offset = options[:offset]
|
||||
limit = options[:limit]
|
||||
|
||||
connection = Connection.where(client_id: client_id).first!
|
||||
locidispid = connection.locidispid
|
||||
|
||||
query = MusicSession
|
||||
.select("music_sessions.*, max(coalesce(current_scores.score, 1000)) as max_score") # 1000 is higher than the allowed max of 999
|
||||
.joins(
|
||||
%Q{
|
||||
INNER JOIN
|
||||
connections
|
||||
ON
|
||||
music_sessions.id = connections.music_session_id
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
current_scores
|
||||
ON
|
||||
current_scores.alocidispid = connections.locidispid
|
||||
AND
|
||||
current_scores.blocidispid = #{locidispid}
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
friendships
|
||||
ON
|
||||
connections.user_id = friendships.user_id
|
||||
AND
|
||||
friendships.friend_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
invitations
|
||||
ON
|
||||
invitations.music_session_id = music_sessions.id
|
||||
AND
|
||||
invitations.receiver_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
.group(
|
||||
%Q{
|
||||
music_sessions.id
|
||||
}
|
||||
)
|
||||
.order(
|
||||
%Q{
|
||||
SUM(CASE WHEN invitations.id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
SUM(CASE WHEN friendships.user_id IS NULL THEN 0 ELSE 1 END) DESC,
|
||||
music_sessions.created_at DESC
|
||||
}
|
||||
)
|
||||
|
||||
if (offset)
|
||||
query = query.offset(offset)
|
||||
end
|
||||
|
||||
if (limit)
|
||||
query = query.limit(limit)
|
||||
end
|
||||
|
||||
if as_musician
|
||||
query = query.where(
|
||||
%Q{
|
||||
musician_access = true
|
||||
OR
|
||||
music_sessions.user_id = '#{current_user.id}'
|
||||
OR
|
||||
invitations.id IS NOT NULL
|
||||
}
|
||||
)
|
||||
else
|
||||
# if you are trying to join the session as a fan/listener,
|
||||
# we have to have a mount, fan_access has to be true, and we have to allow for the reload of icecast to have taken effect
|
||||
query = query.joins('INNER JOIN icecast_mounts ON icecast_mounts.music_session_id = music_sessions.id INNER JOIN icecast_servers ON icecast_mounts.icecast_server_id = icecast_servers.id')
|
||||
query = query.where(:fan_access => true)
|
||||
query = query.where("(music_sessions.created_at < icecast_servers.config_updated_at)")
|
||||
end
|
||||
|
||||
query = query.where("music_sessions.description like '%#{keyword}%'") unless keyword.nil?
|
||||
query = query.where("connections.user_id" => participants.split(',')) unless participants.nil?
|
||||
query = query.joins(:genres).where("genres.id" => genres.split(',')) unless genres.nil?
|
||||
|
||||
if my_bands_only
|
||||
query = query.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
bands_musicians
|
||||
ON
|
||||
bands_musicians.user_id = '#{current_user.id}'
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
if my_bands_only || friends_only
|
||||
query = query.where(
|
||||
%Q{
|
||||
#{friends_only ? "friendships.user_id IS NOT NULL" : "false"}
|
||||
OR
|
||||
#{my_bands_only ? "bands_musicians.band_id = music_sessions.band_id" : "false"}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
return query
|
||||
end
|
||||
|
||||
# Verifies that the specified user can join this music session
|
||||
def can_join? user, as_musician
|
||||
if as_musician
|
||||
if !user.musician
|
||||
return false # "a fan can not join a music session as a musician"
|
||||
raise PermissionError, "a fan can not join a music session as a musician"
|
||||
end
|
||||
|
||||
if self.musician_access
|
||||
if self.approval_required
|
||||
return self.invited_musicians.exists?(user)
|
||||
else
|
||||
return true
|
||||
def grouped_tracks
|
||||
tracks = []
|
||||
self.music_session_user_histories.each do |msuh|
|
||||
user = User.find(msuh.user_id)
|
||||
t = Track.new
|
||||
t.musician = user
|
||||
t.instrument_ids = []
|
||||
# this treats each track as a "user", which has 1 or more instruments in the session
|
||||
unless msuh.instruments.blank?
|
||||
instruments = msuh.instruments.split(SEPARATOR)
|
||||
instruments.each do |instrument|
|
||||
if !t.instrument_ids.include? instrument
|
||||
t.instrument_ids << instrument
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
# the creator can always join, and the invited users can join
|
||||
return self.creator == user || self.invited_musicians.exists?(user)
|
||||
end
|
||||
else
|
||||
# it's a fan, and the only way a fan can join is if fan_access is true
|
||||
return self.fan_access
|
||||
tracks << t
|
||||
end
|
||||
tracks
|
||||
end
|
||||
|
||||
def self.index(current_user, user_id, band_id = nil, genre = nil)
|
||||
hide_private = false
|
||||
if current_user.id != user_id
|
||||
hide_private = false # TODO: change to true once public flag exists
|
||||
end
|
||||
|
||||
query = MusicSession
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
music_sessions_user_history
|
||||
ON
|
||||
music_sessions.id = music_sessions_user_history.music_session_id
|
||||
}
|
||||
)
|
||||
.where(
|
||||
%Q{
|
||||
music_sessions.user_id = '#{user_id}'
|
||||
}
|
||||
)
|
||||
|
||||
#query = query.where("public = false") unless !hide_private
|
||||
query = query.where("music_sessions.band_id = '#{band_id}") unless band_id.nil?
|
||||
query = query.where("music_sessions.genres like '%#{genre}%'") unless genre.nil?
|
||||
return query
|
||||
end
|
||||
|
||||
def unique_users
|
||||
User
|
||||
.joins(:music_session_user_histories)
|
||||
.group("users.id")
|
||||
.order("users.id")
|
||||
.where(%Q{ music_sessions_user_history.music_session_id = '#{id}'})
|
||||
end
|
||||
|
||||
# returns one user history per user, with instruments all crammed together, and with total duration
|
||||
def unique_user_histories
|
||||
MusicSessionUserHistory
|
||||
.joins(:user)
|
||||
.select("STRING_AGG(instruments, '|') AS total_instruments,
|
||||
SUM(date_part('epoch', COALESCE(music_sessions_user_history.session_removed_at, music_sessions_user_history.created_at) - music_sessions_user_history.created_at)) AS total_duration,
|
||||
music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
|
||||
.group("music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
|
||||
.order("music_sessions_user_history.user_id")
|
||||
.where(%Q{ music_sessions_user_history.music_session_id = '#{id}'})
|
||||
end
|
||||
|
||||
def duration_minutes
|
||||
end_time = self.session_removed_at || Time.now
|
||||
(end_time - self.created_at) / 60.0
|
||||
end
|
||||
|
||||
def music_session_user_histories
|
||||
@msuh ||= JamRuby::MusicSessionUserHistory
|
||||
.where(:music_session_id => self.id)
|
||||
.order('created_at DESC')
|
||||
end
|
||||
|
||||
def comments
|
||||
@comments ||= JamRuby::MusicSessionComment
|
||||
.where(:music_session_id => self.id)
|
||||
.order('created_at DESC')
|
||||
end
|
||||
|
||||
def likes
|
||||
@likes ||= JamRuby::MusicSessionLiker
|
||||
.where(:music_session_id => self.music_session_id)
|
||||
end
|
||||
|
||||
# these are 'users that are a part of this session'
|
||||
# which means are currently in the music_session, or, rsvp'ed, or creator
|
||||
def part_of_session? user
|
||||
# XXX check RSVP'ed
|
||||
user == self.creator || (active_music_session ? active_music_session.users.exists?(user) : false)
|
||||
end
|
||||
|
||||
def is_over?
|
||||
active_music_session.nil?
|
||||
end
|
||||
|
||||
def has_mount?
|
||||
active_music_session && active_music_session.mount
|
||||
end
|
||||
|
||||
def recordings
|
||||
Recording.where(music_session_id: self.id)
|
||||
end
|
||||
|
||||
def end_history
|
||||
self.update_attribute(:session_removed_at, Time.now)
|
||||
|
||||
|
||||
# ensure all user histories are closed
|
||||
music_session_user_histories.each do |music_session_user_history|
|
||||
music_session_user_history.end_history
|
||||
|
||||
# then update any users that need their user progress updated
|
||||
if music_session_user_history.duration_minutes > 15 && music_session_user_history.max_concurrent_connections >= 3
|
||||
music_session_user_history.user.update_progression_field(:first_real_music_session_at)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Verifies that the specified user can see this music session
|
||||
def can_see? user
|
||||
if self.musician_access || self.fan_access
|
||||
return true
|
||||
else
|
||||
return self.creator == user || self.invited_musicians.exists?(user)
|
||||
end
|
||||
def self.removed_music_session(session_id)
|
||||
hist = self
|
||||
.where(:id => session_id)
|
||||
.limit(1)
|
||||
.first
|
||||
|
||||
hist.end_history if hist
|
||||
|
||||
Notification.send_session_ended(session_id)
|
||||
end
|
||||
|
||||
# Verifies that the specified user can delete this music session
|
||||
def can_delete? user
|
||||
# the creator can delete
|
||||
return self.creator == user
|
||||
end
|
||||
|
||||
def access? user
|
||||
return self.users.exists? user
|
||||
end
|
||||
|
||||
def most_recent_recording
|
||||
recordings.where(:music_session_id => self.id).order('created_at desc').limit(1).first
|
||||
end
|
||||
|
||||
# is this music session currently recording?
|
||||
def is_recording?
|
||||
recordings.where(:duration => nil).count > 0
|
||||
end
|
||||
|
||||
def is_playing_recording?
|
||||
!self.claimed_recording.nil?
|
||||
end
|
||||
|
||||
def recording
|
||||
recordings.where(:duration => nil).first
|
||||
end
|
||||
|
||||
# stops any active recording
|
||||
def stop_recording
|
||||
current_recording = self.recording
|
||||
current_recording.stop unless current_recording.nil?
|
||||
end
|
||||
|
||||
def claimed_recording_start(owner, claimed_recording)
|
||||
self.claimed_recording = claimed_recording
|
||||
self.claimed_recording_initiator = owner
|
||||
self.save
|
||||
end
|
||||
|
||||
def claimed_recording_stop
|
||||
self.claimed_recording = nil
|
||||
self.claimed_recording_initiator = nil
|
||||
self.save
|
||||
end
|
||||
|
||||
def to_s
|
||||
description
|
||||
end
|
||||
|
||||
def tick_track_changes
|
||||
self.track_changes_counter += 1
|
||||
self.save!(:validate => false)
|
||||
end
|
||||
|
||||
def connected_participant_count
|
||||
Connection.where(:music_session_id => self.id,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
:as_musician => true)
|
||||
.count
|
||||
end
|
||||
|
||||
def started_session
|
||||
GoogleAnalyticsEvent.track_session_duration(self)
|
||||
GoogleAnalyticsEvent.track_band_real_session(self)
|
||||
def remove_non_alpha_num(token)
|
||||
token.gsub(/[^0-9A-Za-z]/, '')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_at_least_one_genre
|
||||
unless skip_genre_validation
|
||||
if self.genres.length < Limits::MIN_GENRES_PER_SESSION
|
||||
errors.add(:genres, ValidationMessages::SESSION_GENRE_MINIMUM_NOT_MET)
|
||||
end
|
||||
def generate_share_token
|
||||
|
||||
token = loop do
|
||||
token = SecureRandom.urlsafe_base64(SHARE_TOKEN_LENGTH, false)
|
||||
token = remove_non_alpha_num(token)
|
||||
token.upcase!
|
||||
break token unless ShareToken.exists?(token: token)
|
||||
end
|
||||
|
||||
self.share_token = ShareToken.new
|
||||
self.share_token.token = token
|
||||
self.share_token.shareable_type = "session"
|
||||
end
|
||||
|
||||
def creator_is_musician
|
||||
unless creator && creator.musician?
|
||||
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
|
||||
end
|
||||
end
|
||||
|
||||
def limit_max_genres
|
||||
unless skip_genre_validation
|
||||
if self.genres.length > Limits::MAX_GENRES_PER_SESSION
|
||||
errors.add(:genres, ValidationMessages::SESSION_GENRE_LIMIT_EXCEEDED)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def sync_music_session_history
|
||||
MusicSessionHistory.save(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ module JamRuby
|
|||
|
||||
default_scope order('created_at DESC')
|
||||
|
||||
belongs_to(:music_session_history,
|
||||
:class_name => "JamRuby::MusicSessionHistory",
|
||||
belongs_to(:music_session,
|
||||
:class_name => "JamRuby::MusicSession",
|
||||
:foreign_key => "music_session_id")
|
||||
|
||||
belongs_to(:user,
|
||||
|
|
|
|||
|
|
@ -1,212 +0,0 @@
|
|||
module JamRuby
|
||||
class MusicSessionHistory < ActiveRecord::Base
|
||||
|
||||
self.table_name = "music_sessions_history"
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to(:user,
|
||||
:class_name => 'JamRuby::User',
|
||||
:foreign_key => :user_id,
|
||||
:inverse_of => :music_session_histories)
|
||||
|
||||
belongs_to(:band,
|
||||
:class_name => 'JamRuby::Band',
|
||||
:foreign_key => :band_id,
|
||||
:inverse_of => :music_session_history)
|
||||
|
||||
belongs_to(:music_session,
|
||||
:class_name => 'JamRuby::MusicSession',
|
||||
:foreign_key => 'music_session_id')
|
||||
|
||||
has_many :music_session_user_histories, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id", :dependent => :delete_all
|
||||
has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
|
||||
has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "session_id"
|
||||
has_many :plays, :class_name => "JamRuby::PlayablePlay", :as => :playable, :dependent => :destroy
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
has_one :feed, :class_name => "JamRuby::Feed", :inverse_of => :music_session_history, :foreign_key => 'music_session_id', :dependent => :destroy
|
||||
|
||||
|
||||
before_create :generate_share_token
|
||||
before_create :add_to_feed
|
||||
|
||||
SHARE_TOKEN_LENGTH = 8
|
||||
|
||||
SEPARATOR = '|'
|
||||
|
||||
def add_to_feed
|
||||
feed = Feed.new
|
||||
feed.music_session_history = self
|
||||
end
|
||||
|
||||
def comment_count
|
||||
self.comments.size
|
||||
end
|
||||
|
||||
def grouped_tracks
|
||||
tracks = []
|
||||
self.music_session_user_histories.each do |msuh|
|
||||
user = User.find(msuh.user_id)
|
||||
t = Track.new
|
||||
t.musician = user
|
||||
t.instrument_ids = []
|
||||
# this treats each track as a "user", which has 1 or more instruments in the session
|
||||
unless msuh.instruments.blank?
|
||||
instruments = msuh.instruments.split(SEPARATOR)
|
||||
instruments.each do |instrument|
|
||||
if !t.instrument_ids.include? instrument
|
||||
t.instrument_ids << instrument
|
||||
end
|
||||
end
|
||||
end
|
||||
tracks << t
|
||||
end
|
||||
tracks
|
||||
end
|
||||
|
||||
def self.index(current_user, user_id, band_id = nil, genre = nil)
|
||||
hide_private = false
|
||||
if current_user.id != user_id
|
||||
hide_private = false # TODO: change to true once public flag exists
|
||||
end
|
||||
|
||||
query = MusicSessionHistory
|
||||
.joins(
|
||||
%Q{
|
||||
LEFT OUTER JOIN
|
||||
music_sessions_user_history
|
||||
ON
|
||||
music_sessions_history.music_session_id = music_sessions_user_history.music_session_id
|
||||
}
|
||||
)
|
||||
.where(
|
||||
%Q{
|
||||
music_sessions_history.user_id = '#{user_id}'
|
||||
}
|
||||
)
|
||||
|
||||
#query = query.where("public = false") unless !hide_private
|
||||
query = query.where("music_sessions_history.band_id = '#{band_id}") unless band_id.nil?
|
||||
query = query.where("music_sessions_history.genres like '%#{genre}%'") unless genre.nil?
|
||||
return query
|
||||
end
|
||||
|
||||
def unique_users
|
||||
User
|
||||
.joins(:music_session_user_histories)
|
||||
.group("users.id")
|
||||
.order("users.id")
|
||||
.where(%Q{ music_sessions_user_history.music_session_id = '#{music_session_id}'})
|
||||
end
|
||||
|
||||
# returns one user history per user, with instruments all crammed together, and with total duration
|
||||
def unique_user_histories
|
||||
MusicSessionUserHistory
|
||||
.joins(:user)
|
||||
.select("STRING_AGG(instruments, '|') AS total_instruments,
|
||||
SUM(date_part('epoch', COALESCE(music_sessions_user_history.session_removed_at, music_sessions_user_history.created_at) - music_sessions_user_history.created_at)) AS total_duration,
|
||||
music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
|
||||
.group("music_sessions_user_history.user_id, music_sessions_user_history.music_session_id, users.first_name, users.last_name, users.photo_url")
|
||||
.order("music_sessions_user_history.user_id")
|
||||
.where(%Q{ music_sessions_user_history.music_session_id = '#{music_session_id}'})
|
||||
end
|
||||
|
||||
def duration_minutes
|
||||
end_time = self.session_removed_at || Time.now
|
||||
(end_time - self.created_at) / 60.0
|
||||
end
|
||||
|
||||
def music_session_user_histories
|
||||
@msuh ||= JamRuby::MusicSessionUserHistory
|
||||
.where(:music_session_id => self.music_session_id)
|
||||
.order('created_at DESC')
|
||||
end
|
||||
|
||||
def comments
|
||||
@comments ||= JamRuby::MusicSessionComment
|
||||
.where(:music_session_id => self.music_session_id)
|
||||
.order('created_at DESC')
|
||||
end
|
||||
|
||||
def likes
|
||||
@likes ||= JamRuby::MusicSessionLiker
|
||||
.where(:music_session_id => self.music_session_id)
|
||||
end
|
||||
|
||||
def self.save(music_session)
|
||||
session_history = MusicSessionHistory.find_by_music_session_id(music_session.id)
|
||||
|
||||
if session_history.nil?
|
||||
session_history = MusicSessionHistory.new
|
||||
end
|
||||
|
||||
session_history.music_session_id = music_session.id
|
||||
session_history.description = music_session.description unless music_session.description.nil?
|
||||
session_history.user_id = music_session.creator.id
|
||||
session_history.band_id = music_session.band.id unless music_session.band.nil?
|
||||
session_history.genres = music_session.genres.map { |g| g.id }.join SEPARATOR if music_session.genres.count > 0
|
||||
session_history.fan_access = music_session.fan_access
|
||||
session_history.save!
|
||||
end
|
||||
|
||||
def is_over?
|
||||
music_session.nil? || !session_removed_at.nil?
|
||||
end
|
||||
|
||||
def has_mount?
|
||||
music_session && music_session.mount
|
||||
end
|
||||
|
||||
def recordings
|
||||
Recording.where(music_session_id: self.id)
|
||||
end
|
||||
|
||||
def end_history
|
||||
self.update_attribute(:session_removed_at, Time.now)
|
||||
|
||||
|
||||
# ensure all user histories are closed
|
||||
music_session_user_histories.each do |music_session_user_history|
|
||||
music_session_user_history.end_history
|
||||
|
||||
# then update any users that need their user progress updated
|
||||
if music_session_user_history.duration_minutes > 15 && music_session_user_history.max_concurrent_connections >= 3
|
||||
music_session_user_history.user.update_progression_field(:first_real_music_session_at)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.removed_music_session(session_id)
|
||||
hist = self
|
||||
.where(:music_session_id => session_id)
|
||||
.limit(1)
|
||||
.first
|
||||
|
||||
hist.end_history if hist
|
||||
|
||||
Notification.send_session_ended(session_id)
|
||||
end
|
||||
|
||||
def remove_non_alpha_num(token)
|
||||
token.gsub(/[^0-9A-Za-z]/, '')
|
||||
end
|
||||
|
||||
private
|
||||
def generate_share_token
|
||||
self.id = music_session.id # unify music_session.id and music_session_history.id
|
||||
|
||||
token = loop do
|
||||
token = SecureRandom.urlsafe_base64(SHARE_TOKEN_LENGTH, false)
|
||||
token = remove_non_alpha_num(token)
|
||||
token.upcase!
|
||||
break token unless ShareToken.exists?(token: token)
|
||||
end
|
||||
|
||||
self.share_token = ShareToken.new
|
||||
self.share_token.token = token
|
||||
self.share_token.shareable_type = "session"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -5,7 +5,7 @@ module JamRuby
|
|||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :music_session_history, class_name:"JamRuby::MusicSessionHistory", foreign_key: "music_session_id", :counter_cache => :like_count
|
||||
belongs_to :music_session, class_name:"JamRuby::MusicSession", foreign_key: "music_session_id", :counter_cache => :like_count
|
||||
|
||||
belongs_to :user, class_name: "JamRuby::User", foreign_key: "liker_id"
|
||||
|
||||
|
|
|
|||
|
|
@ -7,13 +7,13 @@ module JamRuby
|
|||
|
||||
attr_accessible :uri
|
||||
|
||||
belongs_to(:music_session_history,
|
||||
:class_name => "JamRuby::MusicSessionHistory",
|
||||
belongs_to(:music_session,
|
||||
:class_name => "JamRuby::MusicSession",
|
||||
:foreign_key => :music_session_id)
|
||||
|
||||
# mount_uploader :uri, PerfDataUploader
|
||||
|
||||
validates :music_session_history, :presence => true
|
||||
validates :music_session, :presence => true
|
||||
validates :client_id, :presence => true
|
||||
validates :uri, :presence => true
|
||||
|
||||
|
|
|
|||
|
|
@ -6,21 +6,27 @@ module JamRuby
|
|||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :max_concurrent_connections, :session_removed_at, :rating
|
||||
validates_inclusion_of :rating, :in => -1..1, :allow_nil => true
|
||||
|
||||
belongs_to(:user,
|
||||
:class_name => "JamRuby::User",
|
||||
:foreign_key => "user_id",
|
||||
:inverse_of => :music_session_user_histories)
|
||||
|
||||
belongs_to(:music_session_history,
|
||||
:class_name => "MusicSessionHistory",
|
||||
belongs_to(:music_session,
|
||||
:class_name => "MusicSession",
|
||||
:foreign_key => "music_session_id")
|
||||
|
||||
validates_inclusion_of :rating, :in => 0..2, :allow_nil => true
|
||||
after_save :track_user_progression
|
||||
def self.latest_history(client_id)
|
||||
self.where(:client_id => client_id)
|
||||
.order('created_at DESC')
|
||||
.limit(1)
|
||||
.includes(:user)
|
||||
.first
|
||||
end
|
||||
|
||||
def music_session_history
|
||||
@msh ||= JamRuby::MusicSessionHistory.find_by_music_session_id(self.music_session_id)
|
||||
def music_session
|
||||
@msh ||= JamRuby::MusicSession.find_by_music_session_id(self.music_session_id)
|
||||
end
|
||||
|
||||
def perf_data
|
||||
|
|
@ -104,10 +110,23 @@ module JamRuby
|
|||
self.perf_data.try(:uri)
|
||||
end
|
||||
|
||||
def track_user_progression
|
||||
if self.rating == 0
|
||||
user.update_progression_field(:first_good_music_session_at)
|
||||
end
|
||||
def add_rating(rval, comment='')
|
||||
rval = rval.to_i
|
||||
self.rating = rval if 0 != rval
|
||||
self.rating_comment = comment
|
||||
end
|
||||
|
||||
MIN_SESSION_DURATION_RATING = 60
|
||||
|
||||
def should_rate_session?
|
||||
(2 <= music_session.unique_users.all.count &&
|
||||
MIN_SESSION_DURATION_RATING < (Time.now - music_session.created_at).seconds) ||
|
||||
Rails.env.development?
|
||||
end
|
||||
|
||||
def good_rating?
|
||||
0 < self.rating.to_i
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module JamRuby
|
|||
belongs_to :target_user, :class_name => "JamRuby::User", :foreign_key => "target_user_id"
|
||||
belongs_to :source_user, :class_name => "JamRuby::User", :foreign_key => "source_user_id"
|
||||
belongs_to :band, :class_name => "JamRuby::Band", :foreign_key => "band_id"
|
||||
belongs_to :session, :class_name => "JamRuby::MusicSession", :foreign_key => "session_id"
|
||||
belongs_to :session, :class_name => "JamRuby::ActiveMusicSession", :foreign_key => "session_id"
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id"
|
||||
|
||||
validates :target_user, :presence => true
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ class JamRuby::PromoLatest < JamRuby::Promotional
|
|||
|
||||
attr_accessible :latest
|
||||
|
||||
def music_session_history
|
||||
self.latest if self.latest.is_a? MusicSessionHistory
|
||||
def music_session
|
||||
self.latest if self.latest.is_a? MusicSession
|
||||
end
|
||||
|
||||
def recording
|
||||
|
|
@ -101,7 +101,7 @@ class JamRuby::PromoLatest < JamRuby::Promotional
|
|||
def update_with_params(params)
|
||||
if (latest_id = params[:latest_id]).present?
|
||||
self.latest = Recording.where(:id => latest_id).limit(1).first ||
|
||||
MusicSessionHistory.where(:id => latest_id).limit(1).first
|
||||
MusicSession.where(:id => latest_id).limit(1).first
|
||||
end
|
||||
self.position = params[:position]
|
||||
self.aasm_state = params[:aasm_state]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ module JamRuby
|
|||
|
||||
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings, :foreign_key => 'owner_id'
|
||||
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
|
||||
belongs_to :music_session, :class_name => "JamRuby::MusicSession", :inverse_of => :recordings
|
||||
belongs_to :music_session, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :recordings, foreign_key: :music_session_id
|
||||
|
||||
accepts_nested_attributes_for :recorded_tracks, :mixes, :claimed_recordings, allow_destroy: true
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ module JamRuby
|
|||
F_SORT_OPTS = [F_SORT_RECENT, F_SORT_LENGTH, F_SORT_OLDEST]
|
||||
|
||||
SHOW_BOTH = ['Sessions & Recordings', :all]
|
||||
SHOW_SESSIONS = ['Sessions', :music_session_history]
|
||||
SHOW_SESSIONS = ['Sessions', :music_session]
|
||||
SHOW_RECORDINGS = ['Recordings', :recording]
|
||||
SHOW_OPTS = [SHOW_BOTH, SHOW_SESSIONS, SHOW_RECORDINGS]
|
||||
|
||||
|
|
@ -300,8 +300,8 @@ module JamRuby
|
|||
sel_str = 'bands.*'
|
||||
case ordering = self.order_param(params)
|
||||
when :plays # FIXME: double counting?
|
||||
sel_str = "COUNT(records)+COUNT(sessions) AS play_count, #{sel_str}"
|
||||
rel = rel.joins("LEFT JOIN music_sessions AS sessions ON sessions.band_id = bands.id")
|
||||
sel_str = "COUNT(records)+COUNT(msh) AS play_count, #{sel_str}"
|
||||
rel = rel.joins("LEFT JOIN music_sessions AS msh ON msh.band_id = bands.id")
|
||||
.joins("LEFT JOIN recordings AS records ON records.band_id = bands.id")
|
||||
.group("bands.id")
|
||||
.order("play_count DESC, bands.created_at DESC")
|
||||
|
|
@ -311,7 +311,7 @@ module JamRuby
|
|||
.group("bands.id")
|
||||
.order("COUNT(follows) DESC, bands.created_at DESC")
|
||||
when :playing
|
||||
rel = rel.joins("LEFT JOIN music_sessions_history AS msh ON msh.band_id = bands.id")
|
||||
rel = rel.joins("LEFT JOIN music_sessions AS msh ON msh.band_id = bands.id")
|
||||
.where('msh.music_session_id IS NOT NULL AND msh.session_removed_at IS NULL')
|
||||
.order("bands.created_at DESC")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ module JamRuby
|
|||
track.client_track_id = client_track_id
|
||||
end
|
||||
|
||||
track.updated_at = Time.now.getutc
|
||||
track.updated_at = Time.now
|
||||
track.save
|
||||
return track
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module JamRuby
|
|||
attr_accessible :first_name, :last_name, :email, :city, :password, :password_confirmation, :state, :country, :birth_date, :subscribe_email, :terms_of_service, :original_fpfile, :cropped_fpfile, :cropped_large_fpfile, :cropped_s3_path, :cropped_large_s3_path, :photo_url, :large_photo_url, :crop_selection, :lat, :lng
|
||||
|
||||
# updating_password corresponds to a lost_password
|
||||
attr_accessor :updating_password, :updating_email, :updated_email, :update_email_confirmation_url, :administratively_created, :current_password, :setting_password, :confirm_current_password, :updating_avatar, :updating_progression_field
|
||||
attr_accessor :updating_password, :updating_email, :updated_email, :update_email_confirmation_url, :administratively_created, :current_password, :setting_password, :confirm_current_password, :updating_avatar, :updating_progression_field, :mods_json
|
||||
|
||||
belongs_to :icecast_server_group, class_name: "JamRuby::IcecastServerGroup", inverse_of: :users, foreign_key: 'icecast_server_group_id'
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ module JamRuby
|
|||
has_many :owned_recordings, :class_name => "JamRuby::Recording", :foreign_key => "owner_id"
|
||||
has_many :recordings, :through => :claimed_recordings, :class_name => "JamRuby::Recording"
|
||||
has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :user
|
||||
has_many :playing_claimed_recordings, :class_name => "JamRuby::MusicSession", :inverse_of => :claimed_recording_initiator
|
||||
has_many :playing_claimed_recordings, :class_name => "JamRuby::ActiveMusicSession", :inverse_of => :claimed_recording_initiator
|
||||
|
||||
# self.id = user_id in likes table
|
||||
has_many :likings, :class_name => "JamRuby::Like", :inverse_of => :user, :dependent => :destroy
|
||||
|
|
@ -71,8 +71,8 @@ module JamRuby
|
|||
has_many :inverse_friends, :through => :inverse_friendships, :source => :user, :class_name => "JamRuby::User"
|
||||
|
||||
# connections / music sessions
|
||||
has_many :created_music_sessions, :foreign_key => "user_id", :inverse_of => :user, :class_name => "JamRuby::MusicSession" # sessions *created* by the user
|
||||
has_many :music_sessions, :through => :connections, :class_name => "JamRuby::MusicSession"
|
||||
has_many :created_music_sessions, :foreign_key => "user_id", :inverse_of => :user, :class_name => "JamRuby::ActiveMusicSession" # sessions *created* by the user
|
||||
has_many :music_sessions, :through => :connections, :class_name => "JamRuby::ActiveMusicSession"
|
||||
|
||||
# invitations
|
||||
has_many :received_invitations, :foreign_key => "receiver_id", :inverse_of => :receiver, :class_name => "JamRuby::Invitation"
|
||||
|
|
@ -87,7 +87,7 @@ module JamRuby
|
|||
has_many :sent_band_invitations, :inverse_of => :sender, :foreign_key => "creator_id", :class_name => "JamRuby::BandInvitation"
|
||||
|
||||
# session history
|
||||
has_many :music_session_histories, :foreign_key => "user_id", :class_name => "JamRuby::MusicSessionHistory", :inverse_of => :user
|
||||
has_many :music_session_histories, :foreign_key => "user_id", :class_name => "JamRuby::MusicSession", :inverse_of => :user
|
||||
has_many :music_session_user_histories, :foreign_key => "user_id", :class_name => "JamRuby::MusicSessionUserHistory", :inverse_of => :user
|
||||
|
||||
# saved tracks
|
||||
|
|
@ -105,6 +105,8 @@ module JamRuby
|
|||
# affiliate_partner
|
||||
has_one :affiliate_partner, :class_name => "JamRuby::AffiliatePartner", :foreign_key => :partner_user_id
|
||||
belongs_to :affiliate_referral, :class_name => "JamRuby::AffiliatePartner", :foreign_key => :affiliate_referral_id, :counter_cache => :referral_user_count
|
||||
# diagnostics
|
||||
has_many :diagnostics, :class_name => "JamRuby::Diagnostic"
|
||||
|
||||
# This causes the authenticate method to be generated (among other stuff)
|
||||
#has_secure_password
|
||||
|
|
@ -126,6 +128,7 @@ module JamRuby
|
|||
validates :subscribe_email, :inclusion => {:in => [nil, true, false]}
|
||||
validates :musician, :inclusion => {:in => [true, false]}
|
||||
validates :show_whats_next, :inclusion => {:in => [nil, true, false]}
|
||||
validates :mods, json: true
|
||||
|
||||
# custom validators
|
||||
validate :validate_musician_instruments
|
||||
|
|
@ -287,12 +290,25 @@ module JamRuby
|
|||
self.music_sessions.size
|
||||
end
|
||||
|
||||
# mods comes back as text; so give ourselves a parsed version
|
||||
def mods_json
|
||||
@mods_json ||= mods ? JSON.parse(mods, symbolize_names: true) : {}
|
||||
end
|
||||
|
||||
def heartbeat_interval_client
|
||||
mods_json[:heartbeat_interval_client]
|
||||
end
|
||||
|
||||
def connection_expire_time_client
|
||||
mods_json[:connection_expire_time_client]
|
||||
end
|
||||
|
||||
def recent_history
|
||||
recordings = Recording.where(:owner_id => self.id)
|
||||
.order('created_at DESC')
|
||||
.limit(10)
|
||||
|
||||
msh = MusicSessionHistory.where(:user_id => self.id)
|
||||
msh = MusicSession.where(:user_id => self.id)
|
||||
.order('created_at DESC')
|
||||
.limit(10)
|
||||
|
||||
|
|
@ -339,7 +355,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
def session_history(user_id, band_id = nil, genre = nil)
|
||||
return MusicSessionHistory.index(self, user_id, band_id, genre)
|
||||
return MusicSession.index(self, user_id, band_id, genre)
|
||||
end
|
||||
|
||||
def session_user_history(user_id, session_id)
|
||||
|
|
@ -363,7 +379,7 @@ module JamRuby
|
|||
return first_name + ' ' + last_name
|
||||
end
|
||||
|
||||
return id
|
||||
id
|
||||
end
|
||||
|
||||
def set_password(old_password, new_password, new_password_confirmation)
|
||||
|
|
@ -551,7 +567,7 @@ module JamRuby
|
|||
self.biography = biography
|
||||
end
|
||||
|
||||
self.updated_at = Time.now.getutc
|
||||
self.updated_at = Time.now
|
||||
self.save
|
||||
end
|
||||
|
||||
|
|
@ -640,7 +656,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
# def create_session_like(targetSessionId)
|
||||
# targetSession = MusicSessionHistory.find(targetSessionId)
|
||||
# targetSession = MusicSession.find(targetSessionId)
|
||||
|
||||
# like = Like.new
|
||||
# like.likable = targetSession
|
||||
|
|
@ -688,15 +704,7 @@ module JamRuby
|
|||
unless user.nil?
|
||||
|
||||
# only save genre id and description
|
||||
genres = []
|
||||
unless music_session.genres.nil?
|
||||
music_session.genres.each do |genre|
|
||||
g = Hash.new
|
||||
g["id"] = genre.id
|
||||
g["description"] = genre.description
|
||||
genres << g
|
||||
end
|
||||
end
|
||||
genres = [{id: music_session.genre.id, description: music_session.genre.description}]
|
||||
|
||||
# only save invitation receiver id and name
|
||||
invitees = []
|
||||
|
|
@ -709,7 +717,7 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
session_settings = { :band_id => music_session.band_id,
|
||||
session_settings = { :band_id => music_session.band_id,
|
||||
:musician_access => music_session.musician_access,
|
||||
:approval_required => music_session.approval_required,
|
||||
:fan_chat => music_session.fan_chat,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ module JamRuby
|
|||
|
||||
def self.perform(args={})
|
||||
session_id, interval_idx = args['session_id'], args['interval_idx'].to_i
|
||||
return unless session_id && session = MusicSession.find(session_id)
|
||||
return unless session_id && session = MusicSession.find_by_id(session_id)
|
||||
GoogleAnalyticsEvent.enqueue(CAT_SESS_DUR, ACTION_SESS_DUR, SESSION_INTERVALS[interval_idx])
|
||||
interval_idx += 1
|
||||
|
||||
|
|
@ -47,7 +47,7 @@ module JamRuby
|
|||
@queue = QUEUE_BAND_TRACKER
|
||||
|
||||
def self.perform(session_id)
|
||||
return unless session = MusicSession.find(session_id)
|
||||
return unless session = ActiveMusicSession.find(session_id)
|
||||
band = session.band
|
||||
if band.in_real_session?(session)
|
||||
band.update_attribute(:did_real_session, true)
|
||||
|
|
|
|||
|
|
@ -31,46 +31,66 @@ FactoryGirl.define do
|
|||
|
||||
factory :single_user_session do
|
||||
after(:create) do |user, evaluator|
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user)
|
||||
connection = FactoryGirl.create(:connection, :user => user, :music_session => music_session)
|
||||
active_music_session = FactoryGirl.create(:active_music_session, :creator => user)
|
||||
connection = FactoryGirl.create(:connection, :user => user, :music_session => active_music_session)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :music_session_no_history, :class => JamRuby::MusicSession do
|
||||
sequence(:description) { |n| "Music Session #{n}" }
|
||||
factory :musician_instrument, :class => JamRuby::MusicianInstrument do
|
||||
instrument { JamRuby::Instrument.find('electric guitar') }
|
||||
proficiency_level 1
|
||||
priority 0
|
||||
end
|
||||
|
||||
|
||||
factory :active_music_session_no_user_history, :class => JamRuby::ActiveMusicSession do
|
||||
|
||||
association :creator, factory: :user
|
||||
|
||||
ignore do
|
||||
name "My Music Session"
|
||||
description "Come Music Session"
|
||||
fan_chat true
|
||||
fan_access true
|
||||
approval_required false
|
||||
musician_access true
|
||||
legal_terms true
|
||||
genre JamRuby::Genre.first
|
||||
band nil
|
||||
end
|
||||
|
||||
|
||||
before(:create) do |session, evaluator|
|
||||
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,
|
||||
genre: evaluator.genre, creator: evaluator.creator, band: evaluator.band)
|
||||
session.id = music_session.id
|
||||
end
|
||||
|
||||
factory :active_music_session do
|
||||
after(:create) { |session|
|
||||
FactoryGirl.create(:music_session_user_history, :history => session.music_session, :user => session.creator)
|
||||
}
|
||||
|
||||
factory :active_music_session_with_mount do
|
||||
association :mount, :factory => :icecast_mount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
factory :music_session, :class => JamRuby::MusicSession do
|
||||
sequence(:name) { |n| "Music Session #{n}" }
|
||||
sequence(:description) { |n| "Music Session Description #{n}" }
|
||||
fan_chat true
|
||||
fan_access true
|
||||
approval_required false
|
||||
musician_access true
|
||||
legal_terms true
|
||||
genres [JamRuby::Genre.first]
|
||||
language 'english'
|
||||
legal_policy 'standard'
|
||||
genre JamRuby::Genre.first
|
||||
association :creator, :factory => :user
|
||||
|
||||
factory :music_session do
|
||||
|
||||
after(:create) { |session|
|
||||
FactoryGirl.create(:music_session_user_history, :history => session.music_session_history, :user => session.creator)
|
||||
}
|
||||
|
||||
factory :music_session_with_mount do
|
||||
association :mount, :factory => :icecast_mount
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
factory :music_session_history, :class => JamRuby::MusicSessionHistory do
|
||||
ignore do
|
||||
music_session nil
|
||||
end
|
||||
|
||||
fan_access true
|
||||
music_session_id { music_session.id }
|
||||
description { music_session.description }
|
||||
user_id { music_session.user_id }
|
||||
band_id { music_session.band_id }
|
||||
end
|
||||
|
||||
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
|
||||
|
|
@ -80,7 +100,7 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
instruments 'guitar'
|
||||
music_session_id { history.music_session_id }
|
||||
music_session_id { history.id }
|
||||
user_id { user.id }
|
||||
sequence(:client_id) { |n| "Connection #{n}" }
|
||||
end
|
||||
|
|
@ -154,7 +174,7 @@ FactoryGirl.define do
|
|||
factory :recording, :class => JamRuby::Recording do
|
||||
|
||||
association :owner, factory: :user
|
||||
association :music_session, factory: :music_session
|
||||
association :music_session, factory: :active_music_session
|
||||
association :band, factory: :band
|
||||
|
||||
factory :recording_with_track do
|
||||
|
|
@ -196,12 +216,6 @@ FactoryGirl.define do
|
|||
}
|
||||
end
|
||||
|
||||
factory :musician_instrument, :class => JamRuby::MusicianInstrument do
|
||||
instrument { Instrument.find('electric guitar') }
|
||||
proficiency_level 1
|
||||
priority 0
|
||||
end
|
||||
|
||||
factory :invited_user, :class => JamRuby::InvitedUser do
|
||||
sequence(:email) { |n| "user#{n}@someservice.com" }
|
||||
autofriend false
|
||||
|
|
@ -305,7 +319,7 @@ FactoryGirl.define do
|
|||
association :mount_template, :factory => :icecast_mount_template
|
||||
|
||||
factory :iceast_mount_with_music_session do
|
||||
association :music_session, :factory => :music_session
|
||||
association :music_session, :factory => :active_music_session
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -438,4 +452,10 @@ FactoryGirl.define do
|
|||
message Faker::Lorem.characters(10)
|
||||
end
|
||||
end
|
||||
|
||||
factory :diagnostic, :class => JamRuby::Diagnostic do
|
||||
type JamRuby::Diagnostic::NO_HEARTBEAT_ACK
|
||||
creator JamRuby::Diagnostic::CLIENT
|
||||
data Faker::Lorem.sentence
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ require 'spec_helper'
|
|||
describe ConnectionManager do
|
||||
|
||||
TRACKS = [{"instrument_id" => "electric guitar", "sound" => "mono", "client_track_id" => "some_client_track_id"}]
|
||||
STALE_TIME = 40
|
||||
EXPIRE_TIME = 60
|
||||
STALE_BUT_NOT_EXPIRED = 50
|
||||
DEFINITELY_EXPIRED = 70
|
||||
|
||||
before do
|
||||
@conn = PG::Connection.new(:dbname => SpecDb::TEST_DB_NAME, :user => "postgres", :password => "postgres", :host => "localhost")
|
||||
|
|
@ -17,17 +21,6 @@ describe ConnectionManager do
|
|||
end
|
||||
end
|
||||
|
||||
def create_music_session(user_id, options={})
|
||||
default_options = {:musician_access => true, :fan_chat => true, :fan_access => true, :approval_required=> false}
|
||||
options = default_options.merge(options)
|
||||
description = "some session"
|
||||
@conn.exec("INSERT INTO music_sessions (user_id, description, musician_access, approval_required, fan_chat, fan_access) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id", [user_id, description, options[:musician_access], options[:approval_required], options[:fan_chat], options[:fan_access]]) do |result|
|
||||
session_id = result.getvalue(0, 0)
|
||||
@conn.exec("INSERT INTO music_sessions_history (music_session_id, description, user_id, fan_access) VALUES ($1, $2, $3, $4)", [session_id, description, user_id, true])
|
||||
return session_id
|
||||
end
|
||||
end
|
||||
|
||||
def assert_num_connections(client_id, expected_num_connections)
|
||||
# make sure the connection is still there
|
||||
@conn.exec("SELECT count(*) FROM connections where client_id = $1", [client_id]) do |result|
|
||||
|
|
@ -36,7 +29,7 @@ describe ConnectionManager do
|
|||
end
|
||||
|
||||
def assert_session_exists(music_session_id, exists)
|
||||
@conn.exec("SELECT count(*) FROM music_sessions where id = $1", [music_session_id]) do |result|
|
||||
@conn.exec("SELECT count(*) FROM active_music_sessions where id = $1", [music_session_id]) do |result|
|
||||
if exists
|
||||
result.getvalue(0, 0).should == "1"
|
||||
else
|
||||
|
|
@ -53,8 +46,8 @@ describe ConnectionManager do
|
|||
user.save!
|
||||
user = nil
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
expect { @connman.create_connection(user_id, client_id, "1.1.1.1", 'client') }.to raise_error(PG::Error)
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
expect { @connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME) }.to raise_error(PG::Error)
|
||||
end
|
||||
|
||||
it "create connection then delete it" do
|
||||
|
|
@ -63,7 +56,7 @@ describe ConnectionManager do
|
|||
#user_id = create_user("test", "user2", "user2@jamkazam.com")
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
count = @connman.create_connection(user.id, client_id, "1.1.1.1", 'client')
|
||||
count = @connman.create_connection(user.id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
count.should == 1
|
||||
|
||||
|
|
@ -93,7 +86,7 @@ describe ConnectionManager do
|
|||
#user_id = create_user("test", "user2", "user2@jamkazam.com")
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
count = @connman.create_connection(user.id, client_id, "1.1.1.1", 'client')
|
||||
count = @connman.create_connection(user.id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
count.should == 1
|
||||
|
||||
|
|
@ -109,7 +102,7 @@ describe ConnectionManager do
|
|||
cc.addr.should == 0x01010101
|
||||
cc.locidispid.should == 17192000002
|
||||
|
||||
@connman.reconnect(cc, nil, "33.1.2.3")
|
||||
@connman.reconnect(cc, nil, "33.1.2.3", STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
cc = Connection.find_by_client_id!(client_id)
|
||||
cc.connected?.should be_true
|
||||
|
|
@ -222,20 +215,21 @@ describe ConnectionManager do
|
|||
it "flag stale connection" do
|
||||
client_id = "client_id8"
|
||||
user_id = create_user("test", "user8", "user8@jamkazam.com")
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
num = JamRuby::Connection.count(:conditions => ['aasm_state = ?','connected'])
|
||||
num.should == 1
|
||||
assert_num_connections(client_id, num)
|
||||
@connman.flag_stale_connections(60)
|
||||
@connman.flag_stale_connections()
|
||||
assert_num_connections(client_id, num)
|
||||
|
||||
sleep(1)
|
||||
conn = Connection.find_by_client_id(client_id)
|
||||
set_updated_at(conn, Time.now - STALE_BUT_NOT_EXPIRED)
|
||||
|
||||
num = JamRuby::Connection.count(:conditions => ["updated_at < (NOW() - interval '#{1} second') AND aasm_state = 'connected'"])
|
||||
num.should == 1
|
||||
# this should change the aasm_state to stale
|
||||
@connman.flag_stale_connections(1)
|
||||
@connman.flag_stale_connections()
|
||||
|
||||
num = JamRuby::Connection.count(:conditions => ["updated_at < (NOW() - interval '#{1} second') AND aasm_state = 'connected'"])
|
||||
num.should == 0
|
||||
|
|
@ -244,31 +238,39 @@ describe ConnectionManager do
|
|||
num.should == 1
|
||||
assert_num_connections(client_id, 1)
|
||||
|
||||
cids = @connman.stale_connection_client_ids(1)
|
||||
cids.size.should == 1
|
||||
cids[0].should == client_id
|
||||
cids.each { |cid| @connman.delete_connection(cid) }
|
||||
conn = Connection.find_by_client_id(client_id)
|
||||
set_updated_at(conn, Time.now - DEFINITELY_EXPIRED)
|
||||
|
||||
cids = @connman.stale_connection_client_ids()
|
||||
cids.size.should == 1
|
||||
cids[0][:client_id].should == client_id
|
||||
cids[0][:client_type].should == Connection::TYPE_CLIENT
|
||||
cids[0][:music_session_id].should be_nil
|
||||
cids[0][:user_id].should == user_id
|
||||
|
||||
cids.each { |cid| @connman.delete_connection(cid[:client_id]) }
|
||||
|
||||
sleep(1)
|
||||
assert_num_connections(client_id, 0)
|
||||
end
|
||||
|
||||
it "expires stale connection" do
|
||||
client_id = "client_id8"
|
||||
user_id = create_user("test", "user8", "user8@jamkazam.com")
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
sleep(1)
|
||||
@connman.flag_stale_connections(1)
|
||||
conn = Connection.find_by_client_id(client_id)
|
||||
set_updated_at(conn, Time.now - STALE_BUT_NOT_EXPIRED)
|
||||
|
||||
@connman.flag_stale_connections
|
||||
assert_num_connections(client_id, 1)
|
||||
# assert_num_connections(client_id, JamRuby::Connection.count(:conditions => ['aasm_state = ?','stale']))
|
||||
|
||||
@connman.expire_stale_connections(60)
|
||||
@connman.expire_stale_connections
|
||||
assert_num_connections(client_id, 1)
|
||||
|
||||
sleep(1)
|
||||
set_updated_at(conn, Time.now - DEFINITELY_EXPIRED)
|
||||
# this should delete the stale connection
|
||||
@connman.expire_stale_connections(1)
|
||||
@connman.expire_stale_connections
|
||||
assert_num_connections(client_id, 0)
|
||||
end
|
||||
|
||||
|
|
@ -276,12 +278,11 @@ describe ConnectionManager do
|
|||
|
||||
client_id = "client_id9"
|
||||
user_id = create_user("test", "user9", "user9@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS)
|
||||
|
||||
connection.errors.any?.should be_false
|
||||
|
|
@ -302,10 +303,10 @@ describe ConnectionManager do
|
|||
|
||||
client_id = "client_id10"
|
||||
user_id = create_user("test", "user10", "user10@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id)
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
|
||||
|
|
@ -317,13 +318,12 @@ describe ConnectionManager do
|
|||
client_id2 = "client_id10.12"
|
||||
user_id = create_user("test", "user10.11", "user10.11@jamkazam.com", :musician => true)
|
||||
user_id2 = create_user("test", "user10.12", "user10.12@jamkazam.com", :musician => false)
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id2, client_id2, "1.1.1.1", 'client')
|
||||
|
||||
music_session_id = create_music_session(user_id)
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
@connman.create_connection(user_id2, client_id2, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.join_music_session(user, client_id, music_session, true, TRACKS)
|
||||
|
||||
|
|
@ -336,13 +336,12 @@ describe ConnectionManager do
|
|||
|
||||
it "as_musician is coerced to boolean" do
|
||||
client_id = "client_id10.2"
|
||||
user_id = create_user("test", "user10.2", "user10.2@jamkazam.com", :musician => false)
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
|
||||
music_session_id = create_music_session(user_id)
|
||||
user_id = create_user("test", "user10.2", "user10.2@jamkazam.com")
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
connection = @connman.join_music_session(user, client_id, music_session, 'blarg', TRACKS)
|
||||
connection.errors.size.should == 0
|
||||
|
|
@ -355,13 +354,13 @@ describe ConnectionManager do
|
|||
fan_client_id = "client_id10.4"
|
||||
musician_id = create_user("test", "user10.3", "user10.3@jamkazam.com")
|
||||
fan_id = create_user("test", "user10.4", "user10.4@jamkazam.com", :musician => false)
|
||||
@connman.create_connection(musician_id, musician_client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(fan_id, fan_client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(musician_id, musician_client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
@connman.create_connection(fan_id, fan_client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
music_session_id = create_music_session(musician_id, :fan_access => false)
|
||||
music_session = FactoryGirl.create(:active_music_session, :fan_access => false, user_id: musician_id)
|
||||
music_session_id = music_session.id
|
||||
|
||||
user = User.find(musician_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.join_music_session(user, musician_client_id, music_session, true, TRACKS)
|
||||
|
||||
|
|
@ -376,12 +375,11 @@ describe ConnectionManager do
|
|||
client_id = "client_id20"
|
||||
user_id = create_user("test", "user20", "user20@jamkazam.com")
|
||||
user_id2 = create_user("test", "user21", "user21@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id2)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
# specify real user id, but not associated with this session
|
||||
expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS) } .to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
|
@ -391,9 +389,9 @@ describe ConnectionManager do
|
|||
user_id = create_user("test", "user11", "user11@jamkazam.com")
|
||||
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.new
|
||||
music_session = ActiveMusicSession.new
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
connection = @connman.join_music_session(user, client_id, music_session, true, TRACKS)
|
||||
connection.errors.size.should == 1
|
||||
connection.errors.get(:music_session).should == [ValidationMessages::MUSIC_SESSION_MUST_BE_SPECIFIED]
|
||||
|
|
@ -403,12 +401,11 @@ describe ConnectionManager do
|
|||
client_id = "client_id11.1"
|
||||
user_id = create_user("test", "user11.1", "user11.1@jamkazam.com")
|
||||
user_id2 = create_user("test", "user11.2", "user11.2@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id, :approval_required => true)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, :approval_required => true, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id2)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
# specify real user id, but not associated with this session
|
||||
expect { @connman.join_music_session(user, client_id, music_session, true, TRACKS) } .to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
|
@ -420,9 +417,9 @@ describe ConnectionManager do
|
|||
user_id = create_user("test", "user12", "user12@jamkazam.com")
|
||||
|
||||
user = User.find(user_id)
|
||||
dummy_music_session = MusicSession.new
|
||||
dummy_music_session = ActiveMusicSession.new
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
|
||||
expect { @connman.leave_music_session(user, Connection.find_by_client_id(client_id), dummy_music_session) }.to raise_error(JamRuby::StateError)
|
||||
end
|
||||
|
|
@ -431,14 +428,13 @@ describe ConnectionManager do
|
|||
|
||||
client_id = "client_id13"
|
||||
user_id = create_user("test", "user13", "user13@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
dummy_music_session = MusicSession.new
|
||||
dummy_music_session = ActiveMusicSession.new
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
@connman.join_music_session(user, client_id, music_session, true, TRACKS)
|
||||
expect { @connman.leave_music_session(user, Connection.find_by_client_id(client_id), dummy_music_session) }.to raise_error(JamRuby::StateError)
|
||||
end
|
||||
|
|
@ -447,12 +443,11 @@ describe ConnectionManager do
|
|||
|
||||
client_id = "client_id14"
|
||||
user_id = create_user("test", "user14", "user14@jamkazam.com")
|
||||
music_session_id = create_music_session(user_id)
|
||||
|
||||
music_session = FactoryGirl.create(:active_music_session, user_id: user_id)
|
||||
music_session_id = music_session.id
|
||||
user = User.find(user_id)
|
||||
music_session = MusicSession.find(music_session_id)
|
||||
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client')
|
||||
@connman.create_connection(user_id, client_id, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
@connman.join_music_session(user, client_id, music_session, true, TRACKS)
|
||||
|
||||
assert_session_exists(music_session_id, true)
|
||||
|
|
@ -490,19 +485,17 @@ describe ConnectionManager do
|
|||
# and a connection can only point to one active music_session at a time. this is a test of
|
||||
# the latter but we need a test of the former, too.
|
||||
|
||||
|
||||
user_id = create_user("test", "user11", "user11@jamkazam.com")
|
||||
|
||||
user = User.find(user_id)
|
||||
|
||||
client_id1 = Faker::Number.number(20)
|
||||
@connman.create_connection(user_id, client_id1, "1.1.1.1", 'client')
|
||||
music_session1 = MusicSession.find(create_music_session(user_id))
|
||||
@connman.create_connection(user_id, client_id1, "1.1.1.1", 'client', STALE_TIME, EXPIRE_TIME)
|
||||
music_session1 = FactoryGirl.create(:active_music_session, :user_id => user_id)
|
||||
connection1 = @connman.join_music_session(user, client_id1, music_session1, true, TRACKS)
|
||||
|
||||
connection1.errors.size.should == 0
|
||||
|
||||
music_session2 = MusicSession.find(create_music_session(user_id))
|
||||
music_session2 = FactoryGirl.create(:active_music_session, :user_id => user_id)
|
||||
connection2 = @connman.join_music_session(user, client_id1, music_session2, true, TRACKS)
|
||||
|
||||
connection2.errors.size.should == 1
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ describe 'Band search' do
|
|||
|
||||
def make_session(band)
|
||||
usr = band.users[0]
|
||||
session = FactoryGirl.create(:music_session, :creator => usr, :description => "Session", :band => band)
|
||||
session = FactoryGirl.create(:active_music_session, :creator => usr, :description => "Session", :band => band)
|
||||
FactoryGirl.create(:connection, :user => usr, :music_session => session)
|
||||
user = FactoryGirl.create(:user)
|
||||
session
|
||||
|
|
@ -159,7 +159,7 @@ describe 'Band search' do
|
|||
it "by now playing" do
|
||||
# should get 1 result with 1 active session
|
||||
session = make_session(@band3)
|
||||
#FactoryGirl.create(:music_session_history, :music_session => session)
|
||||
#FactoryGirl.create(:active_music_session, :music_session => session)
|
||||
|
||||
results = Search.band_filter({ :orderby => 'playing' })
|
||||
expect(results.results.count).to be 1
|
||||
|
|
@ -168,7 +168,7 @@ describe 'Band search' do
|
|||
# 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)
|
||||
#FactoryGirl.create(:active_music_session, :music_session => session)
|
||||
results = Search.band_filter({ :orderby => 'playing' })
|
||||
expect(results.results.count).to be 2
|
||||
expect(results.results[0].id).to eq(@band4.id)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ describe ClaimedRecording do
|
|||
@connection = FactoryGirl.create(:connection, :user => @user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
|
||||
# @music_session.connections << @connection
|
||||
@music_session.save
|
||||
@connection.join_the_session(@music_session, true, nil)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
describe JamRuby::Connection do
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let (:music_session) { FactoryGirl.create(:music_session, :creator => user) }
|
||||
let (:music_session) { FactoryGirl.create(:active_music_session, :creator => user) }
|
||||
|
||||
it 'starts in the correct state' do
|
||||
connection = FactoryGirl.create(:connection,
|
||||
|
|
@ -37,7 +37,7 @@ describe JamRuby::Connection do
|
|||
pending 'distance search changes'
|
||||
uu = FactoryGirl.create(:user)
|
||||
uu.lat.should == nil
|
||||
msess = FactoryGirl.create(:music_session, :creator => uu)
|
||||
msess = FactoryGirl.create(:active_music_session, :creator => uu)
|
||||
geocode = FactoryGirl.create(:geocoder)
|
||||
connection = FactoryGirl.create(:connection,
|
||||
:user => uu,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Diagnostic do
|
||||
let (:user) { FactoryGirl.create(:user) }
|
||||
let (:diagnostic) { FactoryGirl.create(:diagnostic, user: user) }
|
||||
|
||||
it 'can be made' do
|
||||
diagnostic.save!
|
||||
end
|
||||
|
||||
it "validates type" do
|
||||
diagnostic = FactoryGirl.build(:diagnostic, user: user, type: 'bleh')
|
||||
|
||||
diagnostic.errors[:type].should == []
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -16,7 +16,7 @@ describe Feed do
|
|||
it "one claimed recording" do
|
||||
claimed_recording = FactoryGirl.create(:claimed_recording)
|
||||
MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
MusicSessionHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
MusicSession.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
feeds, start = Feed.index(user1)
|
||||
feeds.length.should == 1
|
||||
feeds[0].recording == claimed_recording.recording
|
||||
|
|
@ -28,7 +28,7 @@ describe Feed do
|
|||
recording.recorded_tracks << second_track
|
||||
FactoryGirl.create(:claimed_recording, recording: recording, user: second_track.user)
|
||||
MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
MusicSessionHistory.delete_all
|
||||
MusicSession.delete_all
|
||||
|
||||
# verify the mess above only made one recording
|
||||
Recording.count.should == 1
|
||||
|
|
@ -38,16 +38,16 @@ describe Feed do
|
|||
end
|
||||
|
||||
it "one music session" do
|
||||
music_session = FactoryGirl.create(:music_session)
|
||||
music_session = FactoryGirl.create(:active_music_session)
|
||||
feeds, start = Feed.index(user1)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history == music_session.music_session_history
|
||||
feeds[0].music_session == music_session.music_session
|
||||
end
|
||||
|
||||
it "does not return a recording with no claimed recordings" do
|
||||
recording = FactoryGirl.create(:recording)
|
||||
MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
MusicSessionHistory.delete_all
|
||||
MusicSession.delete_all
|
||||
|
||||
feeds, start = Feed.index(user1)
|
||||
feeds.length.should == 0
|
||||
|
|
@ -60,7 +60,7 @@ describe Feed do
|
|||
feeds, start = Feed.index(user1)
|
||||
feeds.length.should == 2
|
||||
feeds[0].recording.should == claimed_recording.recording
|
||||
feeds[1].music_session_history.should == claimed_recording.recording.music_session.music_session_history
|
||||
feeds[1].music_session.should == claimed_recording.recording.music_session.music_session
|
||||
end
|
||||
|
||||
it "sort by plays DESC" do
|
||||
|
|
@ -80,14 +80,14 @@ describe Feed do
|
|||
feeds[0].recording.should == claimed_recording2.recording
|
||||
feeds[1].recording.should == claimed_recording1.recording
|
||||
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session_history, user: user1)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session_history, user: user2)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session_history, user: user3)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session, user: user1)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session, user: user2)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session, user: user3)
|
||||
|
||||
|
||||
feeds, start = Feed.index(user1, :sort => 'plays')
|
||||
feeds.length.should == 4
|
||||
feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
|
||||
feeds[1].recording.should == claimed_recording2.recording
|
||||
feeds[2].recording.should == claimed_recording1.recording
|
||||
end
|
||||
|
|
@ -109,13 +109,13 @@ describe Feed do
|
|||
feeds[0].recording.should == claimed_recording2.recording
|
||||
feeds[1].recording.should == claimed_recording1.recording
|
||||
|
||||
FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user1)
|
||||
FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user2)
|
||||
FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user3)
|
||||
FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user1)
|
||||
FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user2)
|
||||
FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user3)
|
||||
|
||||
feeds, start = Feed.index(user1, :sort => 'likes')
|
||||
feeds.length.should == 4
|
||||
feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
|
||||
feeds[1].recording.should == claimed_recording2.recording
|
||||
feeds[2].recording.should == claimed_recording1.recording
|
||||
end
|
||||
|
|
@ -126,18 +126,18 @@ describe Feed do
|
|||
# creates both recording and history record in feed
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
|
||||
feeds, start = Feed.index(user1, :type => 'music_session_history')
|
||||
feeds, start = Feed.index(user1, :type => 'music_session')
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session == claimed_recording1.recording.music_session.music_session
|
||||
end
|
||||
|
||||
it "returns only sessions" do
|
||||
# creates both recording and history record in feed
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
|
||||
feeds, start = Feed.index(user1, :type => 'music_session_history')
|
||||
feeds, start = Feed.index(user1, :type => 'music_session')
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session == claimed_recording1.recording.music_session.music_session
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -203,7 +203,7 @@ describe Feed do
|
|||
options[:start] = start
|
||||
feeds, start = Feed.index(user1, options)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == claimed_recording.recording.music_session.music_session_history
|
||||
feeds[0].music_session.should == claimed_recording.recording.music_session.music_session
|
||||
|
||||
options[:start] = start
|
||||
feeds, start = Feed.index(user1, options)
|
||||
|
|
@ -214,12 +214,12 @@ describe Feed do
|
|||
it "supports likes pagination" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
|
||||
FactoryGirl.create(:music_session_like, music_session_history: claimed_recording1.recording.music_session.music_session_history, user: user1)
|
||||
FactoryGirl.create(:music_session_like, music_session: claimed_recording1.recording.music_session.music_session, user: user1)
|
||||
|
||||
options = {limit: 1, sort: 'likes'}
|
||||
feeds, start = Feed.index(user1, options)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
|
||||
|
||||
options[:start] = start
|
||||
feeds, start = Feed.index(user1, options)
|
||||
|
|
@ -235,12 +235,12 @@ describe Feed do
|
|||
it "supports plays pagination" do
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session_history, user: user1)
|
||||
FactoryGirl.create(:playable_play, playable: claimed_recording1.recording.music_session.music_session, user: user1)
|
||||
|
||||
options = {limit: 1, sort: 'plays'}
|
||||
feeds, start = Feed.index(user1, options)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == claimed_recording1.recording.music_session.music_session_history
|
||||
feeds[0].music_session.should == claimed_recording1.recording.music_session.music_session
|
||||
|
||||
options[:start] = start
|
||||
feeds, start = Feed.index(user1, options)
|
||||
|
|
@ -263,8 +263,8 @@ describe Feed do
|
|||
feeds, start = Feed.index(claimed_recording1.user)
|
||||
feeds.length.should == 1
|
||||
|
||||
claimed_recording1.recording.music_session.fan_access = false
|
||||
claimed_recording1.recording.music_session.save!
|
||||
claimed_recording1.recording.music_session.music_session.fan_access = false
|
||||
claimed_recording1.recording.music_session.music_session.save!
|
||||
|
||||
feeds, start = Feed.index(claimed_recording1.user)
|
||||
feeds.length.should == 0
|
||||
|
|
@ -274,8 +274,8 @@ describe Feed do
|
|||
describe "band feeds" do
|
||||
it "does show other band's stuff in this feed" do
|
||||
other_band = FactoryGirl.create(:band)
|
||||
music_session = FactoryGirl.create(:music_session, band: other_band)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, band: other_band)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)
|
||||
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
claimed_recording1.is_public = true
|
||||
|
|
@ -290,28 +290,28 @@ describe Feed do
|
|||
it "shows public recordings to you and to others" do
|
||||
user1.bands << band
|
||||
user1.save!
|
||||
music_session = FactoryGirl.create(:music_session, band: band)
|
||||
music_session.music_session_history.fan_access.should be_true
|
||||
music_session = FactoryGirl.create(:active_music_session, band: band)
|
||||
music_session.music_session.fan_access.should be_true
|
||||
|
||||
feeds, start = Feed.index(user1, band: band.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
|
||||
feeds, start = Feed.index(user2, band: band.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
end
|
||||
|
||||
it "shows private sessions to you, not to others" do
|
||||
user1.bands << band
|
||||
user1.save!
|
||||
music_session = FactoryGirl.create(:music_session, band: band, fan_access: false)
|
||||
music_session.music_session_history.fan_access.should be_false
|
||||
music_session = FactoryGirl.create(:active_music_session, band: band, fan_access: false)
|
||||
music_session.music_session.fan_access.should be_false
|
||||
|
||||
feeds, start = Feed.index(user1, band: band.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session_history.fan_access.should be_false
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
feeds[0].music_session.fan_access.should be_false
|
||||
|
||||
|
||||
feeds, start = Feed.index(user2, band: band.id)
|
||||
|
|
@ -355,8 +355,8 @@ describe Feed do
|
|||
|
||||
describe "user feeds" do
|
||||
it "does not show stuff from other people" do
|
||||
music_session = FactoryGirl.create(:music_session)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user2)
|
||||
music_session = FactoryGirl.create(:active_music_session)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user2)
|
||||
|
||||
claimed_recording1 = FactoryGirl.create(:claimed_recording)
|
||||
claimed_recording1.is_public = true
|
||||
|
|
@ -367,28 +367,28 @@ describe Feed do
|
|||
end
|
||||
|
||||
it "shows public sessions to you and to others" do
|
||||
music_session = FactoryGirl.create(:music_session)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session)
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)
|
||||
|
||||
feeds, start = Feed.index(user1, user: user1.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
|
||||
feeds, start = Feed.index(user2, user: user1.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
end
|
||||
|
||||
|
||||
it "shows private sessions to you, not to others" do
|
||||
music_session = FactoryGirl.create(:music_session, fan_access: false)
|
||||
music_session.music_session_history.fan_access.should be_false
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, fan_access: false)
|
||||
music_session.music_session.fan_access.should be_false
|
||||
FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user1)
|
||||
|
||||
feeds, start = Feed.index(user1, user: user1.id)
|
||||
feeds.length.should == 1
|
||||
feeds[0].music_session_history.should == music_session.music_session_history
|
||||
feeds[0].music_session_history.fan_access.should be_false
|
||||
feeds[0].music_session.should == music_session.music_session
|
||||
feeds[0].music_session.fan_access.should be_false
|
||||
|
||||
|
||||
feeds, start = Feed.index(user2, user: user1.id)
|
||||
|
|
|
|||
|
|
@ -166,39 +166,39 @@ describe IcecastMount do
|
|||
let(:server1) {FactoryGirl.create(:icecast_server_minimal)}
|
||||
let(:server2) {FactoryGirl.create(:icecast_server_with_overrides)}
|
||||
let(:server3) {FactoryGirl.create(:icecast_server_with_overrides)}
|
||||
let(:hidden_music_session) { FactoryGirl.create(:music_session, :fan_access => false)}
|
||||
let(:public_music_session) { FactoryGirl.create(:music_session, :fan_access => true)}
|
||||
let(:public_music_session2) { FactoryGirl.create(:music_session, :fan_access => true)}
|
||||
let(:public_music_session3) { FactoryGirl.create(:music_session, :fan_access => true)}
|
||||
let(:hidden_music_session) { FactoryGirl.create(:active_music_session, :fan_access => false)}
|
||||
let(:public_music_session) { FactoryGirl.create(:active_music_session, :fan_access => true)}
|
||||
let(:public_music_session2) { FactoryGirl.create(:active_music_session, :fan_access => true)}
|
||||
let(:public_music_session3) { FactoryGirl.create(:active_music_session, :fan_access => true)}
|
||||
|
||||
before(:each) do
|
||||
|
||||
end
|
||||
|
||||
it "no fan access means no mount" do
|
||||
mount = IcecastMount.build_session_mount(hidden_music_session, IcecastServer.find_best_server_for_user(hidden_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(hidden_music_session.music_session, hidden_music_session, IcecastServer.find_best_server_for_user(hidden_music_session.creator))
|
||||
mount.should be_nil
|
||||
end
|
||||
|
||||
it "with no servers" do
|
||||
IcecastServer.count.should == 0
|
||||
mount = IcecastMount.build_session_mount(public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session.music_session, public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount.should be_nil
|
||||
end
|
||||
|
||||
it "with a server that has a mount template" do
|
||||
server1.mount_template.should_not be_nil
|
||||
mount = IcecastMount.build_session_mount(public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session.music_session, public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount.should_not be_nil
|
||||
mount.save!
|
||||
end
|
||||
|
||||
it "with a server that already has an associated mount" do
|
||||
server1.mount_template.should_not be_nil
|
||||
mount = IcecastMount.build_session_mount(public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session.music_session, public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount.save!
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session2.music_session, public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount.save!
|
||||
server1.reload
|
||||
server1.mounts.length.should == 2
|
||||
|
|
@ -207,13 +207,13 @@ describe IcecastMount do
|
|||
it "picks a second server once the 1st has been chosen" do
|
||||
server1.touch
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session.music_session, public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount.listeners = 1 # affect the weight
|
||||
mount.save!
|
||||
|
||||
server2.touch
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session2.music_session, public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount.save!
|
||||
server1.reload
|
||||
server1.mounts.length.should == 1
|
||||
|
|
@ -224,17 +224,17 @@ describe IcecastMount do
|
|||
it "picks the 1st server again once the 2nd has higher weight" do
|
||||
server1.touch
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session.music_session, public_music_session, IcecastServer.find_best_server_for_user(public_music_session.creator))
|
||||
mount.listeners = 1 # affect the weight
|
||||
mount.save!
|
||||
|
||||
server2.touch
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session2.music_session, public_music_session2, IcecastServer.find_best_server_for_user(public_music_session2.creator))
|
||||
mount.sourced = 1
|
||||
mount.save!
|
||||
|
||||
mount = IcecastMount.build_session_mount(public_music_session3, IcecastServer.find_best_server_for_user(public_music_session3.creator))
|
||||
mount = IcecastMount.build_session_mount(public_music_session3.music_session, public_music_session3, IcecastServer.find_best_server_for_user(public_music_session3.creator))
|
||||
mount.listeners = 1
|
||||
mount.save!
|
||||
|
||||
|
|
|
|||
|
|
@ -10,11 +10,11 @@ describe IcecastMountTemplate do
|
|||
|
||||
describe "poke configs" do
|
||||
let(:server) { a = FactoryGirl.create(:icecast_server_with_overrides); a.config_updated; IcecastServer.find(a.id) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session, :fan_access => true)}
|
||||
let(:music_session) { FactoryGirl.create(:active_music_session, :fan_access => true)}
|
||||
|
||||
before(:each) do
|
||||
server.touch
|
||||
mount = IcecastMount.build_session_mount(music_session, IcecastServer.find_best_server_for_user(music_session.creator))
|
||||
mount = IcecastMount.build_session_mount(music_session.music_session, music_session, IcecastServer.find_best_server_for_user(music_session.creator))
|
||||
mount.save!
|
||||
server.save!
|
||||
server.config_updated
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe MusicSession do
|
||||
describe ActiveMusicSession do
|
||||
|
||||
it 'cant create invitation to non-friend' do
|
||||
|
||||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
music_session_member2 = FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session)
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session.music_session)
|
||||
|
||||
invitation.save.should be_false
|
||||
invitation.errors.size.should == 1
|
||||
|
|
@ -24,7 +24,7 @@ describe MusicSession do
|
|||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
music_session_member2 = FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
|
@ -32,7 +32,7 @@ describe MusicSession do
|
|||
FactoryGirl.create(:friendship, :user => user1, :friend => user2)
|
||||
FactoryGirl.create(:friendship, :user => user2, :friend => user1)
|
||||
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session)
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session.music_session)
|
||||
|
||||
invitation.save.should be_true
|
||||
end
|
||||
|
|
@ -41,14 +41,14 @@ describe MusicSession do
|
|||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
connection2 = FactoryGirl.create(:connection, :user => user2, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
||||
join_request = FactoryGirl.create(:join_request, :user => user2, :music_session => music_session)
|
||||
join_request = FactoryGirl.create(:join_request, :user => user2, :music_session => music_session.music_session)
|
||||
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session, :join_request => join_request)
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session.music_session, :join_request => join_request)
|
||||
|
||||
invitation.save.should be_true
|
||||
end
|
||||
|
|
@ -57,15 +57,15 @@ describe MusicSession do
|
|||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session2 = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
music_session2 = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
connection2 = FactoryGirl.create(:connection, :user => user2, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
||||
join_request = FactoryGirl.create(:join_request, :user => user2, :music_session => music_session2)
|
||||
join_request = FactoryGirl.create(:join_request, :user => user2, :music_session => music_session2.music_session)
|
||||
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session, :join_request => join_request)
|
||||
invitation = Invitation.new(:sender => user1, :receiver => user2, :music_session => music_session.music_session, :join_request => join_request)
|
||||
|
||||
invitation.save.should be_false
|
||||
invitation.errors.get(:join_request).should == [Invitation::JOIN_REQUEST_IS_NOT_FOR_RECEIVER_AND_MUSIC_SESSION ]
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ describe JoinRequest do
|
|||
|
||||
it 'can create a join request' do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session, :text => "Let me join yo")
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session.music_session, :text => "Let me join yo")
|
||||
|
||||
join_request.save.should be_true
|
||||
|
||||
|
|
@ -18,9 +18,9 @@ describe JoinRequest do
|
|||
it 'fans cant create a join request' do
|
||||
user1 = FactoryGirl.create(:user, :musician => true)
|
||||
user2 = FactoryGirl.create(:user, :musician => false)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
join_request = JoinRequest.new(:user => user2, :music_session => music_session, :text => "Let me join yo")
|
||||
join_request = JoinRequest.new(:user => user2, :music_session => music_session.music_session, :text => "Let me join yo")
|
||||
|
||||
join_request.save.should be_false
|
||||
join_request.errors.size.should == 1
|
||||
|
|
@ -29,12 +29,12 @@ describe JoinRequest do
|
|||
|
||||
it 'cant create a dup join_request' do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session, :text => "Let me join yo")
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session.music_session, :text => "Let me join yo")
|
||||
join_request.save.should be_true
|
||||
|
||||
join_request2 = JoinRequest.new(:user => user1, :music_session => music_session, :text => "Let me join yo")
|
||||
join_request2 = JoinRequest.new(:user => user1, :music_session => music_session.music_session, :text => "Let me join yo")
|
||||
|
||||
join_request2.save.should be_false
|
||||
join_request2.errors.get(:user_id) == ["has already been taken"]
|
||||
|
|
@ -42,9 +42,9 @@ describe JoinRequest do
|
|||
|
||||
it "cant contain profanity in the text" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session, :text => "fuck you")
|
||||
join_request = JoinRequest.new(:user => user1, :music_session => music_session.music_session, :text => "fuck you")
|
||||
join_request.save
|
||||
join_request.valid?.should be_false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe Mix do
|
|||
@connection = FactoryGirl.create(:connection, :user => @user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
|
||||
# @music_session.connections << @connection
|
||||
@music_session.save
|
||||
@connection.join_the_session(@music_session, true, nil)
|
||||
|
|
|
|||
|
|
@ -1,23 +1,57 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe MusicSessionHistory do
|
||||
describe MusicSession do
|
||||
|
||||
|
||||
let(:creator) {FactoryGirl.create(:user)}
|
||||
let(:some_user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => music_session.creator, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
|
||||
let(:user_history3) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => music_session.creator, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
|
||||
let(:user_history4) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
|
||||
let(:music_session) { FactoryGirl.create(:active_music_session_no_user_history) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user, :created_at => 2.days.ago, :session_removed_at => 1.days.ago) }
|
||||
let(:user_history3) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
|
||||
let(:user_history4) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user, :created_at => 3.days.ago, :session_removed_at => 2.days.ago) }
|
||||
|
||||
it "create" do
|
||||
music_session.music_session_history.description.should eql(music_session.description)
|
||||
describe "validations" do
|
||||
it "genre must be set" do
|
||||
music_session = FactoryGirl.build(:music_session)
|
||||
music_session.genre = nil
|
||||
music_session.save.should be_false
|
||||
music_session.errors[:genre].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it "updates the fields of a music session properly" do
|
||||
genre1 = FactoryGirl.create(:genre)
|
||||
genre2 = FactoryGirl.create(:genre)
|
||||
genre3 = FactoryGirl.create(:genre)
|
||||
genre4 = FactoryGirl.create(:genre)
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genre => genre3)
|
||||
session.update_attributes({:description => "Session2", :genre => genre1})
|
||||
session.reload
|
||||
session.description.should == "Session2"
|
||||
session.genre.should == genre1
|
||||
end
|
||||
|
||||
it "must have legal_terms accepted" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.build(:music_session, :creator => user1, legal_terms: false)
|
||||
music_session.save
|
||||
music_session.valid?.should be_false
|
||||
music_session.errors["legal_terms"].should == ["is not included in the list"]
|
||||
end
|
||||
|
||||
it "cannot have profanity in the description" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.build(:music_session, :creator => user1, legal_terms: false, :description => "fuck you")
|
||||
music_session.save
|
||||
music_session.valid?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
it "unique users" do
|
||||
user_history1.should_not be_nil
|
||||
user_history2.should_not be_nil
|
||||
users = music_session.music_session_history.unique_users
|
||||
users = music_session.music_session.unique_users
|
||||
|
||||
users.length.should eql(2)
|
||||
|
||||
|
|
@ -26,7 +60,7 @@ describe MusicSessionHistory do
|
|||
|
||||
user_history3.should_not be_nil
|
||||
user_history4.should_not be_nil
|
||||
users = music_session.music_session_history.unique_users
|
||||
users = music_session.music_session.unique_users
|
||||
|
||||
users.length.should eql(2)
|
||||
users.include?(some_user).should be_true
|
||||
|
|
@ -44,7 +78,7 @@ describe MusicSessionHistory do
|
|||
user_history2.session_removed_at = session_removed_at
|
||||
user_history2.save!
|
||||
|
||||
histories = music_session.music_session_history.unique_user_histories
|
||||
histories = music_session.music_session.unique_user_histories
|
||||
histories.length.should eql(2)
|
||||
histories[0].first_name.should_not be_nil
|
||||
histories[0].last_name.should_not be_nil
|
||||
|
|
@ -62,7 +96,7 @@ describe MusicSessionHistory do
|
|||
user_history4.session_removed_at = session_removed_at
|
||||
user_history4.save!
|
||||
|
||||
histories = music_session.music_session_history.unique_user_histories
|
||||
histories = music_session.music_session.unique_user_histories
|
||||
histories.length.should eql(2)
|
||||
histories[0].total_duration.to_i.should == 2.day.to_i
|
||||
histories[0].total_instruments.should == 'guitar|guitar'
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
describe MusicSessionPerfData do
|
||||
|
||||
before do
|
||||
#music_session = FactoryGirl.create(:music_session)
|
||||
#music_session = FactoryGirl.create(:active_music_session)
|
||||
#connection = FactoryGirl.create(:connection, :music_session => music_session)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,28 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe MusicSession do
|
||||
describe ActiveMusicSession do
|
||||
|
||||
before(:each) do
|
||||
MusicSession.delete_all
|
||||
ActiveMusicSession.delete_all
|
||||
IcecastServer.delete_all
|
||||
IcecastMount.delete_all
|
||||
end
|
||||
|
||||
describe "validations" do
|
||||
it "genre must be set" do
|
||||
music_session = FactoryGirl.build(:music_session)
|
||||
music_session.genres = []
|
||||
music_session.save.should be_false
|
||||
music_session.errors[:genres].should == [ValidationMessages::SESSION_GENRE_MINIMUM_NOT_MET]
|
||||
end
|
||||
end
|
||||
it 'can grant access to valid user' do
|
||||
|
||||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
user3 = FactoryGirl.create(:user) # not in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1, :musician_access => false)
|
||||
FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
FactoryGirl.create(:connection, :user => user2, :music_session => music_session)
|
||||
|
||||
|
|
@ -38,7 +30,7 @@ describe MusicSession do
|
|||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
user3 = FactoryGirl.create(:user) # not in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => true)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1, :musician_access => true)
|
||||
|
||||
music_session.can_join?(user1, true).should == true
|
||||
music_session.can_join?(user2, true).should == true
|
||||
|
|
@ -50,7 +42,7 @@ describe MusicSession do
|
|||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
user3 = FactoryGirl.create(:user) # not in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1, :musician_access => false)
|
||||
FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
|
||||
music_session.can_join?(user1, true).should == true
|
||||
|
|
@ -60,7 +52,7 @@ describe MusicSession do
|
|||
# invite user 2
|
||||
FactoryGirl.create(:friendship, :user => user1, :friend => user2)
|
||||
FactoryGirl.create(:friendship, :user => user2, :friend => user1)
|
||||
FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session)
|
||||
FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session.music_session)
|
||||
|
||||
music_session.can_join?(user1, true).should == true
|
||||
music_session.can_join?(user2, true).should == true
|
||||
|
|
@ -72,7 +64,7 @@ describe MusicSession do
|
|||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
user3 = FactoryGirl.create(:user) # not in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => false, :fan_access => false)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1, :musician_access => false, :fan_access => false)
|
||||
FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
|
||||
music_session.can_see?(user1).should == true
|
||||
|
|
@ -82,29 +74,28 @@ describe MusicSession do
|
|||
# invite user 2
|
||||
FactoryGirl.create(:friendship, :user => user1, :friend => user2)
|
||||
FactoryGirl.create(:friendship, :user => user2, :friend => user1)
|
||||
FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session)
|
||||
FactoryGirl.create(:invitation, :sender => user1, :receiver => user2, :music_session => music_session.music_session)
|
||||
|
||||
music_session.can_see?(user1).should == true
|
||||
music_session.can_see?(user2).should == true
|
||||
music_session.can_see?(user3).should == false
|
||||
end
|
||||
|
||||
|
||||
describe "index" do
|
||||
it "orders two sessions by created_at starting with most recent" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
creator2 = FactoryGirl.create(:user)
|
||||
|
||||
earlier_session = FactoryGirl.create(:music_session, :creator => creator, :description => "Earlier Session")
|
||||
earlier_session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Earlier Session")
|
||||
FactoryGirl.create(:connection, :user => creator, :music_session => earlier_session)
|
||||
|
||||
later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
|
||||
later_session = FactoryGirl.create(:active_music_session, :creator => creator2, :description => "Later Session")
|
||||
FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)
|
||||
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 2
|
||||
music_sessions.first.id.should == later_session.id
|
||||
end
|
||||
|
|
@ -113,17 +104,17 @@ describe MusicSession do
|
|||
creator1 = FactoryGirl.create(:user)
|
||||
creator2 = FactoryGirl.create(:user)
|
||||
|
||||
earlier_session = FactoryGirl.create(:music_session, :creator => creator1, :description => "Earlier Session")
|
||||
earlier_session = FactoryGirl.create(:active_music_session, :creator => creator1, :description => "Earlier Session")
|
||||
FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
|
||||
later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
|
||||
later_session = FactoryGirl.create(:active_music_session, :creator => creator2, :description => "Later Session")
|
||||
FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)
|
||||
user = FactoryGirl.create(:user)
|
||||
FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
|
||||
FactoryGirl.create(:friendship, :user => creator1, :friend => user)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => creator1)
|
||||
FactoryGirl.create(:invitation, :sender => creator1, :receiver => user, :music_session => earlier_session)
|
||||
FactoryGirl.create(:invitation, :sender => creator1, :receiver => user, :music_session => earlier_session.music_session)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 2
|
||||
music_sessions.first.id.should == earlier_session.id
|
||||
end
|
||||
|
|
@ -133,9 +124,9 @@ describe MusicSession do
|
|||
|
||||
creator1 = FactoryGirl.create(:user)
|
||||
creator2 = FactoryGirl.create(:user)
|
||||
earlier_session = FactoryGirl.create(:music_session, :creator => creator1, :description => "Earlier Session")
|
||||
earlier_session = FactoryGirl.create(:active_music_session, :creator => creator1, :description => "Earlier Session")
|
||||
FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
|
||||
later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
|
||||
later_session = FactoryGirl.create(:active_music_session, :creator => creator2, :description => "Later Session")
|
||||
FactoryGirl.create(:connection, :user => creator2, :music_session => later_session)
|
||||
|
||||
user = FactoryGirl.create(:user)
|
||||
|
|
@ -144,41 +135,41 @@ describe MusicSession do
|
|||
FactoryGirl.create(:connection, :user => creator1, :music_session => earlier_session)
|
||||
FactoryGirl.create(:connection, :user => creator2, :music_session => earlier_session)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 2
|
||||
music_sessions.first.id.should == earlier_session.id
|
||||
end
|
||||
|
||||
it "doesn't list a session if musician_access is set to false" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :musician_access => false)
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :musician_access => false)
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 0
|
||||
end
|
||||
|
||||
it "does list a session if musician_access is set to false but user was invited" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :musician_access => false)
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :musician_access => false)
|
||||
user = FactoryGirl.create(:user)
|
||||
FactoryGirl.create(:connection, :user => creator, :music_session => session)
|
||||
FactoryGirl.create(:friendship, :user => creator, :friend => user)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => creator)
|
||||
FactoryGirl.create(:invitation, :sender => creator, :receiver => user, :music_session => session)
|
||||
FactoryGirl.create(:invitation, :sender => creator, :receiver => user, :music_session => session.music_session)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 1
|
||||
end
|
||||
|
||||
it "lists a session if the genre matches" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
genre = FactoryGirl.create(:genre)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre])
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :genre => genre)
|
||||
FactoryGirl.create(:connection, :user => creator, :music_session => session)
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
music_sessions = MusicSession.index(user, genres: [genre.id])
|
||||
music_sessions = ActiveMusicSession.index(user, genres: [genre.id])
|
||||
music_sessions.length.should == 1
|
||||
end
|
||||
|
||||
|
|
@ -186,37 +177,37 @@ describe MusicSession do
|
|||
creator = FactoryGirl.create(:user)
|
||||
genre1 = FactoryGirl.create(:genre)
|
||||
genre2 = FactoryGirl.create(:genre)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre1])
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :genre => genre1)
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
music_sessions = MusicSession.index(user, genres: [genre2.id])
|
||||
music_sessions = ActiveMusicSession.index(user, genres: [genre2.id])
|
||||
music_sessions.length.should == 0
|
||||
end
|
||||
|
||||
it "does not list a session if friends_only is set and no friends are in it" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session")
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
music_sessions = MusicSession.index(user, friends_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: true)
|
||||
music_sessions.length.should == 0
|
||||
end
|
||||
|
||||
it "lists a session properly if a friend is in it" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session")
|
||||
user = FactoryGirl.create(:user)
|
||||
FactoryGirl.create(:friendship, :user => creator, :friend => user)
|
||||
FactoryGirl.create(:friendship, :user => user, :friend => creator)
|
||||
FactoryGirl.create(:connection, :user => creator, :music_session => session)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 1
|
||||
music_sessions = MusicSession.index(user, friends_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: true)
|
||||
music_sessions.length.should == 1
|
||||
music_sessions = MusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions.length.should == 0
|
||||
music_sessions = MusicSession.index(user, friends_only: true, my_bands_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: true, my_bands_only: true)
|
||||
music_sessions.length.should == 1
|
||||
end
|
||||
|
||||
|
|
@ -225,46 +216,46 @@ describe MusicSession do
|
|||
# however, this bug continually crops up so the .index method will protect against this common bug
|
||||
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session")
|
||||
session.connections.delete_all # should leave a bogus, 0 participant session around
|
||||
|
||||
music_sessions = MusicSession.index(creator)
|
||||
music_sessions = ActiveMusicSession.index(creator)
|
||||
music_sessions.length.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "does not list a session if my_bands_only is set and it's not my band" do
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session")
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session")
|
||||
user = FactoryGirl.create(:user)
|
||||
|
||||
music_sessions = MusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions.length.should == 0
|
||||
end
|
||||
|
||||
it "lists a session properly if it's my band's session" do
|
||||
band = FactoryGirl.create(:band)
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :band => band)
|
||||
session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Session", :band => band)
|
||||
FactoryGirl.create(:connection, :user => creator, :music_session => session)
|
||||
user = FactoryGirl.create(:user)
|
||||
FactoryGirl.create(:band_musician, :band => band, :user => creator)
|
||||
FactoryGirl.create(:band_musician, :band => band, :user => user)
|
||||
|
||||
music_sessions = MusicSession.index(user)
|
||||
music_sessions = ActiveMusicSession.index(user)
|
||||
music_sessions.length.should == 1
|
||||
music_sessions = MusicSession.index(user, friends_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: true)
|
||||
music_sessions.length.should == 0
|
||||
music_sessions = MusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: false, my_bands_only: true)
|
||||
music_sessions.length.should == 1
|
||||
music_sessions = MusicSession.index(user, friends_only: true, my_bands_only: true)
|
||||
music_sessions = ActiveMusicSession.index(user, friends_only: true, my_bands_only: true)
|
||||
music_sessions.length.should == 1
|
||||
end
|
||||
|
||||
describe "index(as_musician: false)" do
|
||||
let(:fan_access) { true }
|
||||
let(:creator) { FactoryGirl.create(:user) }
|
||||
let(:session) { FactoryGirl.create(:music_session, creator: creator, fan_access: fan_access ) }
|
||||
let(:session) { FactoryGirl.create(:active_music_session, creator: creator, fan_access: fan_access ) }
|
||||
let(:connection) { FactoryGirl.create(:connection, user: creator, :music_session => session) }
|
||||
|
||||
let(:user) {FactoryGirl.create(:user) }
|
||||
|
|
@ -277,13 +268,13 @@ describe MusicSession do
|
|||
|
||||
it "no session listed if mount is nil" do
|
||||
connection.touch
|
||||
sessions = MusicSession.index(user, as_musician: false)
|
||||
sessions = ActiveMusicSession.index(user, as_musician: false)
|
||||
sessions.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "with mount" do
|
||||
let(:session_with_mount) { FactoryGirl.create(:music_session_with_mount) }
|
||||
let(:session_with_mount) { FactoryGirl.create(:active_music_session_with_mount) }
|
||||
let(:connection_with_mount) { FactoryGirl.create(:connection, user: creator, :music_session => session_with_mount) }
|
||||
|
||||
|
||||
|
|
@ -293,7 +284,7 @@ describe MusicSession do
|
|||
|
||||
it "no session listed if icecast_server config hasn't been updated" do
|
||||
connection_with_mount.touch
|
||||
sessions = MusicSession.index(user, as_musician: false)
|
||||
sessions = ActiveMusicSession.index(user, as_musician: false)
|
||||
sessions.length.should == 0
|
||||
end
|
||||
|
||||
|
|
@ -303,7 +294,7 @@ describe MusicSession do
|
|||
session_with_mount.save!(:validate => false)
|
||||
session_with_mount.mount.server.config_updated_at = 1.minute.ago
|
||||
session_with_mount.mount.server.save!(:validate => false)
|
||||
sessions = MusicSession.index(user, as_musician: false)
|
||||
sessions = ActiveMusicSession.index(user, as_musician: false)
|
||||
sessions.length.should == 1
|
||||
end
|
||||
end
|
||||
|
|
@ -316,10 +307,10 @@ describe MusicSession do
|
|||
creator = FactoryGirl.create(:user)
|
||||
creator2 = FactoryGirl.create(:user)
|
||||
|
||||
earlier_session = FactoryGirl.create(:music_session, :creator => creator, :description => "Earlier Session")
|
||||
earlier_session = FactoryGirl.create(:active_music_session, :creator => creator, :description => "Earlier Session")
|
||||
c1 = FactoryGirl.create(:connection, user: creator, music_session: earlier_session, addr: 0x01020304, locidispid: 1)
|
||||
|
||||
later_session = FactoryGirl.create(:music_session, :creator => creator2, :description => "Later Session")
|
||||
later_session = FactoryGirl.create(:active_music_session, :creator => creator2, :description => "Later Session")
|
||||
c2 = FactoryGirl.create(:connection, user: creator2, music_session: later_session, addr: 0x21020304, locidispid: 2)
|
||||
|
||||
user = FactoryGirl.create(:user)
|
||||
|
|
@ -331,7 +322,7 @@ describe MusicSession do
|
|||
# scores!
|
||||
|
||||
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
||||
music_sessions = MusicSession.nindex(user, client_id: c3.client_id).take(100)
|
||||
music_sessions = ActiveMusicSession.nindex(user, client_id: c3.client_id).take(100)
|
||||
#music_sessions = MusicSession.index(user).take(100)
|
||||
#ActiveRecord::Base.logger = nil
|
||||
|
||||
|
|
@ -341,50 +332,22 @@ describe MusicSession do
|
|||
end
|
||||
end
|
||||
|
||||
it "updates the fields of a music session properly" do
|
||||
genre1 = FactoryGirl.create(:genre)
|
||||
genre2 = FactoryGirl.create(:genre)
|
||||
genre3 = FactoryGirl.create(:genre)
|
||||
genre4 = FactoryGirl.create(:genre)
|
||||
creator = FactoryGirl.create(:user)
|
||||
session = FactoryGirl.create(:music_session, :creator => creator, :description => "Session", :genres => [genre3,genre4])
|
||||
session.update_attributes({:description => "Session2", :genre => [genre1, genre2]})
|
||||
session.genres = [genre1, genre2]
|
||||
session.reload
|
||||
session.description.should == "Session2"
|
||||
session.genres.length.should == 2
|
||||
session.genres[0].id.should == genre1.id
|
||||
end
|
||||
|
||||
it 'uninvited users cant join approval-required sessions without invitation' do
|
||||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1, :musician_access => true, :approval_required => true)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1, :musician_access => true, :approval_required => true)
|
||||
|
||||
connection1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session)
|
||||
expect { FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :joining_session => true) }.to raise_error(ActiveRecord::RecordInvalid)
|
||||
|
||||
end
|
||||
|
||||
it "must have legal_terms accepted" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false)
|
||||
music_session.save
|
||||
music_session.valid?.should be_false
|
||||
music_session.errors["legal_terms"].should == ["is not included in the list"]
|
||||
end
|
||||
|
||||
it "cannot have profanity in the description" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.build(:music_session, :creator => user1, :legal_terms=> false, :description => "fuck you")
|
||||
music_session.save
|
||||
music_session.valid?.should be_false
|
||||
end
|
||||
|
||||
it "is_recording? returns false if not recording" do
|
||||
user1 = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.build(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.build(:active_music_session, :creator => user1)
|
||||
music_session.is_recording?.should be_false
|
||||
end
|
||||
|
||||
|
|
@ -395,7 +358,7 @@ describe MusicSession do
|
|||
@connection = FactoryGirl.create(:connection, :user => @user1)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user1, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user1, :musician_access => true)
|
||||
# @music_session.connections << @connection
|
||||
@music_session.save!
|
||||
@connection.join_the_session(@music_session, true, nil)
|
||||
|
|
@ -474,7 +437,7 @@ describe MusicSession do
|
|||
before(:each) do
|
||||
@user1 = FactoryGirl.create(:user)
|
||||
@user2 = FactoryGirl.create(:user)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user1, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user1, :musician_access => true)
|
||||
@connection1 = FactoryGirl.create(:connection, :user => @user1, :music_session => @music_session, :as_musician => true)
|
||||
@connection2 = FactoryGirl.create(:connection, :user => @user2, :music_session => @music_session, :as_musician => false)
|
||||
|
||||
|
|
@ -500,14 +463,5 @@ describe MusicSession do
|
|||
@music_session.get_connection_ids(exclude_client_id: @connection2.client_id, as_musician: true).should == [@connection1.client_id]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "autosave of music session history" do
|
||||
it "is created on initial music session create" do
|
||||
music_session = FactoryGirl.create(:music_session)
|
||||
history = MusicSessionHistory.find(music_session.id)
|
||||
history.genres.should == music_session.genres.first.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ require 'spec_helper'
|
|||
describe MusicSessionUserHistory do
|
||||
|
||||
let(:some_user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => music_session.creator) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user) }
|
||||
let(:music_session) { FactoryGirl.create(:active_music_session_no_user_history) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => music_session.creator) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user) }
|
||||
|
||||
describe "create" do
|
||||
pending
|
||||
it {user_history1.music_session_id.should == music_session.id }
|
||||
it {user_history1.created_at.should_not be_nil }
|
||||
it {user_history1.session_removed_at.should be_nil }
|
||||
|
|
@ -15,28 +16,35 @@ describe MusicSessionUserHistory do
|
|||
|
||||
describe "rating" do
|
||||
|
||||
describe "success" do
|
||||
|
||||
before(:each) do
|
||||
user_history1.update_attribute(:rating ,0)
|
||||
end
|
||||
|
||||
it { user_history1.errors.any?.should be_false}
|
||||
it "success" do
|
||||
user_history1.update_attribute(:rating, 1)
|
||||
expect( user_history1.errors.any? ).to eq(false)
|
||||
end
|
||||
|
||||
describe "out of range" do
|
||||
before(:each) do
|
||||
user_history1.update_attribute(:rating, 3)
|
||||
user_history1.save
|
||||
end
|
||||
it "out of range" do
|
||||
user_history1.rating = 2
|
||||
user_history1.save
|
||||
expect( user_history1.errors.any? ).to eq(true)
|
||||
end
|
||||
|
||||
it { user_history1.errors.any?.should be_true}
|
||||
it 'should rate success' do
|
||||
users = [user_history1, user_history2]
|
||||
Timecop.travel(Time.now + (MusicSessionUserHistory::MIN_SESSION_DURATION_RATING * 1.5).seconds)
|
||||
expect( user_history1.should_rate_session? ).to eq(true)
|
||||
Timecop.return
|
||||
end
|
||||
|
||||
it 'should rate fails' do
|
||||
users = [user_history1]
|
||||
expect( user_history1.should_rate_session? ).to eq(false)
|
||||
users = [user_history1, user_history2]
|
||||
expect( user_history2.should_rate_session? ).to eq(false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "end_history" do
|
||||
|
||||
pending
|
||||
it "histories created at the same time" do
|
||||
user_history1.reload
|
||||
user_history2.reload
|
||||
|
|
@ -77,7 +85,7 @@ describe MusicSessionUserHistory do
|
|||
end
|
||||
|
||||
it "two histories with same user within bounds of history1" do
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => some_user)
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => some_user)
|
||||
|
||||
# if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3
|
||||
user_history1.session_removed_at = user_history1.created_at + 5
|
||||
|
|
@ -98,7 +106,7 @@ describe MusicSessionUserHistory do
|
|||
it "two histories with different user within bounds of history1" do
|
||||
third_user = FactoryGirl.create(:user);
|
||||
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => third_user)
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => third_user)
|
||||
|
||||
# if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3
|
||||
user_history1.session_removed_at = user_history1.created_at + 5
|
||||
|
|
@ -119,7 +127,7 @@ describe MusicSessionUserHistory do
|
|||
it "two overlapping histories with different user within bounds of history1" do
|
||||
third_user = FactoryGirl.create(:user);
|
||||
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => third_user)
|
||||
user_history3 = FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => third_user)
|
||||
|
||||
# if user2 comes and goes 2 times while user one is there, it shouldn't be a false 3
|
||||
user_history1.session_removed_at = user_history1.created_at + 5
|
||||
|
|
@ -136,10 +144,7 @@ describe MusicSessionUserHistory do
|
|||
user_history1.end_history
|
||||
user_history1.max_concurrent_connections.should == 3
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ describe 'Musician search' do
|
|||
connection = FactoryGirl.create(:connection, :user => usr)
|
||||
instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
track = FactoryGirl.create(:track, :connection => connection, :instrument => instrument)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => usr, :musician_access => true)
|
||||
# music_session.connections << connection
|
||||
music_session.save
|
||||
connection.join_the_session(music_session, true, nil)
|
||||
|
|
@ -127,7 +127,7 @@ describe 'Musician search' do
|
|||
|
||||
def make_session(usr)
|
||||
connection = FactoryGirl.create(:connection, :user => usr)
|
||||
music_session = FactoryGirl.create(:music_session, :creator => usr, :musician_access => true)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => usr, :musician_access => true)
|
||||
# music_session.connections << connection
|
||||
music_session.save
|
||||
connection.join_the_session(music_session, true, nil)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ describe RecordedTrack do
|
|||
@user = FactoryGirl.create(:user)
|
||||
@connection = FactoryGirl.create(:connection, :user => @user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@recording = FactoryGirl.create(:recording, :music_session => @music_session, :owner => @user)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ describe Recording do
|
|||
before do
|
||||
@user = FactoryGirl.create(:user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
|
||||
@connection = FactoryGirl.create(:connection, :user => @user, :music_session => @music_session)
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
describe ShareToken do
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) {FactoryGirl.create(:music_session) }
|
||||
let(:music_session) {FactoryGirl.create(:active_music_session) }
|
||||
let(:claimed_recording) {FactoryGirl.create(:claimed_recording) }
|
||||
|
||||
before(:each) do
|
||||
|
|
@ -13,9 +13,9 @@ describe ShareToken do
|
|||
it "can reference a music session" do
|
||||
music_session.touch # should create a MSH, and a token, too
|
||||
ShareToken.count.should == 1
|
||||
music_session.music_session_history.share_token.should_not be_nil
|
||||
music_session.music_session.share_token.should_not be_nil
|
||||
token = ShareToken.find_by_shareable_id!(music_session.id)
|
||||
token.should == music_session.music_session_history.share_token
|
||||
token.should == music_session.music_session.share_token
|
||||
token.shareable_id.should == music_session.id
|
||||
token.shareable_type.should == 'session'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,11 +3,11 @@ require 'spec_helper'
|
|||
describe Track do
|
||||
|
||||
let (:user) {FactoryGirl.create(:user) }
|
||||
let (:music_session) { FactoryGirl.create(:music_session, :creator => user)}
|
||||
let (:music_session) { FactoryGirl.create(:active_music_session, :creator => user)}
|
||||
let (:connection) { FactoryGirl.create(:connection, :user => user, :music_session => music_session) }
|
||||
let (:track) { FactoryGirl.create(:track, :connection => connection)}
|
||||
let (:track2) { FactoryGirl.create(:track, :connection => connection)}
|
||||
let (:msuh) {FactoryGirl.create(:music_session_user_history, :history => music_session.music_session_history, :user => user, :client_id => connection.client_id) }
|
||||
let (:msuh) {FactoryGirl.create(:music_session_user_history, :history => music_session.music_session, :user => user, :client_id => connection.client_id) }
|
||||
let (:track_hash) { {:client_track_id => 'client_guid', :sound => 'stereo', :instrument_id => 'drums'} }
|
||||
|
||||
before(:each) do
|
||||
|
|
@ -74,14 +74,7 @@ describe Track do
|
|||
it "updates a single track using .id to correlate" do
|
||||
track.id.should_not be_nil
|
||||
connection.tracks.length.should == 1
|
||||
begin
|
||||
ActiveRecord::Base.record_timestamps = false
|
||||
track.updated_at = 1.days.ago
|
||||
track.save!
|
||||
ensure
|
||||
# very important to turn it back; it'll break all tests otherwise
|
||||
ActiveRecord::Base.record_timestamps = true
|
||||
end
|
||||
set_updated_at(track, 1.days.ago)
|
||||
tracks = Track.sync(connection.client_id, [{:id => track.id, :client_track_id => 'client_guid_new', :sound => 'mono', :instrument_id => 'drums'}])
|
||||
tracks.length.should == 1
|
||||
found = tracks[0]
|
||||
|
|
@ -105,14 +98,7 @@ describe Track do
|
|||
it "does not touch updated_at when nothing changes" do
|
||||
track.id.should_not be_nil
|
||||
connection.tracks.length.should == 1
|
||||
begin
|
||||
ActiveRecord::Base.record_timestamps = false
|
||||
track.updated_at = 1.days.ago
|
||||
track.save!
|
||||
ensure
|
||||
# very important to turn it back; it'll break all tests otherwise
|
||||
ActiveRecord::Base.record_timestamps = true
|
||||
end
|
||||
set_updated_at(track, 1.days.ago)
|
||||
tracks = Track.sync(connection.client_id, [{:id => track.id, :client_track_id => track.client_track_id, :sound => track.sound, :instrument_id => track.instrument_id}])
|
||||
tracks.length.should == 1
|
||||
found = tracks[0]
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ describe User do
|
|||
it { should respond_to(:admin) }
|
||||
it { should respond_to(:valid_password?) }
|
||||
it { should respond_to(:can_invite) }
|
||||
it { should respond_to(:mods) }
|
||||
|
||||
it { should be_valid }
|
||||
it { should_not be_admin }
|
||||
|
|
@ -69,6 +70,24 @@ describe User do
|
|||
it { should_not be_valid }
|
||||
end
|
||||
|
||||
describe "when mods is null" do
|
||||
before { @user.mods = nil }
|
||||
it { should be_valid }
|
||||
end
|
||||
|
||||
describe "when mods is empty" do
|
||||
before { @user.mods = 'nil' }
|
||||
it { should_not be_valid }
|
||||
end
|
||||
|
||||
|
||||
describe "when mods is json object" do
|
||||
before { @user.mods = '{"key":"value"}' }
|
||||
it { should be_valid }
|
||||
end
|
||||
|
||||
|
||||
|
||||
describe "first or last name cant have profanity" do
|
||||
it "should not let the first name have profanity" do
|
||||
@user.first_name = "fuck you"
|
||||
|
|
@ -118,6 +137,7 @@ describe User do
|
|||
|
||||
|
||||
it "should be saved as all lower-case" do
|
||||
pending
|
||||
@user.email = mixed_case_email
|
||||
@user.save!
|
||||
@user.reload.email.should == mixed_case_email.downcase
|
||||
|
|
@ -428,6 +448,29 @@ describe User do
|
|||
|
||||
|
||||
end
|
||||
|
||||
describe "mods" do
|
||||
it "should allow update of JSON" do
|
||||
@user.mods = {some_field: 5}.to_json
|
||||
@user.save!
|
||||
end
|
||||
|
||||
it "should return heartbeart interval" do
|
||||
@user.heartbeat_interval_client.should be_nil
|
||||
@user.mods = {heartbeat_interval_client: 5}.to_json
|
||||
@user.save!
|
||||
@user = User.find(@user.id) # necessary because mods_json is cached in the model
|
||||
@user.heartbeat_interval_client.should == 5
|
||||
end
|
||||
|
||||
it "should return connection_expire_time" do
|
||||
@user.connection_expire_time_client.should be_nil
|
||||
@user.mods = {connection_expire_time_client: 5}.to_json
|
||||
@user.save!
|
||||
@user = User.find(@user.id) # necessary because mods_json is cached in the model
|
||||
@user.connection_expire_time_client.should == 5
|
||||
end
|
||||
end
|
||||
=begin
|
||||
describe "update avatar" do
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ describe MQRouter do
|
|||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
music_session_member2 = FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
|
@ -37,7 +37,7 @@ describe MQRouter do
|
|||
user1 = FactoryGirl.create(:user) # in the jam session
|
||||
user2 = FactoryGirl.create(:user) # in the jam session
|
||||
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user1)
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user1)
|
||||
|
||||
music_session_member1 = FactoryGirl.create(:connection, :user => user1, :music_session => music_session, :ip_address => "1.1.1.1", :client_id => "1")
|
||||
music_session_member2 = FactoryGirl.create(:connection, :user => user2, :music_session => music_session, :ip_address => "2.2.2.2", :client_id => "2")
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ describe AudioMixer do
|
|||
@connection = FactoryGirl.create(:connection, :user => @user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session = FactoryGirl.create(:active_music_session, :creator => @user, :musician_access => true)
|
||||
# @music_session.connections << @connection
|
||||
@music_session.save
|
||||
@connection.join_the_session(@music_session, true, nil)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ describe GoogleAnalyticsEvent do
|
|||
ResqueSpec.reset!
|
||||
user = FactoryGirl.create(:user)
|
||||
band = FactoryGirl.create(:band)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
music_session = FactoryGirl.create(:active_music_session,
|
||||
:creator => user,
|
||||
:musician_access => true,
|
||||
:band => band)
|
||||
|
|
@ -34,7 +34,7 @@ describe GoogleAnalyticsEvent do
|
|||
band.users << user
|
||||
band.users << user1
|
||||
band.reload
|
||||
music_session = FactoryGirl.create(:music_session, :creator => user,
|
||||
music_session = FactoryGirl.create(:active_music_session, :creator => user,
|
||||
:musician_access => true, :band => band)
|
||||
expect(band.band_musicians.count).to eq(2)
|
||||
expect(band.did_real_session).to eq(false)
|
||||
|
|
@ -73,7 +73,7 @@ describe GoogleAnalyticsEvent do
|
|||
end
|
||||
it 'reports size increment' do
|
||||
user = FactoryGirl.create(:user)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
music_session = FactoryGirl.create(:active_music_session,
|
||||
:creator => user,
|
||||
:musician_access => true)
|
||||
connection = FactoryGirl.create(:connection, :user => user,
|
||||
|
|
@ -88,7 +88,7 @@ describe GoogleAnalyticsEvent do
|
|||
it 'reports duration' do
|
||||
user = FactoryGirl.create(:user)
|
||||
JamRuby::GoogleAnalyticsEvent::SessionDurationTracker.should have_schedule_size_of(0)
|
||||
music_session = FactoryGirl.create(:music_session,
|
||||
music_session = FactoryGirl.create(:active_music_session,
|
||||
:creator => user,
|
||||
:musician_access => true)
|
||||
GoogleAnalyticsEvent::SessionDurationTracker.should have_schedule_size_of(1)
|
||||
|
|
|
|||
|
|
@ -136,14 +136,7 @@ describe IcecastConfigWriter do
|
|||
pending "failing on build server"
|
||||
|
||||
server.touch
|
||||
begin
|
||||
ActiveRecord::Base.record_timestamps = false
|
||||
server.updated_at = Time.now.ago(APP_CONFIG.icecast_max_missing_check + 1)
|
||||
server.save!
|
||||
ensure
|
||||
# very important to turn it back; it'll break all tests otherwise
|
||||
ActiveRecord::Base.record_timestamps = true
|
||||
end
|
||||
set_updated_at(server, Time.now.ago(APP_CONFIG.icecast_max_missing_check + 1))
|
||||
|
||||
# should enqueue 1 job
|
||||
IcecastConfigWriter.queue_jobs_needing_retry
|
||||
|
|
|
|||
|
|
@ -122,6 +122,18 @@ def run_tests? type
|
|||
ENV["RUN_#{type}_TESTS"] == "1" || ENV[type] == "1" || ENV['ALL_TESTS'] == "1"
|
||||
end
|
||||
|
||||
# you have go out of your way to update 'updated_at '
|
||||
def set_updated_at(resource, time)
|
||||
begin
|
||||
ActiveRecord::Base.record_timestamps = false
|
||||
resource.updated_at = time
|
||||
resource.save!(validate: false)
|
||||
ensure
|
||||
# very important to turn it back; it'll break all tests otherwise
|
||||
ActiveRecord::Base.record_timestamps = true
|
||||
end
|
||||
end
|
||||
|
||||
def wipe_s3_test_bucket
|
||||
# don't bother if the user isn't doing AWS tests
|
||||
if run_tests? :aws
|
||||
|
|
|
|||
2
update
2
update
|
|
@ -17,7 +17,7 @@ pushd pb
|
|||
popd
|
||||
|
||||
echo ""
|
||||
echo "updating database"
|
||||
echo "updating ruby"
|
||||
echo ""
|
||||
pushd ruby
|
||||
bundle update
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ unless ENV["LOCAL_DEV"] == "1"
|
|||
end
|
||||
# Look for $WORKSPACE, otherwise use "workspace" as dev path.
|
||||
|
||||
devenv = ENV["BUILD_NUMBER"].nil? # Jenkins sets a build number environment variable
|
||||
devenv = ENV["BUILD_NUMBER"].nil? || ENV["TEST_WWW"] == "1"
|
||||
|
||||
if devenv
|
||||
gem 'jam_db', :path=> "../db/target/ruby_package"
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
|
|
@ -15,6 +15,12 @@
|
|||
'exception', 'table'
|
||||
];
|
||||
|
||||
var log_methods = {
|
||||
'log':null, 'debug':null, 'info':null, 'warn':null, 'error':null, 'assert':null, 'trace':null, 'exception':null
|
||||
}
|
||||
|
||||
var logCache = [];
|
||||
|
||||
if ('undefined' === typeof(context.console)) {
|
||||
context.console = {};
|
||||
$.each(console_methods, function(index, value) {
|
||||
|
|
@ -27,23 +33,39 @@
|
|||
context.console.debug = function() { console.log(arguments); }
|
||||
}
|
||||
|
||||
context.JK.logger = context.console;
|
||||
// http://tobyho.com/2012/07/27/taking-over-console-log/
|
||||
function takeOverConsole(){
|
||||
var console = window.console
|
||||
if (!console) return
|
||||
function intercept(method){
|
||||
var original = console[method]
|
||||
console[method] = function(){
|
||||
|
||||
// JW - some code to tone down logging. Uncomment the following, and
|
||||
// then do your logging to logger.dbg - and it will be the only thing output.
|
||||
// TODO - find a way to wrap this up so that debug logs can stay in, but this
|
||||
// class can provide a way to enable/disable certain namespaces of logs.
|
||||
/*
|
||||
var fakeLogger = {};
|
||||
$.each(console_methods, function(index, value) {
|
||||
fakeLogger[value] = $.noop;
|
||||
});
|
||||
fakeLogger.dbg = function(m) {
|
||||
context.console.debug(m);
|
||||
};
|
||||
context.JK.logger = fakeLogger;
|
||||
*/
|
||||
logCache.push([method].concat(arguments));
|
||||
if(logCache.length > 50) {
|
||||
// keep the cache size 50 or lower
|
||||
logCache.pop();
|
||||
}
|
||||
|
||||
if (original.apply){
|
||||
// Do this for normal browsers
|
||||
original.apply(console, arguments)
|
||||
}else{
|
||||
// Do this for IE
|
||||
var message = Array.prototype.slice.apply(arguments).join(' ')
|
||||
original(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
var methods = ['log', 'warn', 'error']
|
||||
for (var i = 0; i < methods.length; i++)
|
||||
intercept(methods[i])
|
||||
}
|
||||
|
||||
takeOverConsole();
|
||||
|
||||
context.JK.logger = context.console;
|
||||
context.JK.logger.logCache = logCache;
|
||||
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -14,15 +14,22 @@
|
|||
|
||||
context.JK.JamServer = function (app) {
|
||||
|
||||
// uniquely identify the websocket connection
|
||||
var channelId = null;
|
||||
var clientType = null;
|
||||
|
||||
// heartbeat
|
||||
var heartbeatInterval = null;
|
||||
var heartbeatMS = null;
|
||||
var heartbeatMissedMS = 10000; // if 5 seconds go by and we haven't seen a heartbeat ack, get upset
|
||||
var connection_expire_time = null;
|
||||
var lastHeartbeatSentTime = null;
|
||||
var lastHeartbeatAckTime = null;
|
||||
var lastHeartbeatFound = false;
|
||||
var lastDisconnectedReason = null;
|
||||
var heartbeatAckCheckInterval = null;
|
||||
var notificationLastSeenAt = undefined;
|
||||
var notificationLastSeen = undefined;
|
||||
var clientClosedConnection = false;
|
||||
|
||||
// reconnection logic
|
||||
var connectDeferred = null;
|
||||
|
|
@ -53,17 +60,23 @@
|
|||
server.connected = false;
|
||||
|
||||
|
||||
function heartbeatStateReset() {
|
||||
lastHeartbeatSentTime = null;
|
||||
lastHeartbeatAckTime = null;
|
||||
lastHeartbeatFound = false;
|
||||
}
|
||||
|
||||
// if activeElementVotes is null, then we are assuming this is the initial connect sequence
|
||||
function initiateReconnect(activeElementVotes, in_error) {
|
||||
var initialConnect = !!activeElementVotes;
|
||||
|
||||
freezeInteraction = activeElementVotes && ((activeElementVotes.dialog && activeElementVotes.dialog.freezeInteraction === true) || (activeElementVotes.screen && activeElementVotes.screen.freezeInteraction === true));
|
||||
|
||||
if(!initialConnect) {
|
||||
if (!initialConnect) {
|
||||
context.JK.CurrentSessionModel.onWebsocketDisconnected(in_error);
|
||||
}
|
||||
|
||||
if(in_error) {
|
||||
if (in_error) {
|
||||
reconnectAttempt = 0;
|
||||
$currentDisplay = renderDisconnected();
|
||||
beginReconnectPeriod();
|
||||
|
|
@ -87,7 +100,7 @@
|
|||
|
||||
if (server.connected) {
|
||||
server.connected = false;
|
||||
if(app.clientUpdating) {
|
||||
if (app.clientUpdating) {
|
||||
// we don't want to do a 'cover the whole screen' dialog
|
||||
// because the client update is already showing.
|
||||
return;
|
||||
|
|
@ -126,8 +139,9 @@
|
|||
|
||||
// check if the server is still sending heartbeat acks back down
|
||||
// this logic equates to 'if we have not received a heartbeat within heartbeatMissedMS, then get upset
|
||||
if (new Date().getTime() - lastHeartbeatAckTime.getTime() > heartbeatMissedMS) {
|
||||
logger.error("no heartbeat ack received from server after ", heartbeatMissedMS, " seconds . giving up on socket connection");
|
||||
if (new Date().getTime() - lastHeartbeatAckTime.getTime() > connection_expire_time) {
|
||||
logger.error("no heartbeat ack received from server after ", connection_expire_time, " seconds . giving up on socket connection");
|
||||
lastDisconnectedReason = 'NO_HEARTBEAT_ACK';
|
||||
context.JK.JamServer.close(true);
|
||||
}
|
||||
else {
|
||||
|
|
@ -140,6 +154,16 @@
|
|||
var message = context.JK.MessageFactory.heartbeat(notificationLastSeen, notificationLastSeenAt);
|
||||
notificationLastSeenAt = undefined;
|
||||
notificationLastSeen = undefined;
|
||||
// for debugging purposes, see if the last time we've sent a heartbeat is way off (500ms) of the target interval
|
||||
var now = new Date();
|
||||
|
||||
if (lastHeartbeatSentTime) {
|
||||
var drift = new Date().getTime() - lastHeartbeatSentTime.getTime() - heartbeatMS;
|
||||
if (drift > 500) {
|
||||
logger.error("significant drift between heartbeats: " + drift + 'ms beyond target interval')
|
||||
}
|
||||
}
|
||||
lastHeartbeatSentTime = now;
|
||||
context.JK.JamServer.send(message);
|
||||
lastHeartbeatFound = false;
|
||||
}
|
||||
|
|
@ -147,11 +171,13 @@
|
|||
|
||||
function loggedIn(header, payload) {
|
||||
|
||||
if(!connectTimeout) {
|
||||
if (!connectTimeout) {
|
||||
clearTimeout(connectTimeout);
|
||||
connectTimeout = null;
|
||||
}
|
||||
|
||||
heartbeatStateReset();
|
||||
|
||||
app.clientId = payload.client_id;
|
||||
|
||||
// tell the backend that we have logged in
|
||||
|
|
@ -159,12 +185,13 @@
|
|||
|
||||
$.cookie('client_id', payload.client_id);
|
||||
|
||||
|
||||
heartbeatMS = payload.heartbeat_interval * 1000;
|
||||
logger.debug("jamkazam.js.loggedIn(): clientId now " + app.clientId + "; Setting up heartbeat every " + heartbeatMS + " MS");
|
||||
connection_expire_time = payload.connection_expire_time * 1000;
|
||||
logger.debug("jamkazam.js.loggedIn(): clientId=" + app.clientId + ", heartbeat=" + payload.heartbeat_interval + "s, expire_time=" + payload.connection_expire_time + 's');
|
||||
heartbeatInterval = context.setInterval(_heartbeat, heartbeatMS);
|
||||
heartbeatAckCheckInterval = context.setInterval(_heartbeatAckCheck, 1000);
|
||||
lastHeartbeatAckTime = new Date(new Date().getTime() + heartbeatMS); // add a little forgiveness to server for initial heartbeat
|
||||
|
||||
connectDeferred.resolve();
|
||||
app.activeElementEvent('afterConnect', payload);
|
||||
|
||||
|
|
@ -209,10 +236,10 @@
|
|||
function internetUp() {
|
||||
var start = new Date().getTime();
|
||||
server.connect()
|
||||
.done(function() {
|
||||
.done(function () {
|
||||
guardAgainstRapidTransition(start, performReconnect);
|
||||
})
|
||||
.fail(function() {
|
||||
.fail(function () {
|
||||
guardAgainstRapidTransition(start, closedOnReconnectAttempt);
|
||||
});
|
||||
}
|
||||
|
|
@ -224,18 +251,37 @@
|
|||
|
||||
function performReconnect() {
|
||||
|
||||
if($currentDisplay.is('.no-websocket-connection')) {
|
||||
$currentDisplay.hide();
|
||||
if(!clientClosedConnection) {
|
||||
lastDisconnectedReason = 'WEBSOCKET_CLOSED_REMOTELY'
|
||||
clientClosedConnection = false;
|
||||
}
|
||||
else if(!lastDisconnectedReason) {
|
||||
// let's have at least some sort of type, however generci
|
||||
lastDisconnectedReason = 'WEBSOCKET_CLOSED_LOCALLY'
|
||||
}
|
||||
|
||||
rest.createDiagnostic({
|
||||
type: lastDisconnectedReason,
|
||||
data: {logs: logger.logCache, client_type: clientType, client_id: server.clientID, channel_id: channelId}
|
||||
})
|
||||
.always(function() {
|
||||
if ($currentDisplay.is('.no-websocket-connection')) {
|
||||
// this path is the 'not in session path'; so there is nothing else to do
|
||||
$currentDisplay.hide();
|
||||
|
||||
// TODO: tell certain elements that we've reconnected
|
||||
}
|
||||
else {
|
||||
// this path is the 'in session' path, where we actually reload the page
|
||||
context.JK.CurrentSessionModel.leaveCurrentSession()
|
||||
.always(function () {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
server.reconnecting = false;
|
||||
});
|
||||
|
||||
|
||||
// TODO: tell certain elements that we've reconnected
|
||||
}
|
||||
else {
|
||||
context.JK.CurrentSessionModel.leaveCurrentSession()
|
||||
.always(function() {
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
server.reconnecting = false;
|
||||
}
|
||||
|
||||
function buildOptions() {
|
||||
|
|
@ -245,14 +291,14 @@
|
|||
function renderDisconnected() {
|
||||
|
||||
var content = null;
|
||||
if(freezeInteraction) {
|
||||
if (freezeInteraction) {
|
||||
var template = $templateDisconnected.html();
|
||||
var templateHtml = $(context.JK.fillTemplate(template, buildOptions()));
|
||||
templateHtml.find('.reconnect-countdown').html(formatDelaySecs(reconnectDelaySecs()));
|
||||
content = context.JK.Banner.show({
|
||||
html : templateHtml,
|
||||
html: templateHtml,
|
||||
type: 'reconnect'
|
||||
}) ;
|
||||
});
|
||||
}
|
||||
else {
|
||||
var $inSituContent = $(context._.template($templateServerConnection.html(), buildOptions(), { variable: 'data' }));
|
||||
|
|
@ -267,7 +313,7 @@
|
|||
}
|
||||
|
||||
function formatDelaySecs(secs) {
|
||||
return $('<span class="countdown-seconds"><span class="countdown">' + secs + '</span> ' + (secs == 1 ? ' second.<span style="visibility:hidden">s</span>' : 'seconds.') + '</span>');
|
||||
return $('<span class="countdown-seconds"><span class="countdown">' + secs + '</span> ' + (secs == 1 ? ' second.<span style="visibility:hidden">s</span>' : 'seconds.') + '</span>');
|
||||
}
|
||||
|
||||
function setCountdown($parent) {
|
||||
|
|
@ -281,7 +327,7 @@
|
|||
function renderReconnecting() {
|
||||
$currentDisplay.find('.reconnect-progress-msg').text('Attempting to reconnect...')
|
||||
|
||||
if($currentDisplay.is('.no-websocket-connection')) {
|
||||
if ($currentDisplay.is('.no-websocket-connection')) {
|
||||
$currentDisplay.find('.disconnected-reconnect').removeClass('reconnect-enabled').addClass('reconnect-disabled');
|
||||
}
|
||||
else {
|
||||
|
|
@ -299,7 +345,7 @@
|
|||
var now = new Date().getTime();
|
||||
|
||||
if ((now - start) < 1500) {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
nextStep();
|
||||
}, 1500 - (now - start))
|
||||
}
|
||||
|
|
@ -315,12 +361,12 @@
|
|||
renderReconnecting();
|
||||
|
||||
rest.serverHealthCheck()
|
||||
.done(function() {
|
||||
.done(function () {
|
||||
guardAgainstRapidTransition(start, internetUp);
|
||||
})
|
||||
.fail(function(xhr, textStatus, errorThrown) {
|
||||
.fail(function (xhr, textStatus, errorThrown) {
|
||||
|
||||
if(xhr && xhr.status >= 100) {
|
||||
if (xhr && xhr.status >= 100) {
|
||||
// we could connect to the server, and it's alive
|
||||
guardAgainstRapidTransition(start, internetUp);
|
||||
}
|
||||
|
|
@ -333,7 +379,7 @@
|
|||
}
|
||||
|
||||
function clearReconnectTimers() {
|
||||
if(countdownInterval) {
|
||||
if (countdownInterval) {
|
||||
clearInterval(countdownInterval);
|
||||
countdownInterval = null;
|
||||
}
|
||||
|
|
@ -341,8 +387,8 @@
|
|||
|
||||
function beginReconnectPeriod() {
|
||||
// allow user to force reconnect
|
||||
$currentDisplay.find('a.disconnected-reconnect').unbind('click').click(function() {
|
||||
if($(this).is('.button-orange') || $(this).is('.reconnect-enabled')) {
|
||||
$currentDisplay.find('a.disconnected-reconnect').unbind('click').click(function () {
|
||||
if ($(this).is('.button-orange') || $(this).is('.reconnect-enabled')) {
|
||||
clearReconnectTimers();
|
||||
attemptReconnect();
|
||||
}
|
||||
|
|
@ -353,9 +399,9 @@
|
|||
reconnectDueTime = reconnectingWaitPeriodStart + reconnectDelaySecs() * 1000;
|
||||
|
||||
// update count down timer periodically
|
||||
countdownInterval = setInterval(function() {
|
||||
countdownInterval = setInterval(function () {
|
||||
var now = new Date().getTime();
|
||||
if(now > reconnectDueTime) {
|
||||
if (now > reconnectDueTime) {
|
||||
clearReconnectTimers();
|
||||
attemptReconnect();
|
||||
}
|
||||
|
|
@ -404,9 +450,14 @@
|
|||
};
|
||||
|
||||
server.connect = function () {
|
||||
if(!clientType) {
|
||||
clientType = context.JK.clientType();
|
||||
}
|
||||
connectDeferred = new $.Deferred();
|
||||
logger.log("server.connect");
|
||||
var uri = context.JK.websocket_gateway_uri; // Set in index.html.erb.
|
||||
channelId = context.JK.generateUUID(); // create a new channel ID for every websocket connection
|
||||
logger.log("connecting websocket, channel_id: " + channelId);
|
||||
|
||||
var uri = context.JK.websocket_gateway_uri + '?channel_id=' + channelId; // Set in index.html.erb.
|
||||
//var uri = context.gon.websocket_gateway_uri; // Leaving here for now, as we're looking for a better solution.
|
||||
|
||||
server.socket = new context.WebSocket(uri);
|
||||
|
|
@ -414,9 +465,10 @@
|
|||
server.socket.onmessage = server.onMessage;
|
||||
server.socket.onclose = server.onClose;
|
||||
|
||||
connectTimeout = setTimeout(function() {
|
||||
connectTimeout = setTimeout(function () {
|
||||
connectTimeout = null;
|
||||
if(connectDeferred.state() === 'pending') {
|
||||
if (connectDeferred.state() === 'pending') {
|
||||
server.close(true);
|
||||
connectDeferred.reject();
|
||||
}
|
||||
}, 4000);
|
||||
|
|
@ -427,6 +479,7 @@
|
|||
server.close = function (in_error) {
|
||||
logger.log("closing websocket");
|
||||
|
||||
clientClosedConnection = true;
|
||||
server.socket.close();
|
||||
|
||||
closedCleanup(in_error);
|
||||
|
|
@ -435,7 +488,7 @@
|
|||
server.rememberLogin = function () {
|
||||
var token, loginMessage;
|
||||
token = $.cookie("remember_token");
|
||||
var clientType = context.jamClient.IsNativeClient() ? 'client' : 'browser';
|
||||
|
||||
loginMessage = msg_factory.login_with_token(token, null, clientType);
|
||||
server.send(loginMessage);
|
||||
};
|
||||
|
|
@ -471,10 +524,11 @@
|
|||
}
|
||||
};
|
||||
|
||||
// onClose is called if either client or server closes connection
|
||||
server.onClose = function () {
|
||||
logger.log("Socket to server closed.");
|
||||
|
||||
if(connectDeferred.state() === "pending") {
|
||||
if (connectDeferred.state() === "pending") {
|
||||
connectDeferred.reject();
|
||||
}
|
||||
|
||||
|
|
@ -521,19 +575,19 @@
|
|||
//console.timeEnd('sendP2PMessage');
|
||||
};
|
||||
|
||||
server.updateNotificationSeen = function(notificationId, notificationCreatedAt) {
|
||||
server.updateNotificationSeen = function (notificationId, notificationCreatedAt) {
|
||||
var time = new Date(notificationCreatedAt);
|
||||
|
||||
if(!notificationCreatedAt) {
|
||||
if (!notificationCreatedAt) {
|
||||
throw 'invalid value passed to updateNotificationSeen'
|
||||
}
|
||||
|
||||
if(!notificationLastSeenAt) {
|
||||
if (!notificationLastSeenAt) {
|
||||
notificationLastSeenAt = notificationCreatedAt;
|
||||
notificationLastSeen = notificationId;
|
||||
logger.debug("updated notificationLastSeenAt with: " + notificationCreatedAt);
|
||||
}
|
||||
else if(time.getTime() > new Date(notificationLastSeenAt).getTime()) {
|
||||
else if (time.getTime() > new Date(notificationLastSeenAt).getTime()) {
|
||||
notificationLastSeenAt = notificationCreatedAt;
|
||||
notificationLastSeen = notificationId;
|
||||
logger.debug("updated notificationLastSeenAt with: " + notificationCreatedAt);
|
||||
|
|
@ -573,6 +627,7 @@
|
|||
}
|
||||
|
||||
function initialize() {
|
||||
|
||||
registerLoginAck();
|
||||
registerHeartbeatAck();
|
||||
registerSocketClosed();
|
||||
|
|
@ -584,12 +639,24 @@
|
|||
$templateServerConnection = $('#template-server-connection');
|
||||
$templateDisconnected = $('#template-disconnected');
|
||||
|
||||
if($inSituBanner.length != 1) { throw "found wrong number of .server-connection: " + $inSituBanner.length; }
|
||||
if($inSituBannerHolder.length != 1) { throw "found wrong number of .no-websocket-connection: " + $inSituBannerHolder.length; }
|
||||
if($messageContents.length != 1) { throw "found wrong number of .message-contents: " + $messageContents.length; }
|
||||
if($dialog.length != 1) { throw "found wrong number of #banner: " + $dialog.length; }
|
||||
if($templateServerConnection.length != 1) { throw "found wrong number of #template-server-connection: " + $templateServerConnection.length; }
|
||||
if($templateDisconnected.length != 1) { throw "found wrong number of #template-disconnected: " + $templateDisconnected.length; }
|
||||
if ($inSituBanner.length != 1) {
|
||||
throw "found wrong number of .server-connection: " + $inSituBanner.length;
|
||||
}
|
||||
if ($inSituBannerHolder.length != 1) {
|
||||
throw "found wrong number of .no-websocket-connection: " + $inSituBannerHolder.length;
|
||||
}
|
||||
if ($messageContents.length != 1) {
|
||||
throw "found wrong number of .message-contents: " + $messageContents.length;
|
||||
}
|
||||
if ($dialog.length != 1) {
|
||||
throw "found wrong number of #banner: " + $dialog.length;
|
||||
}
|
||||
if ($templateServerConnection.length != 1) {
|
||||
throw "found wrong number of #template-server-connection: " + $templateServerConnection.length;
|
||||
}
|
||||
if ($templateDisconnected.length != 1) {
|
||||
throw "found wrong number of #template-disconnected: " + $templateDisconnected.length;
|
||||
}
|
||||
}
|
||||
|
||||
this.initialize = initialize;
|
||||
|
|
|
|||
|
|
@ -7,18 +7,8 @@
|
|||
var logger = context.JK.logger;
|
||||
var myTrackCount;
|
||||
|
||||
var ASSIGNMENT = {
|
||||
CHAT: -2,
|
||||
OUTPUT: -1,
|
||||
UNASSIGNED: 0,
|
||||
TRACK1: 1,
|
||||
TRACK2: 2
|
||||
};
|
||||
|
||||
var VOICE_CHAT = {
|
||||
NO_CHAT: "0",
|
||||
CHAT: "1"
|
||||
};
|
||||
var ASSIGNMENT = context.JK.ASSIGNMENT;
|
||||
var VOICE_CHAT = context.JK.VOICE_CHAT;
|
||||
|
||||
var instrument_array = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -179,51 +179,42 @@
|
|||
// Defaulting to 1st instrument in profile always at the moment.
|
||||
data.tracks = tracks;
|
||||
|
||||
var jsonData = JSON.stringify(data);
|
||||
|
||||
$('#btn-create-session').addClass('button-disabled');
|
||||
$('#btn-create-session').bind('click', false);
|
||||
|
||||
var url = "/api/sessions";
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: url,
|
||||
processData:false,
|
||||
data: jsonData,
|
||||
success: function(response) {
|
||||
var newSessionId = response.id;
|
||||
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
|
||||
context.location = '/client#/session/' + newSessionId;
|
||||
});
|
||||
// Re-loading the session settings will cause the form to reset with the right stuff in it.
|
||||
// This is an extra xhr call, but it keeps things to a single codepath
|
||||
loadSessionSettings();
|
||||
$('#btn-create-session').removeClass('button-disabled');
|
||||
$('#btn-create-session').unbind('click', false);
|
||||
rest.legacyCreateSession(data)
|
||||
.done(function(response) {
|
||||
var newSessionId = response.id;
|
||||
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
|
||||
context.location = '/client#/session/' + newSessionId;
|
||||
});
|
||||
// Re-loading the session settings will cause the form to reset with the right stuff in it.
|
||||
// This is an extra xhr call, but it keeps things to a single codepath
|
||||
loadSessionSettings();
|
||||
$('#btn-create-session').removeClass('button-disabled');
|
||||
$('#btn-create-session').unbind('click', false);
|
||||
|
||||
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);
|
||||
|
||||
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
|
||||
},
|
||||
error: function(jqXHR) {
|
||||
var handled = false;
|
||||
if(jqXHR.status = 422) {
|
||||
var response = JSON.parse(jqXHR.responseText);
|
||||
if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
|
||||
app.notifyAlert("No Inputs Configured", $('<span>You will need to reconfigure your audio device.</span>'));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
if(!handled) {
|
||||
app.notifyServerError(jqXHR, "Unable to Create Session");
|
||||
}
|
||||
$('#btn-create-session').removeClass('button-disabled');
|
||||
$('#btn-create-session').unbind('click', false);
|
||||
context.JK.GA.trackSessionCount(data.musician_access, data.fan_access, invitationCount);
|
||||
|
||||
context.JK.GA.trackSessionMusicians(context.JK.GA.SessionCreationTypes.create);
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
var handled = false;
|
||||
if(jqXHR.status = 422) {
|
||||
var response = JSON.parse(jqXHR.responseText);
|
||||
if(response["errors"] && response["errors"]["tracks"] && response["errors"]["tracks"][0] == "Please select at least one track") {
|
||||
app.notifyAlert("No Inputs Configured", $('<span>You will need to reconfigure your audio device.</span>'));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(!handled) {
|
||||
app.notifyServerError(jqXHR, "Unable to Create Session");
|
||||
}
|
||||
$('#btn-create-session').removeClass('button-disabled');
|
||||
$('#btn-create-session').unbind('click', false);
|
||||
|
||||
})
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@
|
|||
function renderFeeds(feeds) {
|
||||
|
||||
$.each(feeds.entries, function(i, feed) {
|
||||
if(feed.type == 'music_session_history') {
|
||||
if(feed.type == 'music_session') {
|
||||
var options = {
|
||||
feed_item: feed,
|
||||
status_class: feed['is_over?'] ? 'ended' : 'inprogress',
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@
|
|||
join : "Join"
|
||||
};
|
||||
|
||||
var sessionQualityTypes = {
|
||||
good : "Good",
|
||||
poor : "Poor"
|
||||
};
|
||||
|
||||
var invitationTypes = {
|
||||
email : "Email",
|
||||
facebook : "Facebook",
|
||||
|
|
@ -83,6 +88,7 @@
|
|||
audioTest : "AudioTest",
|
||||
sessionCount : "SessionCount",
|
||||
sessionMusicians : "SessionMusicians",
|
||||
sessionQuality : "SessionQuality",
|
||||
invite : "Invite",
|
||||
findSession : "FindSession",
|
||||
friendConnect : "Connect",
|
||||
|
|
@ -174,6 +180,11 @@
|
|||
context.ga('send', 'event', categories.sessionMusicians, joinOrCreate);
|
||||
}
|
||||
|
||||
function trackSessionQuality(goodOrPoor) {
|
||||
assertOneOf(goodOrPoor, sessionQualityTypes);
|
||||
context.ga('send', 'event', categories.sessionQuality, goodOrPoor);
|
||||
}
|
||||
|
||||
function trackServiceInvitations(invitationType, numInvited) {
|
||||
assertOneOf(invitationType, invitationTypes);
|
||||
assertNumber(numInvited);
|
||||
|
|
@ -271,6 +282,7 @@
|
|||
var GA = {};
|
||||
GA.Categories = categories;
|
||||
GA.SessionCreationTypes = sessionCreationTypes;
|
||||
GA.SessionQualityTypes = sessionQualityTypes;
|
||||
GA.InvitationTypes = invitationTypes;
|
||||
GA.FriendConnectTypes = friendConnectTypes;
|
||||
GA.RecordingActions = recordingActions;
|
||||
|
|
@ -281,6 +293,7 @@
|
|||
GA.trackFTUECompletion = trackFTUECompletion;
|
||||
GA.trackSessionCount = trackSessionCount;
|
||||
GA.trackSessionMusicians = trackSessionMusicians;
|
||||
GA.trackSessionQuality = trackSessionQuality;
|
||||
GA.trackServiceInvitations = trackServiceInvitations;
|
||||
GA.trackFindSessions = trackFindSessions;
|
||||
GA.virtualPageView = virtualPageView;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
context.JK = context.JK || {};
|
||||
context.JK.GearWizard = function (app) {
|
||||
|
||||
var ASSIGNMENT = context.JK.ASSIGNMENT;
|
||||
var VOICE_CHAT = context.JK.VOICE_CHAT;
|
||||
|
||||
var $dialog = null;
|
||||
var $wizardSteps = null;
|
||||
|
|
@ -20,11 +22,11 @@
|
|||
|
||||
// populated by loadDevices
|
||||
var deviceInformation = null;
|
||||
var musicInputPorts = null;
|
||||
var musicOutputPorts = null;
|
||||
var musicPorts = null;
|
||||
|
||||
// SELECT DEVICE STATE
|
||||
var validScore = false;
|
||||
|
||||
var validLatencyScore = false;
|
||||
var validIOScore = false;
|
||||
|
||||
// SELECT TRACKS STATE
|
||||
|
||||
|
|
@ -46,7 +48,7 @@
|
|||
display: 'MacOSX Built-In',
|
||||
videoURL: undefined
|
||||
},
|
||||
MACOSX_interface: {
|
||||
MacOSX_interface: {
|
||||
display: 'MacOSX external interface',
|
||||
videoURL: undefined
|
||||
},
|
||||
|
|
@ -86,13 +88,19 @@
|
|||
var $bufferIn = $currentWizardStep.find('.select-buffer-in');
|
||||
var $bufferOut = $currentWizardStep.find('.select-buffer-out');
|
||||
var $frameSize = $currentWizardStep.find('.select-frame-size');
|
||||
var $inputPorts = $currentWizardStep.find('.input-ports');
|
||||
var $outputPorts = $currentWizardStep.find('.output-ports');
|
||||
var $inputChannels = $currentWizardStep.find('.input-ports');
|
||||
var $outputChannels = $currentWizardStep.find('.output-ports');
|
||||
var $scoreReport = $currentWizardStep.find('.results');
|
||||
var $latencyScoreSection = $scoreReport.find('.latency-score-section');
|
||||
var $latencyScore = $scoreReport.find('.latency-score');
|
||||
var $ioScoreSection = $scoreReport.find('.io-score-section');
|
||||
var $ioRateScore = $scoreReport.find('.io-rate-score');
|
||||
var $ioVarScore = $scoreReport.find('.io-var-score');
|
||||
var $ioCountdown = $scoreReport.find('.io-countdown');
|
||||
var $ioCountdownSecs = $scoreReport.find('.io-countdown .secs');
|
||||
var $nextButton = $ftueButtons.find('.btn-next');
|
||||
var $asioControlPanelBtn = $currentWizardStep.find('.asio-settings-btn');
|
||||
var $resyncBtn = $currentWizardStep.find('resync-btn')
|
||||
|
||||
// should return one of:
|
||||
// * MacOSX_builtin
|
||||
|
|
@ -126,22 +134,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function loadDevices() {
|
||||
var devices = context.jamClient.FTUEGetDevices(false);
|
||||
|
||||
var oldDevices = context.jamClient.FTUEGetDevices(false);
|
||||
var devices = context.jamClient.FTUEGetAudioDevices();
|
||||
console.log("oldDevices: " + JSON.stringify(oldDevices));
|
||||
console.log("devices: " + JSON.stringify(devices));
|
||||
|
||||
var loadedDevices = {};
|
||||
|
||||
// augment these devices by determining their type
|
||||
context._.each(devices, function (displayName, deviceId) {
|
||||
context._.each(devices.devices, function (device) {
|
||||
|
||||
if(device.name == "JamKazam Virtual Monitor") {
|
||||
return;
|
||||
}
|
||||
|
||||
var deviceInfo = {};
|
||||
|
||||
deviceInfo.id = deviceId;
|
||||
deviceInfo.type = determineDeviceType(deviceId, displayName);
|
||||
deviceInfo.id = device.guid;
|
||||
deviceInfo.type = determineDeviceType(device.guid, device.display_name);
|
||||
console.log("deviceInfo.type: " + deviceInfo.type)
|
||||
deviceInfo.displayType = audioDeviceBehavior[deviceInfo.type].display;
|
||||
deviceInfo.displayName = displayName;
|
||||
deviceInfo.displayName = device.display_name;
|
||||
|
||||
loadedDevices[deviceId] = deviceInfo;
|
||||
loadedDevices[device.guid] = deviceInfo;
|
||||
|
||||
logger.debug("loaded device: ", deviceInfo);
|
||||
})
|
||||
|
|
@ -179,7 +196,7 @@
|
|||
function initializeNextButtonState() {
|
||||
$nextButton.removeClass('button-orange button-grey');
|
||||
|
||||
if (validScore) $nextButton.addClass('button-orange');
|
||||
if (validLatencyScore) $nextButton.addClass('button-orange');
|
||||
else $nextButton.addClass('button-grey');
|
||||
}
|
||||
|
||||
|
|
@ -218,71 +235,66 @@
|
|||
context.JK.dropdown($bufferOut);
|
||||
}
|
||||
|
||||
// finds out if the $port argument is from a different port pair than what's currently selected
|
||||
function isNewlySelectedPair($port) {
|
||||
var portId = $port.attr('data-id');
|
||||
// get all inputs currently selected except this one
|
||||
var $selectedInputs = $inputPorts.find('input[type="checkbox"]:checked').filter('[data-id="' + portId + '"]');
|
||||
|
||||
console.log("$selectedInputs", $selectedInputs);
|
||||
var isNewlySelected = true;
|
||||
context._.each($selectedInputs, function($current) {
|
||||
var testPairInfo = $($current).data('pair');
|
||||
// reloads the backend's channel state for the currently selected audio devices,
|
||||
// and update's the UI accordingly
|
||||
function initializeChannels() {
|
||||
musicPorts = jamClient.FTUEGetChannels();
|
||||
console.log("musicPorts: %o", JSON.stringify(musicPorts));
|
||||
|
||||
context._.each(testPairInfo.ports, function(port) {
|
||||
// if we can find the newly selected item in this pair, then it's not a different pair...
|
||||
if(port.id == portId) {
|
||||
isNewlySelected = false;
|
||||
return false; // break loop
|
||||
}
|
||||
});
|
||||
initializeInputPorts(musicPorts);
|
||||
initializeOutputPorts(musicPorts);
|
||||
}
|
||||
|
||||
if(isNewlySelected) return false; // break loop
|
||||
// during this phase of the FTUE, we have to assign selected input channels
|
||||
// to tracks. The user, however, does not have a way to indicate which channel
|
||||
// goes to which track (that's not until the next step of the wizard).
|
||||
// so, we just auto-generate a valid assignment
|
||||
function newInputAssignment() {
|
||||
var assigned = 0;
|
||||
context._.each(musicPorts.inputs, function(inputChannel) {
|
||||
if(isChannelAssigned(inputChannel)) {
|
||||
assigned += 1;
|
||||
}
|
||||
});
|
||||
|
||||
return isNewlySelected;
|
||||
var newAssignment = Math.floor(assigned / 2) + 1;
|
||||
return newAssignment;
|
||||
}
|
||||
|
||||
// set checkbox state for all items in the pair
|
||||
function setCheckedForAllInPair($portBox, pairInfo, checked, signalBackend) {
|
||||
context._.each(pairInfo.ports, function(port) {
|
||||
var portId = port.id;
|
||||
var $input = $portBox.find('input[type="checkbox"][data-id="' + portId + '"]');
|
||||
if($input.is(':checked') != checked) {
|
||||
if(checked) {
|
||||
$input.iCheck('check').attr('checked', 'checked');
|
||||
//context.jamClient.FTUESetMusicInput2($input.id);
|
||||
}
|
||||
else {
|
||||
$input.iCheck('uncheck').removeAttr('checked');
|
||||
//context.jamClient.FTUEUnsetMusicInput2($input.id);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function inputPortChanged() {
|
||||
function inputChannelChanged() {
|
||||
if(iCheckIgnore) return;
|
||||
|
||||
var $checkbox = $(this);
|
||||
var portId = $checkbox.data('data-id');
|
||||
var inputPortChecked = $checkbox.is(':checked');
|
||||
console.log('inputPortChecked: ' + inputPortChecked);
|
||||
var channelId = $checkbox.attr('data-id');
|
||||
var isChecked = $checkbox.is(':checked');
|
||||
|
||||
if(inputPortChecked) {
|
||||
if(isNewlySelectedPair($checkbox)) {
|
||||
setCheckedForAllInPair($inputPorts, $checkbox.data('pair'), true, true);
|
||||
}
|
||||
else {
|
||||
//context.jamClient.FTUESetMusicInput2($input.id);
|
||||
}
|
||||
if(isChecked) {
|
||||
var newAssignment = newInputAssignment();
|
||||
logger.debug("assigning input channel %o to track: %o", channelId, newAssignment);
|
||||
context.jamClient.TrackSetAssignment(channelId, true, newAssignment);
|
||||
}
|
||||
else {
|
||||
// context.jamClient.FTUEUnsetMusicInput2($input.id);;
|
||||
logger.debug("unassigning input channel %o", channelId);
|
||||
context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.UNASSIGNED);
|
||||
// unassigning creates a hole in our auto-assigned tracks. reassign them all to keep it consistent
|
||||
var $assignedInputs = $inputChannels.find('input[type="checkbox"]:checked');
|
||||
var assigned = 0;
|
||||
context._.each($assignedInputs, function(assignedInput) {
|
||||
var $assignedInput = $(assignedInput);
|
||||
var assignedChannelId = $assignedInput.attr('data-id');
|
||||
var newAssignment = Math.floor(assigned / 2) + 1;
|
||||
logger.debug("re-assigning input channel %o to track: %o", assignedChannelId, newAssignment);
|
||||
context.jamClient.TrackSetAssignment(assignedChannelId, true, newAssignment);
|
||||
assigned += 1;
|
||||
});
|
||||
}
|
||||
|
||||
initializeChannels();
|
||||
}
|
||||
|
||||
// should be called in a ifChanged callback if you want to cancel. bleh.
|
||||
// should be called in a ifChanged callback if you want to cancel.
|
||||
// you have to use this instead of 'return false' like a typical input 'change' event.
|
||||
function cancelICheckChange($checkbox) {
|
||||
iCheckIgnore = true;
|
||||
var checked = $checkbox.is(':checked');
|
||||
|
|
@ -293,58 +305,64 @@
|
|||
}, 1);
|
||||
}
|
||||
|
||||
function outputPortChanged() {
|
||||
function outputChannelChanged() {
|
||||
if(iCheckIgnore) return;
|
||||
|
||||
var $checkbox = $(this);
|
||||
var portId = $checkbox.data('data-id');
|
||||
var outputPortChecked = $checkbox.is(':checked');
|
||||
console.log('outputPortChecked: ' + outputPortChecked);
|
||||
var channelId = $checkbox.attr('data-id');
|
||||
var isChecked = $checkbox.is(':checked');
|
||||
|
||||
if(outputPortChecked) {
|
||||
var $selectedInputs = $outputPorts.find('input[type="checkbox"]:checked').filter('[data-id="' + portId + '"]');
|
||||
$selectedInputs.iCheck('uncheck').removeAttr('checked');
|
||||
var pairInfo = $checkbox.data('pair');
|
||||
setCheckedForAllInPair($outputPorts, pairInfo, true, false);
|
||||
console.log("Setting music output");
|
||||
context.jamClient.FTUESetMusicOutput(pairInfo.ports.map(function(i) {return i.id}).join(PROFILE_DEV_SEP_TOKEN));
|
||||
}
|
||||
else {
|
||||
context.JK.Banner.showAlert('You must have at least one output pair selected.');
|
||||
// don't allow more than 2 output channels selected at once
|
||||
if($outputChannels.find('input[type="checkbox"]:checked').length > 2) {
|
||||
context.JK.Banner.showAlert('You can only have a maximum of 2 output ports selected.');
|
||||
// can't allow uncheck of last output
|
||||
cancelICheckChange($checkbox);
|
||||
return;
|
||||
}
|
||||
|
||||
if(isChecked) {
|
||||
logger.debug("assigning output channel %o", channelId);
|
||||
context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.OUTPUT);
|
||||
}
|
||||
else {
|
||||
logger.debug("unassigning output channel %o", channelId);
|
||||
context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.UNASSIGNED);
|
||||
}
|
||||
|
||||
initializeChannels();
|
||||
}
|
||||
|
||||
function initializeInputPorts(inputPorts) {
|
||||
context._.each(inputPorts, function(inputPairs) {
|
||||
// there is no guarantee that a pair has two items.
|
||||
context._.each(inputPairs.ports, function(inputInPair) {
|
||||
var inputPort = $(context._.template($templateAudioPort.html(), inputInPair, { variable: 'data' }));
|
||||
var $checkbox = inputPort.find('input');
|
||||
$checkbox.data('pair', inputPairs); // so when it's selected, we can see what other ports, if any, are in the same pair
|
||||
context.JK.checkbox($checkbox);
|
||||
$checkbox.on('ifChanged', inputPortChanged);
|
||||
$inputPorts.append(inputPort);
|
||||
});
|
||||
// checks if it's an assigned OUTPUT or ASSIGNED CHAT
|
||||
function isChannelAssigned(channel) {
|
||||
return channel.assignment == ASSIGNMENT.CHAT || channel.assignment == ASSIGNMENT.OUTPUT || channel.assignment > 0;
|
||||
}
|
||||
|
||||
function initializeInputPorts(musicPorts) {
|
||||
$inputChannels.empty();
|
||||
var inputPorts = musicPorts.inputs;
|
||||
context._.each(inputPorts, function(inputChannel) {
|
||||
var $inputChannel = $(context._.template($templateAudioPort.html(), inputChannel, { variable: 'data' }));
|
||||
var $checkbox = $inputChannel.find('input');
|
||||
if(isChannelAssigned(inputChannel)) {
|
||||
$checkbox.attr('checked', 'checked');
|
||||
}
|
||||
context.JK.checkbox($checkbox);
|
||||
$checkbox.on('ifChanged', inputChannelChanged);
|
||||
$inputChannels.append($inputChannel);
|
||||
});
|
||||
}
|
||||
|
||||
function initializeOutputPorts(outputPorts) {
|
||||
var first = true;
|
||||
context._.each(outputPorts, function(outputPairs) {
|
||||
context._.each(outputPairs.ports, function(outputInPair) {
|
||||
var outputPort = $(context._.template($templateAudioPort.html(), outputInPair, { variable: 'data' }));
|
||||
var $checkbox = outputPort.find('input');
|
||||
$checkbox.data('pair', outputPairs); // so when it's selected, we can see what other ports, if any, are in the same pair
|
||||
context.JK.checkbox($checkbox);
|
||||
$checkbox.on('ifChanged', outputPortChanged);
|
||||
$outputPorts.append(outputPort);
|
||||
});
|
||||
if(first) {
|
||||
first = false;
|
||||
setCheckedForAllInPair($outputPorts, outputPairs, true, false);
|
||||
function initializeOutputPorts(musicPorts) {
|
||||
$outputChannels.empty();
|
||||
var outputChannels = musicPorts.outputs;
|
||||
context._.each(outputChannels, function(outputChannel) {
|
||||
var $outputPort = $(context._.template($templateAudioPort.html(), outputChannel, { variable: 'data' }));
|
||||
var $checkbox = $outputPort.find('input');
|
||||
if(isChannelAssigned(outputChannel)) {
|
||||
$checkbox.attr('checked', 'checked');
|
||||
}
|
||||
context.JK.checkbox($checkbox);
|
||||
$checkbox.on('ifChanged', outputChannelChanged);
|
||||
$outputChannels.append($outputPort);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -364,11 +382,11 @@
|
|||
}
|
||||
|
||||
function clearInputPorts() {
|
||||
$inputPorts.empty();
|
||||
$inputChannels.empty();
|
||||
}
|
||||
|
||||
function clearOutputPorts() {
|
||||
$outputPorts.empty();
|
||||
$outputChannels.empty();
|
||||
}
|
||||
|
||||
function resetScoreReport() {
|
||||
|
|
@ -377,6 +395,27 @@
|
|||
$latencyScore.empty();
|
||||
}
|
||||
|
||||
function renderLatencyScore(latencyValue, latencyClass) {
|
||||
if(latencyValue) {
|
||||
$latencyScore.text(latencyValue + ' ms');
|
||||
}
|
||||
else {
|
||||
$latencyScore.text('');
|
||||
}
|
||||
$latencyScoreSection.removeClass('good acceptable bad unknown starting').addClass(latencyClass);
|
||||
}
|
||||
|
||||
// std deviation is the worst value between in/out
|
||||
// media is the worst value between in/out
|
||||
// io is the value returned by the backend, which has more info
|
||||
// ioClass is the pre-computed rollup class describing the result in simple terms of 'good', 'acceptable', bad'
|
||||
function renderIOScore(std, median, ioData, ioClass) {
|
||||
$ioRateScore.text(median ? median : '');
|
||||
$ioVarScore.text(std ? std : '');
|
||||
$ioScoreSection.removeClass('good acceptable bad unknown starting skip').addClass(ioClass);
|
||||
// TODO: show help bubble of all data in IO data
|
||||
}
|
||||
|
||||
function updateScoreReport(latencyResult) {
|
||||
var latencyClass = "neutral";
|
||||
var latencyValue = 'N/A';
|
||||
|
|
@ -387,37 +426,69 @@
|
|||
if (latencyValue <= 10) {
|
||||
latencyClass = "good";
|
||||
validLatency = true;
|
||||
} else if (latency.latency <= 20) {
|
||||
} else if (latencyValue <= 20) {
|
||||
latencyClass = "acceptable";
|
||||
validLatency = true;
|
||||
} else {
|
||||
latencyClass = "bad";
|
||||
}
|
||||
}
|
||||
else {
|
||||
latencyClass = 'unknown';
|
||||
}
|
||||
|
||||
validScore = validLatency; // validScore may become based on IO variance too
|
||||
validLatencyScore = validLatency;
|
||||
|
||||
$latencyScore.html(latencyValue + ' ms');
|
||||
renderLatencyScore(latencyValue, latencyClass);
|
||||
}
|
||||
|
||||
function audioInputDeviceUnselected() {
|
||||
validScore = false;
|
||||
validLatencyScore = false;
|
||||
initializeNextButtonState();
|
||||
resetFrameBuffers();
|
||||
clearInputPorts();
|
||||
}
|
||||
|
||||
function renderScoringStarted() {
|
||||
validScore = false;
|
||||
validLatencyScore = false;
|
||||
initializeNextButtonState();
|
||||
resetScoreReport();
|
||||
freezeAudioInteraction();
|
||||
renderLatencyScore(null, 'starting');
|
||||
}
|
||||
|
||||
function renderScoringStopped() {
|
||||
initializeNextButtonState();
|
||||
unfreezeAudioInteraction();
|
||||
}
|
||||
|
||||
|
||||
function freezeAudioInteraction() {
|
||||
$audioInput.attr("disabled", "disabled").easyDropDown('disable');
|
||||
$audioOutput.attr("disabled", "disabled").easyDropDown('disable');
|
||||
$frameSize.attr("disabled", "disabled").easyDropDown('disable');
|
||||
$bufferIn.attr("disabled", "disabled").easyDropDown('disable');
|
||||
$bufferOut.attr("disabled", "disabled").easyDropDown('disable');
|
||||
$asioControlPanelBtn.on("click", false);
|
||||
$resyncBtn.on('click', false);
|
||||
iCheckIgnore = true;
|
||||
$inputChannels.find('input[type="checkbox"]').iCheck('disable');
|
||||
$outputChannels.find('input[type="checkbox"]').iCheck('disable');
|
||||
}
|
||||
|
||||
function unfreezeAudioInteraction() {
|
||||
$audioInput.removeAttr("disabled").easyDropDown('enable');
|
||||
$audioOutput.removeAttr("disabled").easyDropDown('enable');
|
||||
$frameSize.removeAttr("disabled").easyDropDown('enable');
|
||||
$bufferIn.removeAttr("disabled").easyDropDown('enable');
|
||||
$bufferOut.removeAttr("disabled").easyDropDown('enable');
|
||||
$asioControlPanelBtn.off("click", false);
|
||||
$resyncBtn.off('click', false);
|
||||
$inputChannels.find('input[type="checkbox"]').iCheck('enable');
|
||||
$outputChannels.find('input[type="checkbox"]').iCheck('enable');
|
||||
iCheckIgnore = false;
|
||||
}
|
||||
|
||||
// Given a latency structure, update the view.
|
||||
function newFtueUpdateLatencyView(latency) {
|
||||
var $report = $('.ftue-new .latency .report');
|
||||
|
|
@ -506,44 +577,52 @@
|
|||
});
|
||||
}
|
||||
|
||||
function initializeAudioInputChanged() {
|
||||
$audioInput.unbind('change').change(function (evt) {
|
||||
function renderIOScoringStarted(secondsLeft) {
|
||||
$ioCountdownSecs.text(secondsLeft);
|
||||
$ioCountdown.show();
|
||||
}
|
||||
|
||||
var audioDeviceId = selectedAudioInput();
|
||||
if (!audioDeviceId) {
|
||||
function renderIOScoringStopped() {
|
||||
$ioCountdown.hide();
|
||||
}
|
||||
|
||||
function renderIOCountdown(secondsLeft) {
|
||||
$ioCountdownSecs.text(secondsLeft);
|
||||
}
|
||||
|
||||
function attemptScore() {
|
||||
var audioInputDeviceId = selectedAudioInput();
|
||||
var audioOutputDeviceId = selectedAudioOutput();
|
||||
if (!audioInputDeviceId) {
|
||||
audioInputDeviceUnselected();
|
||||
return false;
|
||||
}
|
||||
|
||||
var audioDevice = findDevice(selectedAudioInput());
|
||||
if (!audioDevice) {
|
||||
context.JK.alertSupportedNeeded('Unable to find device information for: ' + audioDeviceId);
|
||||
var audioInputDevice = findDevice(audioInputDeviceId);
|
||||
if (!audioInputDevice) {
|
||||
context.JK.alertSupportedNeeded('Unable to find information for input device: ' + audioInputDeviceId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!audioOutputDeviceId) {
|
||||
audioOutputDeviceId = audioInputDeviceId;
|
||||
}
|
||||
var audioOutputDevice = findDevice(audioOutputDeviceId);
|
||||
if (!audioInputDevice) {
|
||||
context.JK.alertSupportedNeeded('Unable to find information for output device: ' + audioOutputDeviceId);
|
||||
return false;
|
||||
}
|
||||
|
||||
jamClient.FTUESetInputMusicDevice(audioInputDeviceId);
|
||||
jamClient.FTUESetOutputMusicDevice(audioOutputDeviceId);
|
||||
|
||||
renderScoringStarted();
|
||||
initializeChannels();
|
||||
|
||||
jamClient.FTUESetMusicDevice(audioDeviceId);
|
||||
|
||||
// enumerate input and output ports
|
||||
musicInputPorts = jamClient.FTUEGetMusicInputs2();
|
||||
console.log(JSON.stringify(musicInputPorts));
|
||||
// [{"inputs":[{"id":"i~5~Built-in Microph~0~0","name":"Built-in Microph - Left"},{"id":"i~5~Built-in Microph~1~0","name":"Built-in Microph - Right"}]}]
|
||||
musicOutputPorts = jamClient.FTUEGetMusicOutputs2();
|
||||
console.log(JSON.stringify(musicOutputPorts));
|
||||
// [{"outputs":[{"id":"o~5~Built-in Output~0~0","name":"Built-in Output - Left"},{"id":"o~5~Built-in Output~1~0","name":"Built-in Output - Right"}]}]
|
||||
|
||||
|
||||
initializeInputPorts(musicInputPorts);
|
||||
initializeOutputPorts(musicOutputPorts);
|
||||
|
||||
|
||||
jamClient.FTUESetInputLatency(selectedAudioInput());
|
||||
jamClient.FTUESetOutputLatency(selectedAudioOutput());
|
||||
jamClient.FTUESetInputLatency(selectedBufferIn());
|
||||
jamClient.FTUESetOutputLatency(selectedBufferOut());
|
||||
jamClient.FTUESetFrameSize(selectedFramesize());
|
||||
|
||||
renderScoringStarted();
|
||||
logger.debug("Calling FTUESave(false)");
|
||||
jamClient.FTUESave(false);
|
||||
|
||||
|
|
@ -551,8 +630,67 @@
|
|||
console.log("FTUEGetExpectedLatency: %o", latency);
|
||||
|
||||
updateScoreReport(latency);
|
||||
renderScoringStopped();
|
||||
});
|
||||
|
||||
// if there was a valid latency score, go on to the next step
|
||||
if(validLatencyScore) {
|
||||
renderIOScore(null, null, null, 'starting');
|
||||
var testTimeSeconds = 10; // allow 10 seconds for IO to establish itself
|
||||
context.jamClient.FTUEStartIoPerfTest();
|
||||
renderIOScoringStarted(testTimeSeconds);
|
||||
renderIOCountdown(testTimeSeconds);
|
||||
var interval = setInterval(function() {
|
||||
testTimeSeconds -= 1;
|
||||
renderIOCountdown(testTimeSeconds);
|
||||
if(testTimeSeconds == 0) {
|
||||
clearInterval(interval);
|
||||
renderIOScoringStopped();
|
||||
var io = context.jamClient.FTUEGetIoPerfData();
|
||||
|
||||
console.log("io: ", io);
|
||||
|
||||
// take the higher variance, which is apparently actually std dev
|
||||
var std = io.in_var > io.out_var ? io.in_var : io.out_var;
|
||||
std = Math.round(std * 100) / 100;
|
||||
// take the furthest-off-from-target io rate
|
||||
var median = Math.abs(io.in_median - io.in_target ) > Math.abs(io.out_median - io.out_target ) ? [io.in_median, io.in_target] : [io.out_median, io.out_target];
|
||||
var medianTarget = median[1];
|
||||
median = Math.round(median[0]);
|
||||
|
||||
var stdIOClass = 'bad';
|
||||
if(std <= 0.50) {
|
||||
stdIOClass = 'good';
|
||||
}
|
||||
else if(std <= 1.00) {
|
||||
stdIOClass = 'acceptable';
|
||||
}
|
||||
|
||||
var medianIOClass = 'bad';
|
||||
if(Math.abs(median - medianTarget) <= 1) {
|
||||
medianIOClass = 'good';
|
||||
}
|
||||
else if(Math.abs(median - medianTarget) <= 2) {
|
||||
medianIOClass = 'acceptable';
|
||||
}
|
||||
|
||||
// now base the overall IO score based on both values.
|
||||
renderIOScore(std, median, io, ioClass);
|
||||
|
||||
// lie for now until IO questions finalize
|
||||
validIOScore = true;
|
||||
|
||||
renderScoringStopped();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
else {
|
||||
renderIOScore(null, null, null, 'skip');
|
||||
renderScoringStopped();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function initializeAudioInputChanged() {
|
||||
$audioInput.unbind('change').change(attemptScore);
|
||||
}
|
||||
|
||||
function initializeAudioOutputChanged() {
|
||||
|
|
@ -677,7 +815,31 @@
|
|||
$currentWizardStep = null;
|
||||
}
|
||||
|
||||
// checks if we already have a profile called 'FTUE...'; if not, create one. if so, re-use it.
|
||||
function findOrCreateFTUEProfile() {
|
||||
var profileName = context.jamClient.FTUEGetMusicProfileName();
|
||||
|
||||
logger.debug("current profile name: " + profileName);
|
||||
|
||||
if(profileName && profileName.indexOf('FTUE') == 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
var newProfileName = 'FTUEAttempt-' + new Date().getTime().toString();
|
||||
logger.debug("setting FTUE-prefixed profile name to: " + newProfileName);
|
||||
context.jamClient.FTUESetMusicProfileName(newProfileName);
|
||||
}
|
||||
|
||||
var profileName = context.jamClient.FTUEGetMusicProfileName();
|
||||
|
||||
logger.debug("name on exit: " + profileName);
|
||||
|
||||
}
|
||||
|
||||
function beforeShow(args) {
|
||||
context.jamClient.FTUECancel();
|
||||
findOrCreateFTUEProfile();
|
||||
|
||||
step = args.d1;
|
||||
if (!step) step = 0;
|
||||
step = parseInt(step);
|
||||
|
|
@ -689,7 +851,7 @@
|
|||
}
|
||||
|
||||
function afterHide() {
|
||||
|
||||
context.jamClient.FTUECancel();
|
||||
}
|
||||
|
||||
function back() {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,20 @@
|
|||
UNIX: "Unix"
|
||||
};
|
||||
|
||||
// TODO: store these client_id values in instruments table, or store
|
||||
context.JK.ASSIGNMENT = {
|
||||
CHAT: -2,
|
||||
OUTPUT: -1,
|
||||
UNASSIGNED: 0,
|
||||
TRACK1: 1,
|
||||
TRACK2: 2
|
||||
};
|
||||
|
||||
context.JK.VOICE_CHAT = {
|
||||
NO_CHAT: "0",
|
||||
CHAT: "1"
|
||||
};
|
||||
|
||||
// TODO: store these client_id values in instruments table, or store
|
||||
// server_id as the client_id to prevent maintenance nightmares. As it's
|
||||
// set up now, we will have to deploy each time we add new instruments.
|
||||
context.JK.server_to_client_instrument_map = {
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
$.each(response.musicians, function(index, val) {
|
||||
var instrumentHtml = '';
|
||||
|
||||
musicianHtml += '<tr><td width="50"><a href="#" class="avatar-tiny"><img src="' + context.JK.resolveAvatarUrl(val.photo_url) + '" /></a></td>';
|
||||
musicianHtml += '<td width="75"><a href="#">' + val.name + '</a></td>';
|
||||
musicianHtml += '<tr><td width="50"><a user-id="' + val.id + '" profileaction="musician" class="avatar-tiny"><img src="' + context.JK.resolveAvatarUrl(val.photo_url) + '" /></a></td>';
|
||||
musicianHtml += '<td width="75"><<a user-id="' + val.id + '" profileaction="musician">' + val.name + '</a></td>';
|
||||
|
||||
instrumentHtml = '<td><div class="nowrap">';
|
||||
if (val.instruments) { // @FIXME: edge case for Test user that has no instruments?
|
||||
|
|
@ -75,6 +75,8 @@
|
|||
});
|
||||
|
||||
$(hoverSelector).append('<h2>Band Detail</h2>' + bandHtml);
|
||||
|
||||
context.JK.bindProfileClickEvents(hoverSelector);
|
||||
configureActionButtons(response);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
|
|
|
|||
|
|
@ -36,19 +36,21 @@
|
|||
followingHtml += '<tr>';
|
||||
}
|
||||
|
||||
var avatarUrl, profilePath;
|
||||
var avatarUrl, attrId, type;
|
||||
|
||||
if (val.type === "band") {
|
||||
avatarUrl = context.JK.resolveBandAvatarUrl(val.photo_url);
|
||||
profilePath = "bandProfile";
|
||||
attrId = "band-id";
|
||||
type = "band";
|
||||
}
|
||||
else {
|
||||
avatarUrl = context.JK.resolveAvatarUrl(val.photo_url);
|
||||
profilePath = "profile";
|
||||
attrId = "user-id";
|
||||
type = "musician";
|
||||
}
|
||||
|
||||
followingHtml += '<td width="24"><a href="#" class="avatar-tiny"><img src="' + avatarUrl + '" /></a></td>';
|
||||
followingHtml += '<td><a href="/client#/' + profilePath + '/' + val.id + '"><strong>' + val.name + '</strong></a></td>';
|
||||
followingHtml += '<td width="24"><a ' + attrId + '="' + val.id + '" profileaction="' + type + '" class="avatar-tiny"><img src="' + avatarUrl + '" /></a></td>';
|
||||
followingHtml += '<td><a ' + attrId + '="' + val.id + '" profileaction="' + type + '"><strong>' + val.name + '</strong></a></td>';
|
||||
|
||||
if (index % 2 > 0) {
|
||||
followingHtml += '</tr>';
|
||||
|
|
@ -76,6 +78,8 @@
|
|||
});
|
||||
|
||||
$(hoverSelector).append('<h2>Fan Detail</h2>' + fanHtml);
|
||||
|
||||
context.JK.bindProfileClickEvents(hoverSelector);
|
||||
configureActionButtons(response);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
|
|
|
|||
|
|
@ -42,19 +42,21 @@
|
|||
followingHtml += '<tr>';
|
||||
}
|
||||
|
||||
var avatarUrl, profilePath;
|
||||
var avatarUrl, attrId, type;
|
||||
|
||||
if (val.type === "band") {
|
||||
avatarUrl = context.JK.resolveBandAvatarUrl(val.photo_url);
|
||||
profilePath = "bandProfile";
|
||||
attrId = "band-id";
|
||||
type = "band";
|
||||
}
|
||||
else {
|
||||
avatarUrl = context.JK.resolveAvatarUrl(val.photo_url);
|
||||
profilePath = "profile";
|
||||
attrId = "user-id";
|
||||
type = "musician";
|
||||
}
|
||||
|
||||
followingHtml += '<td width="24"><a href="#" class="avatar-tiny"><img src="' + avatarUrl + '" /></a></td>';
|
||||
followingHtml += '<td><a href="/client#/' + profilePath + '/' + val.id + '"><strong>' + val.name + '</strong></a></td>';
|
||||
followingHtml += '<td width="24"><a ' + attrId + '="' + val.id + '" profileaction="' + type + '" class="avatar-tiny"><img src="' + avatarUrl + '" /></a></td>';
|
||||
followingHtml += '<td><a ' + attrId + '="' + val.id + '" profileaction="' + type + '"><strong>' + val.name + '</strong></a></td>';
|
||||
|
||||
if (index % 2 > 0) {
|
||||
followingHtml += '</tr>';
|
||||
|
|
@ -101,6 +103,8 @@
|
|||
});
|
||||
|
||||
$(hoverSelector).append('<h2>Musician Detail</h2>' + musicianHtml);
|
||||
|
||||
context.JK.bindProfileClickEvents(hoverSelector);
|
||||
configureActionButtons(response);
|
||||
})
|
||||
.fail(function(xhr) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue