diff --git a/db/manifest b/db/manifest
index 853a1cef6..dbc4afe31 100755
--- a/db/manifest
+++ b/db/manifest
@@ -221,3 +221,4 @@ connection_network_testing.sql
video_sources.sql
recorded_videos.sql
emails_from_update2.sql
+add_youtube_flag_to_claimed_recordings.sql
\ No newline at end of file
diff --git a/db/up/add_youtube_flag_to_claimed_recordings.sql b/db/up/add_youtube_flag_to_claimed_recordings.sql
new file mode 100644
index 000000000..5ad549f7f
--- /dev/null
+++ b/db/up/add_youtube_flag_to_claimed_recordings.sql
@@ -0,0 +1 @@
+ALTER TABLE claimed_recordings ADD COLUMN upload_to_youtube BOOLEAN NOT NULL DEFAULT false;
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb
index 9daaa1e8d..394975a34 100755
--- a/ruby/lib/jam_ruby.rb
+++ b/ruby/lib/jam_ruby.rb
@@ -51,6 +51,7 @@ require "jam_ruby/resque/scheduled/new_musician_emailer"
require "jam_ruby/resque/scheduled/music_session_scheduler"
require "jam_ruby/resque/scheduled/active_music_session_cleaner"
require "jam_ruby/resque/scheduled/score_history_sweeper"
+require "jam_ruby/resque/scheduled/scheduled_music_session_cleaner"
require "jam_ruby/resque/google_analytics_event"
require "jam_ruby/resque/batch_email_job"
require "jam_ruby/mq_router"
diff --git a/ruby/lib/jam_ruby/models/claimed_recording.rb b/ruby/lib/jam_ruby/models/claimed_recording.rb
index 9fa1e569a..88898cb89 100644
--- a/ruby/lib/jam_ruby/models/claimed_recording.rb
+++ b/ruby/lib/jam_ruby/models/claimed_recording.rb
@@ -3,7 +3,7 @@ module JamRuby
include HtmlSanitize
html_sanitize strict: [:name, :description]
- attr_accessible :name, :description, :is_public, :genre_id, :recording_id, :user_id, as: :admin
+ attr_accessible :name, :description, :is_public, :genre_id, :recording_id, :user_id, :upload_to_youtube, as: :admin
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings, :foreign_key => 'recording_id'
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
@@ -17,6 +17,8 @@ module JamRuby
validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true
validates :description, no_profanity: true, length: {maximum: 8000}
validates :is_public, :inclusion => {:in => [true, false]}
+ validates :upload_to_youtube, :inclusion => {:in => [true, false]}
+
validates :genre, presence: true
validates :user, presence: true
validates_uniqueness_of :user_id, :scope => :recording_id
diff --git a/ruby/lib/jam_ruby/models/recorded_video.rb b/ruby/lib/jam_ruby/models/recorded_video.rb
index fc787d20a..42f40ea9c 100644
--- a/ruby/lib/jam_ruby/models/recorded_video.rb
+++ b/ruby/lib/jam_ruby/models/recorded_video.rb
@@ -6,6 +6,10 @@ module JamRuby
validates :client_video_source_id, :presence => true
+ def upload_sign(content_md5)
+
+ end
+
def self.create_from_video_source(video_source, recording)
recorded_video_source = self.new
recorded_video_source.recording = recording
diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb
index f467fe563..1d9c6fd9c 100644
--- a/ruby/lib/jam_ruby/models/recording.rb
+++ b/ruby/lib/jam_ruby/models/recording.rb
@@ -180,8 +180,8 @@ module JamRuby
# Called when a user wants to "claim" a recording. To do this, the user must have been one of the tracks in the recording.
- def claim(user, name, description, genre, is_public)
-
+ def claim(user, name, description, genre, is_public, upload_to_youtube=false)
+ upload_to_youtube = !!upload_to_youtube # Correct where nil is borking save
unless self.users.exists?(user)
raise PermissionError, "user was not in this session"
end
@@ -193,6 +193,7 @@ module JamRuby
claimed_recording.description = description
claimed_recording.genre = genre
claimed_recording.is_public = is_public
+ claimed_recording.upload_to_youtube = upload_to_youtube
self.claimed_recordings << claimed_recording
if claimed_recording.save
@@ -305,7 +306,7 @@ module JamRuby
uploads = []
# Uploads now include videos in addition to the tracks.
- # This is accomplished using a SQL union via arel, as follows:
+ # This is accomplished using a SQL UNION query via arel, as follows:
# Select fields from track. Note the reorder, which removes
# the default scope sort as it b0rks the union. Also note the
@@ -356,7 +357,7 @@ module JamRuby
# Further joining and criteria for the unioned object:
arel = arel.joins("INNER JOIN (SELECT id as rec_id, all_discarded, duration FROM recordings) recs ON rec_id=recorded_items.recording_id") \
.where('recorded_items.user_id' => user.id) \
- .where('recorded_items.fully_uploaded =?', false) \
+ .where('recorded_items.fully_uploaded = ?', false) \
.where('recorded_items.id > ?', since) \
.where("upload_failures <= #{APP_CONFIG.max_track_upload_failures}") \
.where("duration IS NOT NULL") \
diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb
index b33a1d2c0..de0592801 100644
--- a/ruby/lib/jam_ruby/models/user.rb
+++ b/ruby/lib/jam_ruby/models/user.rb
@@ -324,7 +324,7 @@ module JamRuby
read_attribute(:music_session_id)
end
- # ===== ARTIFICIAL ATTRIBUTES CREATED BY ActiveMusicSession.ams_users, MusicSession.sms_uses
+ # ===== ARTIFICIAL ATTRIBUTES CREATED BY ActiveMusicSession.ams_users, MusicSession.sms_users
def full_score
return nil unless has_attribute?(:full_score)
a = read_attribute(:full_score)
@@ -344,6 +344,14 @@ module JamRuby
end
# ====== END ARTIFICAL ATTRIBUTES
+ def score_info(destination_user)
+ if self.last_jam_locidispid && destination_user.last_jam_locidispid
+ self.connection.execute("select score from current_network_scores where alocidispid = #{self.last_jam_locidispid} and blocidispid = #{destination_user.last_jam_locidispid}").check
+ else
+ nil
+ end
+ end
+
# mods comes back as text; so give ourselves a parsed version
def mods_json
@mods_json ||= mods ? JSON.parse(mods, symbolize_names: true) : {}
diff --git a/ruby/spec/jam_ruby/models/recording_spec.rb b/ruby/spec/jam_ruby/models/recording_spec.rb
index 6a6ab6ee6..0989e777c 100644
--- a/ruby/spec/jam_ruby/models/recording_spec.rb
+++ b/ruby/spec/jam_ruby/models/recording_spec.rb
@@ -126,6 +126,7 @@ describe Recording do
@claimed_recording.description.should == "description"
@claimed_recording.genre.should == @genre
@claimed_recording.is_public.should == true
+ @claimed_recording.upload_to_youtube.should == false
end
it "should fail if a user who was not in the session claims a recording" do
@@ -149,6 +150,7 @@ describe Recording do
@claimed_recording.description.should == "description2"
@claimed_recording.genre.should == @genre2
@claimed_recording.is_public.should == false
+ @claimed_recording.upload_to_youtube.should == false
end
it "should only allow the owner to edit a claimed recording" do
@@ -195,6 +197,29 @@ describe Recording do
@recording.all_discarded.should == false
end
+ it "should set youtube flag" do
+
+ @connection.join_the_session(@music_session, true, nil, @user, 10)
+ @recording = Recording.start(@music_session, @user)
+ @recording.stop
+ @recording.reload
+ @genre = FactoryGirl.create(:genre)
+ @recording.claim(@user, "name", "description", @genre, true, true)
+
+ @recording.reload
+ @recording.users.length.should == 1
+ @recording.users.first.should == @user
+ @user.recordings.length.should == 1
+ @user.recordings.first.should == @recording
+ @recording.claimed_recordings.length.should == 1
+ @claimed_recording = @recording.claimed_recordings.first
+ @claimed_recording.name.should == "name"
+ @claimed_recording.description.should == "description"
+ @claimed_recording.genre.should == @genre
+ @claimed_recording.is_public.should == true
+ @claimed_recording.upload_to_youtube.should == true
+ end
+
it "should destroy the entire recording if there was only one claimed_recording which is discarded" do
@recording = Recording.start(@music_session, @user)
@recording.stop
diff --git a/web/Gemfile b/web/Gemfile
index c97941bd1..4c31c7956 100644
--- a/web/Gemfile
+++ b/web/Gemfile
@@ -43,6 +43,7 @@ gem 'omniauth', '1.1.1'
gem 'omniauth-facebook', '1.4.1'
gem 'omniauth-twitter'
gem 'omniauth-google-oauth2', '0.2.1'
+gem 'google-api-client'
gem 'twitter'
gem 'fb_graph', '2.5.9'
gem 'sendgrid', '1.2.0'
diff --git a/web/app/assets/javascripts/hoverMusician.js b/web/app/assets/javascripts/hoverMusician.js
index 70f688d35..97af8da8a 100644
--- a/web/app/assets/javascripts/hoverMusician.js
+++ b/web/app/assets/javascripts/hoverMusician.js
@@ -7,8 +7,12 @@
var logger = context.JK.logger;
var rest = context.JK.Rest();
var hoverSelector = "#musician-hover";
+ var helpBubble = context.JK.HelpBubbleHelper;
+ var $templateLatency = null;
+ var sessionUtils = context.JK.SessionUtils;
this.showBubble = function() {
+ $templateLatency = $("#template-account-session-latency");
var mouseLeft = x < (document.body.clientWidth / 2);
var mouseTop = y < (document.body.clientHeight / 2);
var css = {};
@@ -82,10 +86,29 @@
}
}
+ var fullScore = null;
+
+ if (response.last_jam_audio_latency && response.my_audio_latency && response.internet_score) {
+ fullScore = response.last_jam_audio_latency + response.my_audio_latency + response.internet_score;
+ }
+
+ // latency badge template needs these 2 properties
+ $.extend(response, {
+ audio_latency: response.last_jam_audio_latency,
+ full_score: fullScore
+ });
+
+ var latencyBadge = context._.template(
+ $templateLatency.html(),
+ $.extend(sessionUtils.createLatency(response), response),
+ {variable: 'data'}
+ );
+
var musicianHtml = context.JK.fillTemplate(template, {
userId: response.id,
avatar_url: context.JK.resolveAvatarUrl(response.photo_url),
name: response.name,
+ first_name: response.first_name,
location: response.location,
instruments: instrumentHtml,
friend_count: response.friend_count,
@@ -95,6 +118,7 @@
session_display: sessionDisplayStyle,
join_display: joinDisplayStyle,
sessionId: sessionId,
+ latency_badge: latencyBadge,
//friendAction: response.is_friend ? "removeMusicianFriend" : (response.pending_friend_request ? "" : "sendMusicianFriendRequest"),
friendAction: response.is_friend ? "" : (response.pending_friend_request ? "" : "sendMusicianFriendRequest"),
followAction: response.is_following ? "removeMusicianFollowing" : "addMusicianFollowing",
diff --git a/web/app/assets/javascripts/session_utils.js b/web/app/assets/javascripts/session_utils.js
index 725da855d..482aaeab1 100644
--- a/web/app/assets/javascripts/session_utils.js
+++ b/web/app/assets/javascripts/session_utils.js
@@ -77,34 +77,34 @@
description = 'me';
}
else if (!full_score) {
- latencyDescription = LATENCY.UNKNOWN.description;
+ latencyDescription = LATENCY.UNKNOWN.description;
latencyStyle = LATENCY.UNKNOWN.style;
- iconName = 'purple'
- description = 'missing'
+ iconName = 'purple';
+ description = 'missing';
}
else if (full_score <= LATENCY.GOOD.max) {
latencyDescription = LATENCY.GOOD.description;
latencyStyle = LATENCY.GOOD.style;
- iconName = 'green'
- description = 'good'
+ iconName = 'green';
+ description = 'good';
}
else if (full_score <= LATENCY.MEDIUM.max) {
latencyDescription = LATENCY.MEDIUM.description;
latencyStyle = LATENCY.MEDIUM.style;
iconName = 'yellow';
- description = 'fair'
+ description = 'fair';
}
else if (full_score <= LATENCY.POOR.max) {
latencyDescription = LATENCY.POOR.description;
latencyStyle = LATENCY.POOR.style;
- iconName = 'red'
- description = 'poor'
+ iconName = 'red';
+ description = 'poor';
}
else {
latencyStyle = LATENCY.UNACCEPTABLE.style;
latencyDescription = LATENCY.UNACCEPTABLE.description;
- iconName = 'blue'
- description = 'unacceptable'
+ iconName = 'blue';
+ description = 'unacceptable';
}
return {
diff --git a/web/app/assets/stylesheets/client/account.css.scss b/web/app/assets/stylesheets/client/account.css.scss
index 81d700c12..74183442c 100644
--- a/web/app/assets/stylesheets/client/account.css.scss
+++ b/web/app/assets/stylesheets/client/account.css.scss
@@ -115,7 +115,7 @@
background-color: #C5C5C5;
border: medium none;
box-shadow: 2px 2px 3px 0 #888888 inset;
- color: #666666;
+ color: #000;
font-size: 14px;
height: 178px;
overflow: auto;
diff --git a/web/app/assets/stylesheets/client/band.css.scss b/web/app/assets/stylesheets/client/band.css.scss
index 4da4130d3..d2e8504d5 100644
--- a/web/app/assets/stylesheets/client/band.css.scss
+++ b/web/app/assets/stylesheets/client/band.css.scss
@@ -13,7 +13,7 @@
border:none;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
- color:#666;
+ color:#000;
overflow:auto;
font-size:14px;
}
diff --git a/web/app/assets/stylesheets/client/content.css.scss b/web/app/assets/stylesheets/client/content.css.scss
index 68434368c..9bee28a72 100644
--- a/web/app/assets/stylesheets/client/content.css.scss
+++ b/web/app/assets/stylesheets/client/content.css.scss
@@ -222,7 +222,6 @@
border:none;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
- color:#666;
}
}
diff --git a/web/app/assets/stylesheets/client/createSession.css.scss b/web/app/assets/stylesheets/client/createSession.css.scss
index a4cbec1dd..83eeba993 100644
--- a/web/app/assets/stylesheets/client/createSession.css.scss
+++ b/web/app/assets/stylesheets/client/createSession.css.scss
@@ -209,7 +209,7 @@
border: none;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
- color: #666;
+ color: #000;
overflow: auto;
font-size: 14px;
diff --git a/web/app/assets/stylesheets/client/ftue.css.scss b/web/app/assets/stylesheets/client/ftue.css.scss
index ef81f1a39..1082b843e 100644
--- a/web/app/assets/stylesheets/client/ftue.css.scss
+++ b/web/app/assets/stylesheets/client/ftue.css.scss
@@ -528,14 +528,14 @@ div[layout-id="ftue3"] {
border:none;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
- color:#666;
+ color:#000;
overflow:auto;
font-size:14px;
}
.ftue-instrumentlist select, .ftue-instrumentlist .easydropdown {
width:100%;
- color:#666;
+ color:#000;
}
table.audiogeartable {
diff --git a/web/app/assets/stylesheets/client/hoverBubble.css.scss b/web/app/assets/stylesheets/client/hoverBubble.css.scss
index a53fff3b8..b8d6ec315 100644
--- a/web/app/assets/stylesheets/client/hoverBubble.css.scss
+++ b/web/app/assets/stylesheets/client/hoverBubble.css.scss
@@ -1,3 +1,5 @@
+@import 'common';
+
.bubble {
width:350px;
min-height:200px;
@@ -74,4 +76,48 @@
-moz-border-radius:12px;
border-radius:12px;
}
+
+ .musician-latency {
+ margin-right:35px;
+ position:relative;
+ width:350px;
+ }
+
+ .latency-holder {
+ position:absolute;
+ width:100%;
+ text-align:center;
+ }
+
+ .latency {
+ min-width: 50px;
+ display:inline-block;
+ padding:4px;
+ font-family:Arial, Helvetica, sans-serif;
+ font-weight:200;
+ font-size:11px;
+ text-align:center;
+ @include border-radius(2px);
+ color:white;
+ }
+
+ .latency-unknown {
+ background-color:$latencyBadgeUnknown;
+ }
+
+ .latency-unacceptable {
+ background-color:$latencyBadgeUnacceptable;
+ }
+
+ .latency-good {
+ background-color:$latencyBadgeGood;
+ }
+
+ .latency-fair{
+ background-color:$latencyBadgeFair;
+ }
+
+ .latency-poor {
+ background-color:$latencyBadgePoor;
+ }
}
\ No newline at end of file
diff --git a/web/app/assets/stylesheets/client/jamkazam.css.scss b/web/app/assets/stylesheets/client/jamkazam.css.scss
index 46df063a6..8ccd7a022 100644
--- a/web/app/assets/stylesheets/client/jamkazam.css.scss
+++ b/web/app/assets/stylesheets/client/jamkazam.css.scss
@@ -302,7 +302,6 @@ input[type="button"] {
.search-box {
float:left;
- width:140px;
margin-left: 10px;
-webkit-border-radius: 6px;
border-radius: 6px;
@@ -321,7 +320,6 @@ input[type="button"] {
input[type="text"], input[type="password"]{
background-color:$ColorTextBoxBackground;
border:none;
- color:#666;
padding:3px;
font-size:15px;
}
diff --git a/web/app/assets/stylesheets/client/screen_common.css.scss b/web/app/assets/stylesheets/client/screen_common.css.scss
index 30cc32a06..f36438ea4 100644
--- a/web/app/assets/stylesheets/client/screen_common.css.scss
+++ b/web/app/assets/stylesheets/client/screen_common.css.scss
@@ -143,7 +143,6 @@ textarea {
border:none;
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
box-shadow: inset 2px 2px 3px 0px #888;
- color:#333;
}
diff --git a/web/app/assets/stylesheets/easydropdown_jk.css.scss b/web/app/assets/stylesheets/easydropdown_jk.css.scss
index 4b2ff52b6..47e43c108 100644
--- a/web/app/assets/stylesheets/easydropdown_jk.css.scss
+++ b/web/app/assets/stylesheets/easydropdown_jk.css.scss
@@ -106,15 +106,12 @@ body.jam {
.dropdown-wrapper li {
padding: 5px 5px;
font-size:15px;
-
- color: #666666;
}
.dropdown-wrapper li {
margin:0;
padding:3px;
font-size:15px;
- color: #666666;
&.focus {
background-color: #ed3618;
@@ -151,8 +148,6 @@ body.jam div.dropdown {
.selected, .dropdown li {
padding: 5px 5px;
font-size:15px;
-
- color: #666666;
}
.selected:after {
box-shadow: none;
@@ -166,7 +161,6 @@ body.jam div.dropdown {
margin:0;
padding:3px;
font-size:15px;
- color: #666666;
&.focus {
background-color: #ed3618;
diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb
index 66c5625f9..e7c67b29d 100644
--- a/web/app/controllers/api_recordings_controller.rb
+++ b/web/app/controllers/api_recordings_controller.rb
@@ -79,7 +79,7 @@ class ApiRecordingsController < ApiController
# claim will create a claimed recording for the creator
def claim
- claim = @recording.claim(current_user, params[:name], params[:description], Genre.find_by_id(params[:genre]), params[:is_public])
+ claim = @recording.claim(current_user, params[:name], params[:description], Genre.find_by_id(params[:genre]), params[:is_public], params[:upload_to_youtube])
if claim.errors.any?
response.status = :unprocessable_entity
diff --git a/web/app/controllers/sessions_controller.rb b/web/app/controllers/sessions_controller.rb
index f2f705141..7a2bb8ca7 100644
--- a/web/app/controllers/sessions_controller.rb
+++ b/web/app/controllers/sessions_controller.rb
@@ -134,11 +134,16 @@ class SessionsController < ApplicationController
# Always make and save a new authorization. This is because they expire, and honestly there's no cost
# to just making and saving it.
+ user_auth_hash = {
+ :provider => auth_hash[:provider],
+ :uid => auth_hash[:uid],
+ :token => auth_hash[:credentials][:token],
+ :token_expiration => Time.at(auth_hash[:credentials][:expires_at]),
+ :secret => auth_hash[:credentials][:secret]
+ }
+
#if authorization.nil?
- authorization = current_user.user_authorizations.build :provider => auth_hash[:provider],
- :uid => auth_hash[:uid],
- :token => auth_hash[:credentials][:token],
- :token_expiration => Time.at(auth_hash[:credentials][:expires_at])
+ authorization = current_user.user_authorizations.build(user_auth_hash)
authorization.save
#end
diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl
index b2827fdba..fd8b9b87e 100644
--- a/web/app/views/api_users/show.rabl
+++ b/web/app/views/api_users/show.rabl
@@ -30,6 +30,12 @@ elsif current_user
node :pending_friend_request do |uu|
current_user.pending_friend_request?(@user)
end
+ node :my_audio_latency do |user|
+ current_user.last_jam_audio_latency.round if current_user.last_jam_audio_latency
+ end
+ node :internet_score do |user|
+ current_user.score_info(user)
+ end
end
child :friends => :friends do
diff --git a/web/app/views/clients/_hoverMusician.html.erb b/web/app/views/clients/_hoverMusician.html.erb
index 0a185a3ed..dd1994d6d 100644
--- a/web/app/views/clients/_hoverMusician.html.erb
+++ b/web/app/views/clients/_hoverMusician.html.erb
@@ -115,6 +115,11 @@