diff --git a/admin/jenkins b/admin/jenkins index 67733e8c2..cfc6734ab 100755 --- a/admin/jenkins +++ b/admin/jenkins @@ -9,17 +9,21 @@ if [ "$?" = "0" ]; then echo "build succeeded" if [ ! -z "$PACKAGE" ]; then - echo "publishing ubuntu package (.deb)" - DEBPATH=`find target/deb -name *.deb` - DEBNAME=`basename $DEBPATH` + if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* ]]; then + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` - curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME - if [ "$?" != "0" ]; then - echo "deb publish failed" - exit 1 + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + else + echo "Skipping publish since branch is neither master or develop..." fi - echo "done publishing deb" fi else echo "build failed" diff --git a/db/jenkins b/db/jenkins index 8d2afbc49..3c3f5b055 100755 --- a/db/jenkins +++ b/db/jenkins @@ -7,38 +7,39 @@ echo "starting build..." ./build if [ "$?" = "0" ]; then - echo "build succeeded" - echo "publishing gem" - pushd "target/ruby_package" - find . -name *.gem -exec curl -f -T {} $GEM_SERVER/{} \; - - if [ "$?" != "0" ]; then - echo "publish failed" - exit 1 - fi - popd - echo "done publishing gems" + echo "build succeeded" + if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* ]]; then + echo "publishing gem" + pushd "target/ruby_package" + find . -name *.gem -exec curl -f -T {} $GEM_SERVER/{} \; - if [ ! -z "$PACKAGE" ]; then - echo "publishing ubuntu packages (.deb)" - for f in `find target -name '*.deb'`; do - DEBNAME=`basename $f` - DEBPATH="$f" - echo "publishing $DEBPATH to deb server" - curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME - - if [ "$?" != "0" ]; then - echo "deb publish failed of $DEBPATH" - exit 1 - fi - done + if [ "$?" != "0" ]; then + echo "publish failed" + exit 1 + fi - echo "done publishing debs" + popd + echo "done publishing gems" + + if [ ! -z "$PACKAGE" ]; then + echo "publishing ubuntu packages (.deb)" + for f in `find target -name '*.deb'`; do + DEBNAME=`basename $f` + DEBPATH="$f" + echo "publishing $DEBPATH to deb server" + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + if [ "$?" != "0" ]; then + echo "deb publish failed of $DEBPATH" + exit 1 + fi + done + + echo "done publishing debs" + fi + else + echo "Skipping publish since branch is neither master or develop..." fi - else echo "build failed" exit 1 fi - - diff --git a/pb/src/client_container.proto b/pb/src/client_container.proto index fef2995dc..0169de05e 100644 --- a/pb/src/client_container.proto +++ b/pb/src/client_container.proto @@ -9,43 +9,61 @@ package jampb; message ClientMessage { enum Type { - LOGIN = 100; - LOGIN_ACK = 101; + LOGIN = 100; + LOGIN_ACK = 105; + LOGIN_MUSIC_SESSION = 110; + LOGIN_MUSIC_SESSION_ACK = 115; + LEAVE_MUSIC_SESSION = 120; + LEAVE_MUSIC_SESSION_ACK = 125; + HEARTBEAT = 130; + HEARTBEAT_ACK = 135; - LOGIN_MUSIC_SESSION = 102; - LOGIN_MUSIC_SESSION_ACK = 103; - FRIEND_SESSION_JOIN = 104; - LEAVE_MUSIC_SESSION = 105; - LEAVE_MUSIC_SESSION_ACK = 106; - HEARTBEAT = 107; - FRIEND_UPDATE = 108; - SESSION_INVITATION = 109; - MUSICIAN_SESSION_DEPART = 110; - JOIN_REQUEST = 111; - FRIEND_REQUEST = 112; - FRIEND_REQUEST_ACCEPTED = 113; - MUSICIAN_SESSION_JOIN = 114; - MUSICIAN_SESSION_FRESH = 115; - MUSICIAN_SESSION_STALE = 116; - HEARTBEAT_ACK = 117; - JOIN_REQUEST_APPROVED = 118; - JOIN_REQUEST_REJECTED = 119; - BAND_INVITATION = 120; - BAND_INVITATION_ACCEPTED = 121; + // friend notifications + FRIEND_UPDATE = 140; + FRIEND_REQUEST = 145; + FRIEND_REQUEST_ACCEPTED = 150; + FRIEND_SESSION_JOIN = 155; + NEW_USER_FOLLOWER = 160; + NEW_BAND_FOLLOWER = 161; - TEST_SESSION_MESSAGE = 200; + // session invitations + SESSION_INVITATION = 165; + SESSION_ENDED = 170; + JOIN_REQUEST = 175; + JOIN_REQUEST_APPROVED = 180; + JOIN_REQUEST_REJECTED = 185; + SESSION_JOIN = 190; + SESSION_DEPART = 195; + MUSICIAN_SESSION_JOIN = 196; + + // recording notifications + MUSICIAN_RECORDING_SAVED = 200; + BAND_RECORDING_SAVED = 205; + RECORDING_STARTED = 210; + RECORDING_ENDED = 215; + RECORDING_MASTER_MIX_COMPLETE = 220; + + // band notifications + BAND_INVITATION = 225; + BAND_INVITATION_ACCEPTED = 230; + BAND_SESSION_JOIN = 235; + + MUSICIAN_SESSION_FRESH = 240; + MUSICIAN_SESSION_STALE = 245; + + TEST_SESSION_MESSAGE = 295; PING_REQUEST = 300; - PING_ACK = 301; - PEER_MESSAGE = 302; - TEST_CLIENT_MESSAGE = 303; + PING_ACK = 305; + PEER_MESSAGE = 310; + TEST_CLIENT_MESSAGE = 315; SERVER_BAD_STATE_RECOVERED = 900; SERVER_GENERIC_ERROR = 1000; - SERVER_REJECTION_ERROR = 1001; - SERVER_PERMISSION_ERROR = 1002; - SERVER_BAD_STATE_ERROR = 1003; + SERVER_REJECTION_ERROR = 1005; + SERVER_PERMISSION_ERROR = 1010; + SERVER_BAD_STATE_ERROR = 1015; } // Identifies which inner message is filled in @@ -59,45 +77,64 @@ message ClientMessage { // Client-Server messages (to/from) optional Login login = 100; // to server - optional LoginAck login_ack = 101; // from server - optional LoginMusicSession login_music_session = 102; // to server - optional LoginMusicSessionAck login_music_session_ack = 103; // from server - optional FriendSessionJoin friend_session_join = 104; // from server to all members - optional LeaveMusicSession leave_music_session = 105; - optional LeaveMusicSessionAck leave_music_session_ack = 106; - optional Heartbeat heartbeat = 107; - optional FriendUpdate friend_update = 108; // from server to all friends of user - optional SessionInvitation session_invitation = 109; // from server to user - optional MusicianSessionDepart musician_session_depart = 110; - optional JoinRequest join_request = 111; - optional FriendRequest friend_request = 112; - optional FriendRequestAccepted friend_request_accepted = 113; - optional MusicianSessionJoin musician_session_join = 114; - optional MusicianSessionFresh musician_session_fresh = 115; - optional MusicianSessionStale musician_session_stale = 116; - optional HeartbeatAck heartbeat_ack = 117; - optional JoinRequestApproved join_request_approved = 118; - optional JoinRequestRejected join_request_rejected = 119; - optional BandInvitation band_invitation = 120; - optional BandInvitationAccepted band_invitation_accepted = 121; + optional LoginAck login_ack = 105; // from server + optional LoginMusicSession login_music_session = 110; // to server + optional LoginMusicSessionAck login_music_session_ack = 115; // from server + optional LeaveMusicSession leave_music_session = 120; + optional LeaveMusicSessionAck leave_music_session_ack = 125; + optional Heartbeat heartbeat = 130; + optional HeartbeatAck heartbeat_ack = 135; + + // friend notifications + optional FriendUpdate friend_update = 140; // from server to all friends of user + optional FriendRequest friend_request = 145; + optional FriendRequestAccepted friend_request_accepted = 150; + optional NewUserFollower new_user_follower = 160; + optional NewBandFollower new_band_follower = 161; + + // session invitations + optional SessionInvitation session_invitation = 165; // from server to user + optional SessionEnded session_ended = 170; + optional JoinRequest join_request = 175; + optional JoinRequestApproved join_request_approved = 180; + optional JoinRequestRejected join_request_rejected = 185; + optional SessionJoin session_join = 190; + optional SessionDepart session_depart = 195; + optional MusicianSessionJoin musician_session_join = 196; + optional BandSessionJoin band_session_join = 197; + + // recording notifications + optional MusicianRecordingSaved musician_recording_saved = 200; + optional BandRecordingSaved band_recording_saved = 205; + optional RecordingStarted recording_started = 210; + optional RecordingEnded recording_ended = 215; + optional RecordingMasterMixComplete recording_master_mix_complete = 220; + + // band notifications + optional BandInvitation band_invitation = 225; + optional BandInvitationAccepted band_invitation_accepted = 230; + + optional MusicianSessionFresh musician_session_fresh = 240; + optional MusicianSessionStale musician_session_stale = 245; + // Client-Session messages (to/from) - optional TestSessionMessage test_session_message = 200; + optional TestSessionMessage test_session_message = 295; // Client-Client messages (to/from) optional PingRequest ping_request = 300; - optional PingAck ping_ack = 301; - optional PeerMessage peer_message = 302; - optional TestClientMessage test_client_message = 303; + optional PingAck ping_ack = 305; + optional PeerMessage peer_message = 310; + optional TestClientMessage test_client_message = 315; // Server-to-Client special messages optional ServerBadStateRecovered server_bad_state_recovered = 900; // Server-to-Client errors optional ServerGenericError server_generic_error = 1000; - optional ServerRejectionError server_rejection_error = 1001; - optional ServerPermissionError server_permission_error = 1002; - optional ServerBadStateError server_bad_state_error = 1003; + optional ServerRejectionError server_rejection_error = 1005; + optional ServerPermissionError server_permission_error = 1010; + optional ServerBadStateError server_bad_state_error = 1015; } // route_to: server @@ -157,32 +194,157 @@ message LeaveMusicSessionAck { optional string error_reason = 2; } -// route_to: client: -// sent by server to let the rest of the participants know a user has joined. -message FriendSessionJoin { - optional string session_id = 1; // the session ID - optional string user_id = 2; // this is the user_id and can be used for user unicast messages - optional string username = 3; // meant to be a display name - optional string photo_url = 4; +message FriendUpdate { + optional string user_id = 1; + optional string photo_url = 2; + optional bool online = 3; + optional string msg = 4; +} + +message FriendRequest { + optional string friend_request_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; +} + +message FriendRequestAccepted { + optional string photo_url = 1; + optional string msg = 2; + optional string notification_id = 3; + optional string created_at = 4; +} + +message NewUserFollower { + optional string photo_url = 1; + optional string msg = 2; + optional string notification_id = 3; + optional string created_at = 4; +} + +message NewBandFollower { + optional string photo_url = 1; + optional string msg = 2; + optional string notification_id = 3; + optional string created_at = 4; +} + +message SessionInvitation { + optional string session_id = 1; + optional string msg = 2; + optional string notification_id = 3; + optional string created_at = 4; +} + +message SessionEnded { + +} + +message JoinRequest { + optional string join_request_id = 1; + optional string session_id = 2; + optional string photo_url = 3; + optional string msg = 4; + optional string notification_id = 5; + optional string created_at = 6; +} + +message JoinRequestApproved { + optional string join_request_id = 1; + optional string session_id = 2; + optional string photo_url = 3; + optional string msg = 4; + optional string notification_id = 5; + optional string created_at = 6; +} + +message JoinRequestRejected { + optional string invitation_id = 1; + optional string session_id = 2; + optional string photo_url = 3; + optional string msg = 4; + optional string notification_id = 5; + optional string created_at = 6; +} + +message SessionJoin { + optional string session_id = 1; + optional string photo_url = 2; + optional string msg = 3; +} + +message SessionDepart { + optional string session_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string recording_id = 4; } -// route_to: client: -// sent by server to let the rest of the participants know a user has joined. message MusicianSessionJoin { - optional string session_id = 1; // the session ID - optional string user_id = 2; // this is the user_id and can be used for user unicast messages - optional string username = 3; // meant to be a display name - optional string photo_url = 4; + optional string session_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; } -// route_to: client: -// sent by server to let the rest of the participants know a user has left. -message MusicianSessionDepart { - optional string session_id = 1; // the session ID - optional string user_id = 2; // this is the user_id and can be used for user unicast messages - optional string username = 3; // meant to be a display name - optional string photo_url = 4; - optional string recordingId = 5; // if specified, the recording was stopped automatically +message BandSessionJoin { + optional string session_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; +} + +message MusicianRecordingSaved { + optional string recording_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; +} + +message BandRecordingSaved { + optional string recording_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; +} + +message RecordingStarted { + optional string photo_url = 1; + optional string msg = 2; +} + +message RecordingEnded { + optional string photo_url = 1; + optional string msg = 2; +} + +message RecordingMasterMixComplete { + optional string recording_id = 1; + optional string msg = 2; + optional string notification_id = 3; + optional string created_at = 4; +} + +message BandInvitation { + optional string band_invitation_id = 1; + optional string band_id = 2; + optional string photo_url = 3; + optional string msg = 4; + optional string notification_id = 5; + optional string created_at = 6; +} + +message BandInvitationAccepted { + optional string band_invitation_id = 1; + optional string photo_url = 2; + optional string msg = 3; + optional string notification_id = 4; + optional string created_at = 5; } // route_to: client: @@ -203,59 +365,6 @@ message MusicianSessionStale { optional string photo_url = 4; } -message JoinRequest { - optional string join_request_id = 1; - optional string session_id = 2; - optional string username = 3; - optional string photo_url = 4; - optional string msg = 5; - optional string notification_id = 6; - optional string created_at = 7; -} - -message JoinRequestApproved { - optional string join_request_id = 1; - optional string session_id = 2; - optional string username = 3; - optional string photo_url = 4; - optional string msg = 5; - optional string notification_id = 6; - optional string created_at = 7; -} - -message JoinRequestRejected { - optional string invitation_id = 1; - optional string session_id = 2; - optional string username = 3; - optional string photo_url = 4; - optional string msg = 5; - optional string notification_id = 6; - optional string created_at = 7; -} - -message BandInvitation { - optional string band_invitation_id = 1; - optional string band_id = 2; - optional string user_id = 3; - optional string username = 4; - optional string photo_url = 5; - optional string band_name = 6; - optional string msg = 7; - optional string notification_id = 8; - optional string created_at = 9; -} - -message BandInvitationAccepted { - optional string band_invitation_id = 1; - optional string user_id = 2; - optional string username = 3; - optional string photo_url = 4; - optional string band_name = 5; - optional string msg = 6; - optional string notification_id = 7; - optional string created_at = 8; -} - // route_to: session // a test message used by ruby-client currently. just gives way to send out to rest of session message TestSessionMessage { @@ -298,57 +407,12 @@ message Heartbeat { message HeartbeatAck { } -// target: client -// send from server to client when user sends a friend request -message FriendRequest { - optional string friend_request_id = 1; - optional string user_id = 2; - optional string name = 3; - optional string photo_url = 4; - optional string friend_id = 5; - optional string msg = 6; - optional string notification_id = 7; - optional string created_at = 8; -} - -// target: client -message FriendRequestAccepted { - optional string friend_id = 1; // accepter - optional string name = 2; - optional string photo_url = 3; - optional string user_id = 4; // original requester - optional string msg = 5; - optional string notification_id = 6; - optional string created_at = 7; -} - -// target: client -// send from server to client when a user logs in -message FriendUpdate { - optional string user_id = 1; - optional string name = 2; - optional string photo_url = 3; - optional bool online = 4; - optional string msg = 5; -} - -// route_to: user:[USER_ID] -// let a user know they've been invited to a session -message SessionInvitation { - optional string sender_name = 1; - optional string session_id = 2; - optional string notification_id = 3; - optional string created_at = 4; -} - // route_to: client // this should follow a ServerBadStateError in the case that the // websocket gateway recovers from whatever ailed it message ServerBadStateRecovered { } - - // route_to: client // this indicates unhandled error on server // if you receive this, your connection will close after. diff --git a/ruby/Gemfile b/ruby/Gemfile index 67fa507f4..f8607162e 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -10,6 +10,7 @@ gem 'pg', '0.15.1', :platform => [:mri, :mswin, :mingw] gem 'jdbc_postgres', :platform => [:jruby] gem 'activerecord', '3.2.13' +gem "activerecord-import", "~> 0.4.1" gem 'uuidtools', '2.1.2' gem 'bcrypt-ruby', '3.0.1' gem 'ruby-protocol-buffers', '1.2.2' diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index c399f4e24..9fbc5bf66 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -88,5 +88,83 @@ end end + #################################### NOTIFICATION EMAILS #################################### + def friend_request(email, msg) + subject = "You have a new friend request on JamKazam" + unique_args = {:type => "friend_request"} + send_notification(email, subject, msg, unique_args) + end + + def friend_request_accepted(email, msg) + subject = "You have a new friend on JamKazam" + unique_args = {:type => "friend_request_accepted"} + send_notification(email, subject, msg, unique_args) + end + + def new_user_follower(email, msg) + subject = "You have a new follower on JamKazam" + unique_args = {:type => "new_user_follower"} + send_notification(email, subject, msg, unique_args) + end + + def new_band_follower(email, msg) + subject = "Your band has a new follower on JamKazam" + unique_args = {:type => "new_band_follower"} + send_notification(email, subject, msg, unique_args) + end + + def session_invitation(email, msg) + subject = "You have been invited to a session on JamKazam" + unique_args = {:type => "session_invitation"} + send_notification(email, subject, msg, unique_args) + end + + def musician_session_join(email, msg) + subject = "Someone you know is in a session on JamKazam" + unique_args = {:type => "musician_session_join"} + send_notification(email, subject, msg, unique_args) + end + + def band_session_join(email, msg) + subject = "A band that you follow has joined a session" + unique_args = {:type => "band_session_join"} + send_notification(email, subject, msg, unique_args) + end + + def musician_recording_saved(email, msg) + subject = msg + unique_args = {:type => "musician_recording_saved"} + send_notification(email, subject, msg, unique_args) + end + + def band_recording_saved(email, msg) + subject = msg + unique_args = {:type => "band_recording_saved"} + send_notification(email, subject, msg, unique_args) + end + + def band_invitation(email, msg) + subject = "You have been invited to join a band on JamKazam" + unique_args = {:type => "band_invitation"} + send_notification(email, subject, msg, unique_args) + end + + def band_invitation_accepted(email, msg) + subject = "Your band invitation was accepted" + unique_args = {:type => "band_invitation_accepted"} + send_notification(email, subject, msg, unique_args) + end + + def send_notification(email, subject, msg, unique_args) + @body = msg + sendgrid_category "Notification" + sendgrid_unique_args :type => unique_args[:type] + mail(:bcc => email, :subject => subject) do |format| + format.text + format.html + end + end + ############################################################################################# + end end diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.html.erb new file mode 100644 index 000000000..daac81671 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Band Invitation') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.html.erb new file mode 100644 index 000000000..91eb88c0b --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'Band Invitation Accepted') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_invitation_accepted.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.html.erb new file mode 100644 index 000000000..e0a1a0008 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Band Recording') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_recording_saved.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.html.erb new file mode 100644 index 000000000..74a84c56b --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Band Session') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/band_session_join.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.html.erb new file mode 100644 index 000000000..ccfdaf529 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New JamKazam Friend Request') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.html.erb new file mode 100644 index 000000000..00a7d3e08 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'Friend Request Accepted') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/friend_request_accepted.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.html.erb new file mode 100644 index 000000000..8a0ff0a7a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Musician Recording') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_recording_saved.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.html.erb new file mode 100644 index 000000000..ae36c8a1e --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'Musician in Session') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/musician_session_join.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.html.erb new file mode 100644 index 000000000..9fd8ef321 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Band Follower on JamKazam') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_band_follower.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.html.erb new file mode 100644 index 000000000..cdb0c6622 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'New Follower on JamKazam') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/new_user_follower.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.html.erb new file mode 100644 index 000000000..7d74c64b8 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'Recording Master Mix Completed') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/recording_master_mix_complete.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.html.erb new file mode 100644 index 000000000..6c99a1d33 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.html.erb @@ -0,0 +1,3 @@ +<% provide(:title, 'Session Invitation') %> + +

<%= @body %>

\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.text.erb new file mode 100644 index 000000000..2f21cf84a --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/session_invitation.text.erb @@ -0,0 +1 @@ +<%= @body %> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/constants/notification_types.rb b/ruby/lib/jam_ruby/constants/notification_types.rb index 272095f59..a6091f5a0 100644 --- a/ruby/lib/jam_ruby/constants/notification_types.rb +++ b/ruby/lib/jam_ruby/constants/notification_types.rb @@ -5,23 +5,29 @@ module NotificationTypes FRIEND_REQUEST = "FRIEND_REQUEST" FRIEND_REQUEST_ACCEPTED = "FRIEND_REQUEST_ACCEPTED" FRIEND_SESSION_JOIN = "FRIEND_SESSION_JOIN" + NEW_USER_FOLLOWER = "NEW_USER_FOLLOWER" + NEW_BAND_FOLLOWER = "NEW_BAND_FOLLOWER" # session notifications SESSION_INVITATION = "SESSION_INVITATION" - SESSION_ENDED = "SESSION_ENDED" # used to remove session-related notification from sidebar + SESSION_ENDED = "SESSION_ENDED" # used to remove session-related notifications from sidebar JOIN_REQUEST = "JOIN_REQUEST" JOIN_REQUEST_APPROVED = "JOIN_REQUEST_APPROVED" JOIN_REQUEST_REJECTED = "JOIN_REQUEST_REJECTED" - - # musician notifications + SESSION_JOIN = "SESSION_JOIN" + SESSION_DEPART = "SESSION_DEPART" MUSICIAN_SESSION_JOIN = "MUSICIAN_SESSION_JOIN" - MUSICIAN_SESSION_DEPART = "MUSICIAN_SESSION_DEPART" # recording notifications - RECORDING_CREATED = "RECORDING_CREATED" + MUSICIAN_RECORDING_SAVED = "MUSICIAN_RECORDING_SAVED" + BAND_RECORDING_SAVED = "BAND_RECORDING_SAVED" + RECORDING_STARTED = "RECORDING_STARTED" + RECORDING_ENDED = "RECORDING_ENDED" + RECORDING_MASTER_MIX_COMPLETE = "RECORDING_MASTER_MIX_COMPLETE" # band notifications BAND_INVITATION = "BAND_INVITATION" BAND_INVITATION_ACCEPTED = "BAND_INVITATION_ACCEPTED" + BAND_SESSION_JOIN = "BAND_SESSION_JOIN" # cleared using SESSION_ENDED notification end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/message_factory.rb b/ruby/lib/jam_ruby/message_factory.rb index 51df0e0d5..7bdcb0881 100644 --- a/ruby/lib/jam_ruby/message_factory.rb +++ b/ruby/lib/jam_ruby/message_factory.rb @@ -1,4 +1,4 @@ - module JamRuby +module JamRuby # creates messages (implementation: protocol buffer) objects cleanly class MessageFactory @@ -9,18 +9,18 @@ CLIENT_TARGET_PREFIX = "client:" def initialize() - @type_values = {} + @type_values = {} - Jampb::ClientMessage::Type.constants.each do |constant| - @type_values[Jampb::ClientMessage::Type.const_get(constant)] = constant - end + Jampb::ClientMessage::Type.constants.each do |constant| + @type_values[Jampb::ClientMessage::Type.const_get(constant)] = constant + end end - # given a string (bytes) payload, return a client message - def parse_client_msg(payload) - return Jampb::ClientMessage.parse(payload) - end + # given a string (bytes) payload, return a client message + def parse_client_msg(payload) + return Jampb::ClientMessage.parse(payload) + end # create a login message using user/pass def login_with_user_pass(username, password, options = {}) @@ -114,6 +114,28 @@ ) end + # create a heartbeat + def heartbeat() + heartbeat = Jampb::Heartbeat.new + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::HEARTBEAT, + :route_to => SERVER_TARGET, + :heartbeat => heartbeat + ) + end + + # create a heartbeat ack + def heartbeat_ack() + heartbeat_ack = Jampb::HeartbeatAck.new + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::HEARTBEAT_ACK, + :route_to => CLIENT_TARGET, + :heartbeat_ack => heartbeat_ack + ) + end + # create a server bad state recovered msg def server_bad_state_recovered(original_message_id) recovered = Jampb::ServerBadStateRecovered.new() @@ -126,7 +148,7 @@ ) end - # create a server error + # create a server error def server_generic_error(error_msg) error = Jampb::ServerGenericError.new(:error_msg => error_msg) @@ -137,7 +159,7 @@ ) end - # create a server rejection error + # create a server rejection error def server_rejection_error(error_msg) error = Jampb::ServerRejectionError.new(:error_msg => error_msg) @@ -172,52 +194,310 @@ ) end - # create a friend joined session message - def friend_session_join(session_id, user_id, username, photo_url) - join = Jampb::FriendSessionJoin.new( - :session_id => session_id, + ###################################### NOTIFICATIONS ###################################### + + # create a friend update message + def friend_update(user_id, photo_url, online, msg) + friend = Jampb::FriendUpdate.new( :user_id => user_id, - :username => username, - :photo_url => photo_url + :photo_url => photo_url, + :online => online, + :msg => msg ) return Jampb::ClientMessage.new( - :type => ClientMessage::Type::FRIEND_SESSION_JOIN, - :route_to => CLIENT_TARGET, - :friend_session_join => join + :type => ClientMessage::Type::FRIEND_UPDATE, + :route_to => USER_TARGET_PREFIX + user_id, + :friend_update => friend ) end - # create a musician joined session message - def musician_session_join(session_id, user_id, username, photo_url) - join = Jampb::MusicianSessionJoin.new( + # create a friend request message + def friend_request(receiver_id, friend_request_id, photo_url, msg, notification_id, created_at) + friend_request = Jampb::FriendRequest.new( + :friend_request_id => friend_request_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::FRIEND_REQUEST, + :route_to => USER_TARGET_PREFIX + receiver_id, + :friend_request => friend_request + ) + end + + # create a friend request acceptance message + def friend_request_accepted(receiver_id, photo_url, msg, notification_id, created_at) + friend_request_accepted = Jampb::FriendRequestAccepted.new( + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::FRIEND_REQUEST_ACCEPTED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :friend_request_accepted => friend_request_accepted + ) + end + + def new_user_follower(receiver_id, photo_url, msg, notification_id, created_at) + new_user_follower = Jampb::NewUserFollower.new( + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::NEW_USER_FOLLOWER, + :route_to => USER_TARGET_PREFIX + receiver_id, + :new_user_follower => new_user_follower + ) + end + + def new_band_follower(receiver_id, photo_url, msg, notification_id, created_at) + new_band_follower = Jampb::NewBandFollower.new( + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::NEW_BAND_FOLLOWER, + :route_to => USER_TARGET_PREFIX + receiver_id, + :new_band_follower => new_band_follower + ) + end + + def session_invitation(receiver_id, session_id, msg, notification_id, created_at) + session_invitation = Jampb::SessionInvitation.new( :session_id => session_id, - :user_id => user_id, - :username => username, - :photo_url => photo_url + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::SESSION_INVITATION, + :route_to => USER_TARGET_PREFIX + receiver_id, + :session_invitation => session_invitation + ) + end + + # create a join request session message + def join_request(join_request_id, session_id, photo_url, msg, notification_id, created_at) + req = Jampb::JoinRequest.new( + :join_request_id => join_request_id, + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::JOIN_REQUEST, + :route_to => SESSION_TARGET_PREFIX + session_id, + :join_request => req + ) + end + + # create a join request approved session message + def join_request_approved(join_request_id, session_id, photo_url, msg, notification_id, created_at) + req_approved = Jampb::JoinRequestApproved.new( + :join_request_id => join_request_id, + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::JOIN_REQUEST_APPROVED, + :route_to => SESSION_TARGET_PREFIX + session_id, + :join_request_approved => req_approved + ) + end + + # create a join request rejected session message + def join_request_rejected(join_request_id, session_id, photo_url, msg, notification_id, created_at) + req_rejected = Jampb::JoinRequestRejected.new( + :join_request_id => join_request_id, + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::JOIN_REQUEST_REJECTED, + :route_to => SESSION_TARGET_PREFIX + session_id, + :join_request_rejected => req_rejected + ) + end + + def session_join(session_id, photo_url, msg) + join = Jampb::SessionJoin.new( + :session_id => session_id, + :photo_url => photo_url, + :msg => msg + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::SESSION_JOIN, + :route_to => CLIENT_TARGET, + :session_join => join + ) + end + + def session_depart(session_id, photo_url, msg, recording_id = nil) + left = Jampb::SessionDepart.new( + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :recording_id => recording_id + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::SESSION_DEPART, + :route_to => CLIENT_TARGET, + :session_depart => left + ) + end + + def musician_session_join(receiver_id, session_id, photo_url, msg, notification_id, created_at) + musician_session_join = Jampb::MusicianSessionJoin.new( + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at ) return Jampb::ClientMessage.new( :type => ClientMessage::Type::MUSICIAN_SESSION_JOIN, - :route_to => CLIENT_TARGET, - :musician_session_join => join + :route_to => USER_TARGET_PREFIX + receiver_id, + :musician_session_join => musician_session_join ) end - # create a musician left session message - def musician_session_depart(session_id, user_id, username, photo_url, recordingId = nil) - left = Jampb::MusicianSessionDepart.new( - :session_id => session_id, - :user_id => user_id, - :username => username, + def band_session_join(receiver_id, session_id, photo_url, msg, notification_id, created_at) + band_session_join = Jampb::BandSessionJoin.new( + :session_id => session_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::BAND_SESSION_JOIN, + :route_to => USER_TARGET_PREFIX + receiver_id, + :band_session_join => band_session_join + ) + end + + def musician_recording_saved(receiver_id, recording_id, photo_url, msg, notification_id, created_at) + musician_recording_saved = Jampb::MusicianRecordingSaved.new( + :recording_id => recording_id, :photo_url => photo_url, - :recordingId => recordingId + :msg => msg, + :notification_id => notification_id, + :created_at => created_at ) return Jampb::ClientMessage.new( - :type => ClientMessage::Type::MUSICIAN_SESSION_DEPART, - :route_to => CLIENT_TARGET, - :musician_session_depart => left + :type => ClientMessage::Type::MUSICIAN_RECORDING_SAVED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :musician_recording_saved => musician_recording_saved + ) + end + + def band_recording_saved(receiver_id, recording_id, photo_url, msg, notification_id, created_at) + band_recording_saved = Jampb::BandRecordingSaved.new( + :recording_id => recording_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::BAND_RECORDING_SAVED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :band_recording_saved => band_recording_saved + ) + end + + def recording_started(receiver_id, photo_url, msg) + recording_started = Jampb::RecordingStarted.new( + :photo_url => photo_url, + :msg => msg + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::RECORDING_STARTED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :recording_started => recording_started + ) + end + + def recording_ended(receiver_id, photo_url, msg) + recording_ended = Jampb::RecordingEnded.new( + :photo_url => photo_url, + :msg => msg + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::RECORDING_ENDED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :recording_ended => recording_ended + ) + end + + def recording_master_mix_complete + end + + # create a band invitation message + def band_invitation(receiver_id, invitation_id, band_id, photo_url, msg, notification_id, created_at) + band_invitation = Jampb::BandInvitation.new( + :band_invitation_id => invitation_id, + :band_id => band_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::BAND_INVITATION, + :route_to => USER_TARGET_PREFIX + receiver_id, + :band_invitation => band_invitation + ) + end + + # create a band invitation acceptance message + def band_invitation_accepted(receiver_id, invitation_id, photo_url, msg, notification_id, created_at) + band_invitation_accepted = Jampb::BandInvitationAccepted.new( + :band_invitation_id => invitation_id, + :photo_url => photo_url, + :msg => msg, + :notification_id => notification_id, + :created_at => created_at + ) + + return Jampb::ClientMessage.new( + :type => ClientMessage::Type::BAND_INVITATION_ACCEPTED, + :route_to => USER_TARGET_PREFIX + receiver_id, + :band_invitation_accepted => band_invitation_accepted ) end @@ -253,183 +533,14 @@ ) end - # create a join request session message - def join_request(join_request_id, session_id, username, photo_url, msg, notification_id, created_at) - req = Jampb::JoinRequest.new( - :join_request_id => join_request_id, - :session_id => session_id, - :username => username, - :photo_url => photo_url, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::JOIN_REQUEST, - :route_to => SESSION_TARGET_PREFIX + session_id, - :join_request => req - ) - end - - # create a join request approved session message - def join_request_approved(join_request_id, session_id, username, photo_url, msg, notification_id, created_at) - req_approved = Jampb::JoinRequestApproved.new( - :join_request_id => join_request_id, - :session_id => session_id, - :username => username, - :photo_url => photo_url, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::JOIN_REQUEST_APPROVED, - :route_to => SESSION_TARGET_PREFIX + session_id, - :join_request_approved => req_approved - ) - end - - # create a join request rejected session message - def join_request_rejected(join_request_id, session_id, username, photo_url, msg, notification_id, created_at) - req_rejected = Jampb::JoinRequestRejected.new( - :join_request_id => join_request_id, - :session_id => session_id, - :username => username, - :photo_url => photo_url, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::JOIN_REQUEST_REJECTED, - :route_to => SESSION_TARGET_PREFIX + session_id, - :join_request_rejected => req_rejected - ) - end - - # create a band invitation message - def band_invitation(invitation_id, band_id, receiver_id, username, photo_url, band_name, msg, notification_id, created_at) - band_invitation = Jampb::BandInvitation.new( - :band_invitation_id => invitation_id, - :band_id => band_id, - :user_id => receiver_id, - :username => username, - :photo_url => photo_url, - :band_name => band_name, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::BAND_INVITATION, - :route_to => USER_TARGET_PREFIX + receiver_id, - :band_invitation => band_invitation - ) - end - - # create a band invitation acceptance message - def band_invitation_accepted(invitation_id, receiver_id, username, photo_url, band_name, msg, notification_id, created_at) - band_invitation_accepted = Jampb::BandInvitationAccepted.new( - :band_invitation_id => invitation_id, - :user_id => receiver_id, - :username => username, - :photo_url => photo_url, - :band_name => band_name, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::BAND_INVITATION_ACCEPTED, - :route_to => USER_TARGET_PREFIX + receiver_id, - :band_invitation_accepted => band_invitation_accepted - ) - end - - # create a test message to send in session - def test_session_message(session_id, msg) - test = Jampb::TestSessionMessage.new(:msg => msg) + # create a test message to send in session + def test_session_message(session_id, msg) + test = Jampb::TestSessionMessage.new(:msg => msg) return Jampb::ClientMessage.new( :type => ClientMessage::Type::TEST_SESSION_MESSAGE, :route_to => SESSION_TARGET_PREFIX + session_id, :test_session_message => test - ) - end - - def session_invitation(receiver_id, sender_name, session_id, notification_id, created_at) - session_invitation = Jampb::SessionInvitation.new( - :sender_name => sender_name, - :session_id => session_id, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::SESSION_INVITATION, - :route_to => USER_TARGET_PREFIX + receiver_id, - :session_invitation => session_invitation - ) - end - - # create a friend update message - def friend_update(user_id, name, photo_url, online, msg) - friend = Jampb::FriendUpdate.new( - :user_id => user_id, - :name => name, - :photo_url => photo_url, - :online => online, - :msg => msg - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::FRIEND_UPDATE, - :route_to => USER_TARGET_PREFIX + user_id, - :friend_update => friend - ) - end - - # create a friend request message - def friend_request(friend_request_id, user_id, name, photo_url, friend_id, msg, notification_id, created_at) - friend_request = Jampb::FriendRequest.new( - :friend_request_id => friend_request_id, - :user_id => user_id, - :name => name, - :photo_url => photo_url, - :friend_id => friend_id, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::FRIEND_REQUEST, - :route_to => USER_TARGET_PREFIX + friend_id, - :friend_request => friend_request - ) - end - - # create a friend request acceptance message - def friend_request_accepted(friend_id, name, photo_url, user_id, msg, notification_id, created_at) - friend_request_accepted = Jampb::FriendRequestAccepted.new( - :friend_id => friend_id, - :name => name, - :photo_url => photo_url, - :user_id => user_id, - :msg => msg, - :notification_id => notification_id, - :created_at => created_at - ) - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::FRIEND_REQUEST_ACCEPTED, - :route_to => USER_TARGET_PREFIX + user_id, - :friend_request_accepted => friend_request_accepted ) end @@ -473,28 +584,6 @@ #################################################### - # create a heartbeat - def heartbeat() - heartbeat = Jampb::Heartbeat.new - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::HEARTBEAT, - :route_to => SERVER_TARGET, - :heartbeat => heartbeat - ) - end - - # create a heartbeat ack - def heartbeat_ack() - heartbeat_ack = Jampb::HeartbeatAck.new - - return Jampb::ClientMessage.new( - :type => ClientMessage::Type::HEARTBEAT_ACK, - :route_to => CLIENT_TARGET, - :heartbeat_ack => heartbeat_ack - ) - end - # is this message directed to the server? def server_directed? msg return msg.route_to == MessageFactory::SERVER_TARGET @@ -519,8 +608,8 @@ return msg.route_to[MessageFactory::SESSION_TARGET_PREFIX..-1] end - def get_message_type msg - return @type_values[msg.type] - end + def get_message_type msg + return @type_values[msg.type] + end end end diff --git a/ruby/lib/jam_ruby/models/notification.rb b/ruby/lib/jam_ruby/models/notification.rb index 5c54cdd00..220b9bfd9 100644 --- a/ruby/lib/jam_ruby/models/notification.rb +++ b/ruby/lib/jam_ruby/models/notification.rb @@ -12,8 +12,7 @@ module JamRuby belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id" def index(user_id) - results = Notification.where(:target_user_id => user_id).limit(50) - return results + Notification.where(:target_user_id => user_id).limit(50) end def photo_url @@ -25,37 +24,17 @@ module JamRuby # used for persisted notifications def formatted_msg # target_user, band, session, recording, invitation, join_request = nil - source_user = nil - - # unless self.target_user_id.nil? - # target_user = User.find(self.target_user_id) - # end + source_user, band = nil unless self.source_user_id.nil? source_user = User.find(self.source_user_id) end - # unless self.band_id.nil? - # band = Band.find(self.band_id) - # end + unless self.band_id.nil? + band = Band.find(self.band_id) + end - # unless self.session_id.nil? - # session = MusicSession.find(self.session_id) - # end - - # unless self.recording_id.nil? - # recording = Recording.find(self.recording_id) - # end - - # unless self.invitation_id.nil? - # invitation = Invitation.find(self.invitation_id) - # end - - # unless self.join_request_id.nil? - # join_request = JoinRequest.find(self.join_request_id) - # end - - return self.class.format_msg(self.description, source_user) + return self.class.format_msg(self.description, source_user, band) end # TODO: MAKE ALL METHODS BELOW ASYNC SO THE CLIENT DOESN'T BLOCK ON NOTIFICATION LOGIC @@ -81,7 +60,7 @@ module JamRuby return friend_ids end - def retrieve_followers(connection, user_id) + def retrieve_user_followers(connection, user_id) follower_ids = [] connection.exec("SELECT uf.follower_id as friend_id FROM users_followers uf WHERE uf.user_id = $1", [user_id]) do |follower_results| follower_results.each do |follower_result| @@ -91,9 +70,20 @@ module JamRuby return follower_ids end + def retrieve_friends_not_in_session(connection, user_id, session_id) + ids = retrieve_friends(connection, user_id) + connection.exec("SELECT c.user_id as musician_id FROM connections c WHERE c.music_session_id = $1", [session_id]) do |musicians| + musicians.each do |musician_result| + # remove users who are in the session + ids.reject! {|item| item == musician_result['musician_id']} + end + end + return ids + end + def retrieve_friends_and_followers(connection, user_id) ids = retrieve_friends(connection, user_id) - ids.concat(retrieve_followers(connection, user_id)) + ids.concat(retrieve_user_followers(connection, user_id)) ids.uniq! {|id| id} return ids end @@ -109,15 +99,21 @@ module JamRuby return ids end - def format_msg(description, user = nil) - name = "" + def format_msg(description, user = nil, band = nil) + name, band_name = "" unless user.nil? name = user.name else name = "Someone" end + if !band.nil? + band_name = band.name + end + case description + + # friend notifications when NotificationTypes::FRIEND_UPDATE return "#{name} is now " @@ -127,15 +123,13 @@ module JamRuby when NotificationTypes::FRIEND_REQUEST_ACCEPTED return "#{name} has accepted your friend request." - when NotificationTypes::FRIEND_SESSION_JOIN - return "#{name} has joined the session." + when NotificationTypes::NEW_USER_FOLLOWER + return "#{name} is now following you on JamKazam." - when NotificationTypes::MUSICIAN_SESSION_JOIN - return "#{name} has joined the session." - - when NotificationTypes::MUSICIAN_SESSION_DEPART - return "#{name} has left the session." + when NotificationTypes::NEW_BAND_FOLLOWER + return "#{name} is now following your band #{band.name} on JamKazam." + # session notifications when NotificationTypes::SESSION_INVITATION return "#{name} has invited you to a session." @@ -148,46 +142,72 @@ module JamRuby when NotificationTypes::JOIN_REQUEST_REJECTED return "We're sorry, but you cannot join the session at this time." + when NotificationTypes::SESSION_JOIN + return "#{name} has joined the session." + + when NotificationTypes::SESSION_DEPART + return "#{name} has left the session." + + when NotificationTypes::MUSICIAN_SESSION_JOIN + return "#{name} is now in a session." + + when NotificationTypes::BAND_SESSION_JOIN + return "#{band_name} is now in a session." + + + # recording notifications + when NotificationTypes::MUSICIAN_RECORDING_SAVED + return "#{name} has made a new recording." + + when NotificationTypes::BAND_RECORDING_SAVED + return "#{band.name} has made a new recording." + + when NotificationTypes::RECORDING_STARTED + return "#{name} has started a recording." + + when NotificationTypes::RECORDING_ENDED + return "#{name} has stopped recording." + + when NotificationTypes::RECORDING_MASTER_MIX_COMPLETE + return "This recording has been mastered and mixed and is ready to share." + + + # band notifications when NotificationTypes::BAND_INVITATION - return "You have been invited to join the band #{name}." + return "You have been invited to join the band #{band_name}." when NotificationTypes::BAND_INVITATION_ACCEPTED - return "#{name} has accepted your band invitation." + return "#{name} has accepted your band invitation to join #{band_name}." else return "" end end - ################### FRIEND UPDATE ################### def send_friend_update(user_id, online, connection) - # (1) get all of this user's friends friend_ids = retrieve_friends(connection, user_id) - unless friend_ids.blank? + unless friend_ids.empty? user = User.find(user_id) - # (2) create notification online_msg = online ? "online." : "offline." notification_msg = format_msg(NotificationTypes::FRIEND_UPDATE, user) + online_msg msg = @@message_factory.friend_update( - user_id, user.name, + user.id, user.photo_url, online, notification_msg ) - # (3) send notification @@mq_router.publish_to_friends(friend_ids, msg, user_id) end end - ################### FRIEND REQUEST ################### def send_friend_request(friend_request_id, user_id, friend_id) user = User.find(user_id) + friend = User.find(friend_id) - # (1) save to database notification = Notification.new notification.description = NotificationTypes::FRIEND_REQUEST notification.source_user_id = user_id @@ -195,157 +215,151 @@ module JamRuby notification.friend_request_id = friend_request_id notification.save - # (2) create notification notification_msg = format_msg(notification.description, user) - msg = @@message_factory.friend_request( - friend_request_id, - user_id, - user.name, - user.photo_url, - friend_id, - notification_msg, - notification.id, - notification.created_at.to_s - ) - # (3) send notification - @@mq_router.publish_to_user(friend_id, msg) + if friend.online + msg = @@message_factory.friend_request( + friend.id, + friend_request_id, + user.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(friend_id, msg) + + else + UserMailer.friend_request(friend.email, notification_msg) + end end - ############### FRIEND REQUEST ACCEPTED ############### def send_friend_request_accepted(user_id, friend_id) friend = User.find(friend_id) + user = User.find(user_id) - # (1) save to database notification = Notification.new notification.description = NotificationTypes::FRIEND_REQUEST_ACCEPTED notification.source_user_id = friend_id notification.target_user_id = user_id notification.save - # (2) create notification notification_msg = format_msg(notification.description, friend) - msg = @@message_factory.friend_request_accepted( - friend_id, - friend.name, - friend.photo_url, - user_id, notification_msg, - notification.id, - notification.created_at.to_s - ) - # (3) send notification - @@mq_router.publish_to_user(user_id, msg) - end - - ################## SESSION INVITATION ################## - def send_session_invitation(receiver_id, sender, session_id) - - # (1) save to database - notification = Notification.new - notification.description = NotificationTypes::SESSION_INVITATION - notification.source_user_id = sender.id - notification.target_user_id = receiver_id - notification.session_id = session_id - notification.save - - # (2) create notification - msg = @@message_factory.session_invitation( - receiver_id, - sender.name, - session_id, - notification.id, - notification.created_at.to_s - ) - - # (3) send notification - @@mq_router.publish_to_user(receiver_id, msg) - end - - ################## SESSION INVITATION ################## - def send_musician_session_join(music_session, connection, user) - - # (1) create notification - msg = @@message_factory.musician_session_join( - music_session.id, - user.id, - user.name, - user.photo_url - ) - - # (2) send notification - @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => connection.client_id}) - end - - ################## MUSICIAN SESSION DEPART ################## - def send_musician_session_depart(music_session, client_id, user, recordingId = nil) - - # (1) create notification - msg = @@message_factory.musician_session_depart( - music_session.id, - user.id, - user.name, - user.photo_url, - recordingId - ) - - # (2) send notification - @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) - end - - ################## MUSICIAN SESSION FRESH ################## - def send_musician_session_fresh(music_session, client_id, user) - - # (1) create notification - msg = @@message_factory.musician_session_fresh( - music_session.id, - user.id, - user.name, - user.photo_url - ) - - # (2) send notification - @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) - end - - ################## MUSICIAN SESSION STALE ################## - def send_musician_session_stale(music_session, client_id, user) - - # (1) create notification - msg = @@message_factory.musician_session_stale( - music_session.id, - user.id, - user.name, - user.photo_url - ) - - # (2) send notification - @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) - end - - ################## FRIEND SESSION JOIN ################## - def send_friend_session_join(db_conn, connection, user) - ids = retrieve_friends_and_followers_not_in_session(db_conn, user.id, connection.music_session.id) - - if ids.length > 0 - # (1) save to database - - # (2) create notification - msg = @@message_factory.friend_session_join( - connection.music_session.id, + if user.online + msg = @@message_factory.friend_request_accepted( user.id, - user.name, - user.photo_url) + friend.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) - # (3) send notification - @@mq_router.publish_to_friends(ids, msg, sender = {:client_id => connection.client_id}) + @@mq_router.publish_to_user(user.id, msg) + + else + UserMailer.friend_request_accepted(user.email, notification_msg) end end - ################## JOIN REQUEST ################## + def send_new_user_follower(follower, user) + + notification = Notification.new + notification.description = NotificationTypes::NEW_USER_FOLLOWER + notification.source_user_id = follower.id + notification.target_user_id = user.id + notification.save + + notification_msg = format_msg(notification.description, follower) + + if follower.id != user.id + if user.online + msg = @@message_factory.new_user_follower( + user.id, + follower.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(user.id, msg) + + else + UserMailer.new_user_follower(user.email, notification_msg) + end + end + end + + def send_new_band_follower(follower, band) + + notifications = [] + + band.band_musicians.each.each do |bm| + + notification = Notification.new + notification.description = NotificationTypes::NEW_BAND_FOLLOWER + notification.source_user_id = follower.id + notification.target_user_id = bm.user_id + notification.band_id = band.id + notification.save + + notification_msg = format_msg(notification.description, follower, band) + + # this protects against sending the notification to a band member who decides to follow the band + if follower.id != bm.user.id + if bm.user.online + msg = @@message_factory.new_user_follower( + bm.user_id, + follower.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(bm.user_id, msg) + + else + UserMailer.new_band_follower(bm.user.email, notification_msg) + end + end + end + end + + def send_session_invitation(receiver, sender, session_id) + + notification = Notification.new + notification.description = NotificationTypes::SESSION_INVITATION + notification.source_user_id = sender.id + notification.target_user_id = receiver.id + notification.session_id = session_id + notification.save + + notification_msg = format_msg(NotificationTypes::SESSION_INVITATION, sender) + + if receiver.online + msg = @@message_factory.session_invitation( + receiver.id, + session_id, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(receiver.id, msg) + + else + UserMailer.session_invitation(receiver.email, notification_msg) + end + end + + def send_session_ended(music_session, connection) + + # TODO: this should actually publish to all users who have a notification for this session + @@mq_router.server_publish_to_session(music_session, nil, sender = {:client_id => connection.client_id}) + end + def send_join_request(music_session, join_request, text) - # (1) save to database notification = Notification.new notification.description = NotificationTypes::JOIN_REQUEST notification.source_user_id = join_request.user.id @@ -353,26 +367,22 @@ module JamRuby notification.session_id = music_session.id notification.save - # (2) create notification notification_msg = format_msg(notification.description, join_request.user) + msg = @@message_factory.join_request( join_request.id, music_session.id, - join_request.user.name, join_request.user.photo_url, notification_msg, notification.id, notification.created_at.to_s ) - # (3) send notification @@mq_router.publish_to_user(music_session.creator.id, msg) end - ################## JOIN REQUEST APPROVED ################## def send_join_request_approved(music_session, join_request) - # (1) save to database notification = Notification.new notification.description = NotificationTypes::JOIN_REQUEST_APPROVED notification.source_user_id = music_session.creator.id @@ -380,26 +390,22 @@ module JamRuby notification.session_id = music_session.id notification.save - # (2) create notification notification_msg = format_msg(notification.description, music_session.creator) + msg = @@message_factory.join_request_approved( join_request.id, music_session.id, - music_session.creator.name, music_session.creator.photo_url, notification_msg, notification.id, notification.created_at.to_s ) - # (3) send notification @@mq_router.publish_to_user(join_request.user.id, msg) end - ################## JOIN REQUEST REJECTED ################## def send_join_request_rejected(music_session, join_request) - # (1) save to database notification = Notification.new notification.description = NotificationTypes::JOIN_REQUEST_REJECTED notification.source_user_id = music_session.creator.id @@ -407,26 +413,255 @@ module JamRuby notification.session_id = music_session.id notification.save - # (2) create notification notification_msg = format_msg(notification.description, music_session.creator) + msg = @@message_factory.join_request_rejected( join_request.id, music_session.id, - music_session.creator.name, music_session.creator.photo_url, - notification_msg, notification.id, notification.created_at.to_s ) - # (3) send notification @@mq_router.publish_to_user(join_request.user.id, msg) end - ################## BAND INVITATION ################## + def send_session_join(music_session, connection, user) + + notification_msg = format_msg(NotificationTypes::SESSION_JOIN, user) + + msg = @@message_factory.session_join( + music_session.id, + user.photo_url, + notification_msg + ) + + @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => connection.client_id}) + end + + def send_session_depart(music_session, client_id, user, recordingId = nil) + + notification_msg = format_msg(NotificationTypes::SESSION_DEPART, user) + + msg = @@message_factory.session_depart( + music_session.id, + user.photo_url, + notification_msg, + recordingId + ) + + @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) + end + + def send_musician_session_join(music_session, connection, user) + + if music_session.musician_access || music_session.fan_access + + friends = Friendship.where(:friend_id => user.id) + user_followers = UserFollower.where(:user_id => user.id) + + # construct an array of User objects representing friends and followers + friend_users = friends.map { |fu| fu.user } + follower_users = user_followers.map { |uf| uf.follower } + friends_and_followers = friend_users.concat(follower_users).uniq + + # remove anyone in the session + friends_and_followers = friends_and_followers - music_session.users + notifications, online_ff, offline_ff = [], [], [] + notification_msg = format_msg(NotificationTypes::MUSICIAN_SESSION_JOIN, user) + + friends_and_followers.each do |ff| + if (ff.musician && music_session.musician_access) || (!ff.musician && music_session.fan_access) + notification = Notification.new + notification.description = NotificationTypes::MUSICIAN_SESSION_JOIN + notification.source_user_id = user.id + notification.target_user_id = ff.id + notification.save + + if ff.online + msg = @@message_factory.musician_session_join( + ff.id, + music_session.id, + user.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(ff.id, msg) + else + offline_ff << ff + end + end + end + + # send email notifications + unless offline_ff.empty? + UserMailer.musician_session_join(offline_ff.map! {|f| f.email}, notification_msg) + end + end + end + + def send_band_session_join(music_session, band) + + # if the session is private, don't send any notifications + if music_session.musician_access || music_session.fan_access + + band_followers = BandFollower.where(:band_id => band.id) + + notifications, online_followers, offline_followers = [], [], [] + notification_msg = format_msg(NotificationTypes::BAND_SESSION_JOIN, nil, band) + + band_followers.each do |bf| + if (bf.follower.musician && music_session.musician_access) || (!bf.follower.musician && music_session.fan_access) + notification = Notification.new + notification.band_id = band.id + notification.description = NotificationTypes::BAND_SESSION_JOIN + notification.target_user_id = bf.follower.id + notification.save + + if bf.follower.online + msg = @@message_factory.band_session_join( + bf.follower.id, + music_session.id, + band.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(bf.follower.id, msg) + else + offline_followers << bf.follower + end + end + end + + # send email notifications + unless offline_followers.empty? + UserMailer.band_session_join(offline_followers.map! {|f| f.email}, notification_msg) + end + end + end + + def send_musician_recording_saved(recording) + + user = recording.owner + + friends = Friendship.where(:friend_id => user.id) + user_followers = UserFollower.where(:user_id => user.id) + + # construct an array of User objects representing friends and followers + friend_users = friends.map { |fu| fu.friend } + follower_users = user_followers.map { |uf| uf.follower } + friends_and_followers = friend_users.concat(follower_users).uniq + + notifications, online_ff, offline_ff = [], [], [] + notification_msg = format_msg(NotificationTypes::MUSICIAN_RECORDING_SAVED, user) + + friends_and_followers.each do |ff| + notification = Notification.new + notification.description = NotificationTypes::MUSICIAN_SESSION_JOIN + notification.source_user_id = user.id + notification.target_user_id = ff.id + notification.save + + if ff.online + msg = @@message_factory.musician_recording_saved( + ff.id, + recording.id, + user.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(ff.id, notification_msg) + else + offline_ff << ff + end + end + + # send email notifications + unless offline_ff.empty? + UserMailer.musician_recording_saved(offline_ff.map! {|f| f.email}, notification_msg) + end + end + + def send_band_recording_saved(recording) + + band_followers = BandFollower.where(:band_id => band.id) + notification_msg = format_msg(NotificationTypes::BAND_RECORDING_SAVED, nil, recording.band) + + band_followers.each do |bf| + notification = Notification.new + notification.description = NotificationTypes::BAND_RECORDING_SAVED + notification.band_id = band.id + notification.target_user_id = bf.follower.id + notification.recording_id = recording.id + notification.save + + if bf.follower.online + msg = @@message_factory.band_recording_saved( + bf.follower.id, + recording.id, + band.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(of.id, notification_msg) + else + offline_followers << bf.follower + end + end + + # send email notifications + unless offline_followers.empty? + UserMailer.band_recording_saved(offline_followers.map! {|f| f.email}, notification_msg) + end + end + + def send_recording_started(music_session, connection, user) + + notification_msg = format_msg(NotificationTypes::RECORDING_STARTED, user) + + music_session.users.each do |musician| + if musician.id != user.id + msg = @@message_factory.recording_started( + musician.id, + user.photo_url, + notification_msg + ) + + @@mq_router.publish_to_user(musician.id, msg) + end + end + end + + def send_recording_ended(music_session, connection, user) + + notification_msg = format_msg(NotificationTypes::RECORDING_ENDED, user) + + music_session.users.each do |musician| + if musician.id != user.id + msg = @@message_factory.recording_ended( + musician.id, + user.photo_url, + notification_msg + ) + + @@mq_router.publish_to_user(musician.id, msg) + end + end + end + + def send_recording_master_mix_complete(recording) + end + def send_band_invitation(band, band_invitation, sender, receiver) - # (1) save to database notification = Notification.new notification.band_id = band.id notification.band_invitation_id = band_invitation.id @@ -435,28 +670,28 @@ module JamRuby notification.target_user_id = receiver.id notification.save - # (2) create notification - notification_msg = format_msg(notification.description, band) - msg = @@message_factory.band_invitation( - band_invitation.id, - band.id, - receiver.id, - sender.name, - sender.photo_url, - band.name, - notification_msg, - notification.id, - notification.created_at.to_s - ) + notification_msg = format_msg(notification.description, nil, band) - # (3) send notification - @@mq_router.publish_to_user(receiver.id, msg) + if receiver.online + msg = @@message_factory.band_invitation( + receiver.id, + band_invitation.id, + band.id, + sender.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + + @@mq_router.publish_to_user(receiver.id, msg) + + else + UserMailer.band_invitation(receiver.email, notification_msg) + end end - ################## BAND INVITATION ACCEPTED ################## def send_band_invitation_accepted(band, band_invitation, sender, receiver) - # (1) save to database notification = Notification.new notification.band_id = band.id notification.description = NotificationTypes::BAND_INVITATION_ACCEPTED @@ -464,23 +699,47 @@ module JamRuby notification.target_user_id = receiver.id notification.save - # (2) create notification - notification_msg = format_msg(notification.description, sender) - msg = @@message_factory.band_invitation_accepted( - band_invitation.id, - receiver.id, - sender.name, - sender.photo_url, - band.name, - notification_msg, - notification.id, - notification.created_at.to_s - ) + notification_msg = format_msg(notification.description, sender, band) - # (3) send notification - @@mq_router.publish_to_user(receiver.id, msg) + if receiver.online + msg = @@message_factory.band_invitation_accepted( + receiver.id, + band_invitation.id, + sender.photo_url, + notification_msg, + notification.id, + notification.created_at.to_s + ) + @@mq_router.publish_to_user(receiver.id, msg) + + else + UserMailer.band_invitation_accepted(receiver.email, notification_msg) + end end + def send_musician_session_fresh(music_session, client_id, user) + + msg = @@message_factory.musician_session_fresh( + music_session.id, + user.id, + user.name, + user.photo_url + ) + + @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) + end + + def send_musician_session_stale(music_session, client_id, user) + + msg = @@message_factory.musician_session_stale( + music_session.id, + user.id, + user.name, + user.photo_url + ) + + @@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => client_id}) + end end end end \ No newline at end of file diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 78c244f29..2fb51f7a7 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -87,16 +87,9 @@ module JamRuby end end end - - # FIXME: - # NEED TO SEND NOTIFICATION TO ALL USERS IN THE SESSION THAT RECORDING HAS STARTED HERE. - # I'LL STUB IT A BIT. NOTE THAT I REDO THE FIND HERE BECAUSE I DON'T WANT TO SEND THESE - # NOTIFICATIONS WHILE THE DB ROW IS LOCKED - #music_session = MusicSession.find(music_session_id) - #music_session.connections.each do |connection| - # # connection.notify_recording_has_started - #end + connection = Connection.where(:user_id => owner.id).where(:music_session_id => music_session.id).first + Notification.send_recording_started(music_session, connection, owner) recording end @@ -111,6 +104,10 @@ module JamRuby self.is_done = true self.save end + + connection = Connection.where(:user_id => self.owner.id).where(:music_session_id => music_session.id).first + Notification.send_recording_ended(music_session, connection, self.owner) + self end diff --git a/ruby/lib/jam_ruby/models/user.rb b/ruby/lib/jam_ruby/models/user.rb index 4c52c4170..60a3b4dd6 100644 --- a/ruby/lib/jam_ruby/models/user.rb +++ b/ruby/lib/jam_ruby/models/user.rb @@ -549,6 +549,28 @@ module JamRuby self.save end + def create_user_following(user_id) + follower = UserFollower.new + follower.user_id = user_id + follower.follower_id = self.id + follower.save + + # TODO: make this async + user = User.find(user_id) + Notification.send_new_user_follower(self, user) + end + + def create_band_following(band_id) + follower = BandFollower.new + follower.band_id = band_id + follower.follower_id = self.id + follower.save + + # TODO: make this async + band = Band.find(band_id) + Notification.send_new_band_follower(self, band) + end + def self.finalize_update_email(update_email_token) # updates the user model to have a new email address user = User.find_by_update_email_token!(update_email_token) @@ -561,7 +583,6 @@ module JamRuby return user end - def self.create_user_like(user_id, liker_id) liker = UserLiker.new() liker.user_id = user_id @@ -579,7 +600,7 @@ module JamRuby end def self.create_band_like(band_id, liker_id) - liker = BandLiker.new() + liker = BandLiker.new liker.band_id = band_id liker.liker_id = liker_id liker.save @@ -589,13 +610,6 @@ module JamRuby JamRuby::BandLiker.delete_all "(band_id = '#{band_id}' AND liker_id = '#{liker_id}')" end - def self.create_user_following(user_id, follower_id) - follower = UserFollower.new() - follower.user_id = user_id - follower.follower_id = follower_id - follower.save - end - def self.delete_following(user_id, band_id, follower_id) if !user_id.nil? JamRuby::UserFollower.delete_all "(user_id = '#{user_id}' AND follower_id = '#{follower_id}')" @@ -605,19 +619,12 @@ module JamRuby end end - def self.create_band_following(band_id, follower_id) - follower = BandFollower.new() - follower.band_id = band_id - follower.follower_id = follower_id - follower.save - end - def self.delete_band_following(band_id, follower_id) JamRuby::BandFollower.delete_all "(band_id = '#{band_id}' AND follower_id = '#{follower_id}')" end def self.create_favorite(user_id, recording_id) - favorite = UserFavorite.new() + favorite = UserFavorite.new favorite.user_id = user_id favorite.recording_id = recording_id favorite.save diff --git a/ruby/lib/jam_ruby/mq_router.rb b/ruby/lib/jam_ruby/mq_router.rb index 8fb3b30a6..087bace44 100644 --- a/ruby/lib/jam_ruby/mq_router.rb +++ b/ruby/lib/jam_ruby/mq_router.rb @@ -89,7 +89,7 @@ class MQRouter def publish_to_friends(friend_ids, user_msg, from_user_id) EM.schedule do friend_ids.each do |friend_id| - @@log.debug "publishing to friend:#{friend_id} from user #{from_user_id}" + @@log.debug "publishing to friend:#{friend_id} from user/band #{from_user_id}" # put it on the topic exchange for users self.class.user_exchange.publish(user_msg, :routing_key => "user.#{friend_id}") end diff --git a/ruby/spec/jam_ruby/models/mix_spec.rb b/ruby/spec/jam_ruby/models/mix_spec.rb index 12f549bd6..3c902b492 100755 --- a/ruby/spec/jam_ruby/models/mix_spec.rb +++ b/ruby/spec/jam_ruby/models/mix_spec.rb @@ -11,7 +11,7 @@ describe Mix do @music_session.save @recording = Recording.start(@music_session, @user) @recording.stop - @recording.claim(@user, "name", "description", Genre.first, true, true) + @recording.claim(@user, "name", "description", Genre.first, true, true) @mix = Mix.schedule(@recording, "{}") end diff --git a/web/Gemfile b/web/Gemfile index 414a1fb47..86d95f4a4 100644 --- a/web/Gemfile +++ b/web/Gemfile @@ -65,6 +65,7 @@ gem "bugsnag" group :development, :test do gem 'rspec-rails' + gem "activerecord-import", "~> 0.4.1" gem 'guard-rspec', '0.5.5' gem 'jasmine', '1.3.1' gem 'pry' diff --git a/web/app/assets/javascripts/AAB_message_factory.js b/web/app/assets/javascripts/AAB_message_factory.js index b648b7ec9..e45d11c86 100644 --- a/web/app/assets/javascripts/AAB_message_factory.js +++ b/web/app/assets/javascripts/AAB_message_factory.js @@ -12,22 +12,41 @@ LOGIN_ACK : "LOGIN_ACK", LOGIN_MUSIC_SESSION : "LOGIN_MUSIC_SESSION", LOGIN_MUSIC_SESSION_ACK : "LOGIN_MUSIC_SESSION_ACK", - FRIEND_SESSION_JOIN : "FRIEND_SESSION_JOIN", - MUSICIAN_SESSION_JOIN : "MUSICIAN_SESSION_JOIN", - MUSICIAN_SESSION_DEPART : "MUSICIAN_SESSION_DEPART", LEAVE_MUSIC_SESSION : "LEAVE_MUSIC_SESSION", LEAVE_MUSIC_SESSION_ACK : "LEAVE_MUSIC_SESSION_ACK", HEARTBEAT : "HEARTBEAT", HEARTBEAT_ACK : "HEARTBEAT_ACK", + + // friend notifications FRIEND_UPDATE : "FRIEND_UPDATE", + FRIEND_REQUEST : "FRIEND_REQUEST", + FRIEND_REQUEST_ACCEPTED : "FRIEND_REQUEST_ACCEPTED", + FRIEND_SESSION_JOIN : "FRIEND_SESSION_JOIN", + NEW_USER_FOLLOWER : "NEW_USER_FOLLOWER", + NEW_BAND_FOLLOWER : "NEW_BAND_FOLLOWER", + + // session notifications SESSION_INVITATION : "SESSION_INVITATION", + SESSION_ENDED : "SESSION_ENDED", JOIN_REQUEST : "JOIN_REQUEST", JOIN_REQUEST_APPROVED : "JOIN_REQUEST_APPROVED", JOIN_REQUEST_REJECTED : "JOIN_REQUEST_REJECTED", - FRIEND_REQUEST : "FRIEND_REQUEST", - FRIEND_REQUEST_ACCEPTED : "FRIEND_REQUEST_ACCEPTED", + SESSION_JOIN : "SESSION_JOIN", + SESSION_DEPART : "SESSION_DEPART", + MUSICIAN_SESSION_JOIN : "MUSICIAN_SESSION_JOIN", + BAND_SESSION_JOIN : "BAND_SESSION_JOIN", + + // recording notifications + MUSICIAN_RECORDING_SAVED : "MUSICIAN_RECORDING_SAVED", + BAND_RECORDING_SAVED : "BAND_RECORDING_SAVED", + RECORDING_STARTED : "RECORDING_STARTED", + RECORDING_ENDED : "RECORDING_ENDED", + RECORDING_MASTER_MIX_COMPLETE : "RECORDING_MASTER_MIX_COMPLETE", + + // band notifications BAND_INVITATION : "BAND_INVITATION", BAND_INVITATION_ACCEPTED : "BAND_INVITATION_ACCEPTED", + TEST_SESSION_MESSAGE : "TEST_SESSION_MESSAGE", PING_REQUEST : "PING_REQUEST", PING_ACK : "PING_ACK", @@ -84,10 +103,10 @@ // reconnect_music_session_id is an optional argument that allows the session to be immediately associated // with a music session. factory.login_with_token = function(token, reconnect_music_session_id) { - //context.JK.logger.debug("*** login_with_token: client_id = "+$.cookie("client_id")); + //context.JK.logger.debug("*** login_with_token: client_id = "+$.cookie("client_id")); var login = { token : token, - client_id : $.cookie("client_id") - }; + client_id : $.cookie("client_id") + }; return client_container(msg.LOGIN, route_to.SERVER, login); }; diff --git a/web/app/assets/javascripts/profile.js b/web/app/assets/javascripts/profile.js index fb9bab119..967c51839 100644 --- a/web/app/assets/javascripts/profile.js +++ b/web/app/assets/javascripts/profile.js @@ -7,6 +7,7 @@ var logger = context.JK.logger; var userId; var user = null; + var rest = context.JK.Rest(); var instrument_logo_map = context.JK.getInstrumentIconMap24(); @@ -24,13 +25,12 @@ function beforeShow(data) { userId = data.id; - user = null; + user = null; } function afterShow(data) { + initUser(); resetForm(); - events(); - renderActive(); } function resetForm() { @@ -46,83 +46,76 @@ $('.profile-nav a.#profile-about-link').addClass('active'); } - function getUser() { - if (user === null) { - var url = "/api/users/" + userId; - $.ajax({ - type: "GET", - dataType: "json", - url: url, - async: false, - processData:false, - success: function(response) { - user = response; - }, - error: function(jqXHR, textStatus, errorMessage) { - user = null; - app.ajaxError(jqXHR, textStatus, errorMessage); - } - }); - } - return user; - } + function initUser() { + if (user === null) { + rest.getUserDetail({"id": userId}) + .done(function(response) { + user = response; + events(); + renderActive(); + }) + .fail(app.ajaxError); + } + return user; + } - function isMusician() { - if (getUser()) { - return user.musician === true; - } - return false; - } + function isMusician() { + if (user) { + return user.musician === true; + } + return false; + } - function isCurrentUser() { - return userId === context.JK.currentUserId; - } + function isCurrentUser() { + return userId === context.JK.currentUserId; + } - function configureUserType() { - if (isMusician()) { - $('#profile-history-link').show(); - $('#profile-bands-link').show(); - $('#profile-instruments').show(); - $('#profile-session-stats').show(); - $('#profile-recording-stats').show(); + function configureUserType() { + if (isMusician()) { + $('#profile-history-link').show(); + $('#profile-bands-link').show(); + $('#profile-instruments').show(); + $('#profile-session-stats').show(); + $('#profile-recording-stats').show(); - // $('#profile-following-stats').hide(); - // $('#profile-favorites-stats').hide(); + // $('#profile-following-stats').hide(); + // $('#profile-favorites-stats').hide(); - $('#btn-add-friend').show(); + $('#btn-add-friend').show(); $('.profile-social-left').show(); - $('#profile-type-label').text('musician'); - $('#profile-location-label').text('Location'); + $('#profile-type-label').text('musician'); + $('#profile-location-label').text('Location'); + } + else { + $('#profile-history-link').hide(); + $('#profile-bands-link').hide(); + $('#profile-instruments').hide(); + $('#profile-session-stats').hide(); + $('#profile-recording-stats').hide(); - } else { - $('#profile-history-link').hide(); - $('#profile-bands-link').hide(); - $('#profile-instruments').hide(); - $('#profile-session-stats').hide(); - $('#profile-recording-stats').hide(); - - // $('#profile-following-stats').show(); - // $('#profile-favorites-stats').show(); - - $('#btn-add-friend').hide(); + // $('#profile-following-stats').show(); + // $('#profile-favorites-stats').show(); + + $('#btn-add-friend').hide(); $('.profile-social-left').hide(); - $('#profile-type-label').text('fan'); - $('#profile-location-label').text('Presence'); - } + $('#profile-type-label').text('fan'); + $('#profile-location-label').text('Presence'); + } - if (isCurrentUser()) { + if (isCurrentUser()) { $('#btn-profile-edit').show(); - } else { + } + else { $('#btn-profile-edit').hide(); - } - } + } + } /****************** MAIN PORTION OF SCREEN *****************/ // events for main screen function events() { - configureUserType(); + configureUserType(); // wire up panel clicks $('#profile-about-link').click(renderAbout); @@ -168,7 +161,7 @@ } function isFriend() { - return getUser() ? user.is_friend : false; + return user ? user.is_friend : false; } function friendRequestCallback() { @@ -240,7 +233,7 @@ } function isFollowing() { - return getUser() ? user.is_following : false; + return user ? user.is_following : false; } function configureFollowingButton(following) { @@ -300,7 +293,7 @@ function bindAbout() { $('#profile-instruments').empty(); - if (getUser()) { + if (user !== null) { // name $('#profile-username').html(user.name); @@ -338,18 +331,18 @@ text = user.follower_count > 1 || user.follower_count === 0 ? " Followers" : " Follower"; $('#profile-follower-stats').html(user.follower_count + text); - if (isMusician()) { + if (isMusician()) { text = user.session_count > 1 || user.session_count === 0 ? " Sessions" : " Session"; $('#profile-session-stats').html(user.session_count + text); text = user.recording_count > 1 || user.recording_count === 0 ? " Recordings" : " Recording"; $('#profile-recording-stats').html(user.recording_count + text); - } else { + } else { text = " Following"; $('#profile-following-stats').html(user.following_count + text); text = user.favorite_count > 1 || user.favorite_count === 0 ? " Favorites" : " Favorite"; $('#profile-favorite-stats').html(user.favorite_count + text); - } + } $('#profile-biography').html(user.biography); } @@ -373,41 +366,41 @@ $('.profile-nav a.active').removeClass('active'); $('.profile-nav a.#profile-social-link').addClass('active'); - /*if (isMusician()) { + /*if (isMusician()) { $('.profile-social-left').show(); - } else { + } else { $('.profile-social-left').hide(); - }*/ + }*/ bindSocial(); } function bindSocial() { - if (isMusician()) { - // FRIENDS - var url = "/api/users/" + userId + "/friends"; - $.ajax({ - type: "GET", - dataType: "json", - url: url, - async: false, - processData:false, - success: function(response) { - $.each(response, function(index, val) { - var template = $('#template-profile-social').html(); - var friendHtml = context.JK.fillTemplate(template, { - avatar_url: context.JK.resolveAvatarUrl(val.photo_url), - userName: val.name, - location: val.location, - type: "Friends" - }); + if (isMusician()) { + // FRIENDS + var url = "/api/users/" + userId + "/friends"; + $.ajax({ + type: "GET", + dataType: "json", + url: url, + async: false, + processData:false, + success: function(response) { + $.each(response, function(index, val) { + var template = $('#template-profile-social').html(); + var friendHtml = context.JK.fillTemplate(template, { + avatar_url: context.JK.resolveAvatarUrl(val.photo_url), + userName: val.name, + location: val.location, + type: "Friends" + }); - $('#profile-social-friends').append(friendHtml); - }); - }, - error: app.ajaxError - }); - } + $('#profile-social-friends').append(friendHtml); + }); + }, + error: app.ajaxError + }); + } // FOLLOWINGS (USERS) url = "/api/users/" + userId + "/followings"; @@ -614,6 +607,7 @@ var newFollowing = {}; newFollowing.band_id = bandId; + logger.debug("Following band " + bandId); var url = "/api/users/" + context.JK.currentUserId + "/followings"; $.ajax({ @@ -624,6 +618,7 @@ data: JSON.stringify(newFollowing), processData: false, success: function(response) { + logger.debug("following band " + bandId); renderBands(); // refresh stats configureBandFollowingButton(true, bandId); }, diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index e454d5c98..618e88d39 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -156,9 +156,15 @@ acceptFriendRequest({ "friend_request_id": payload.friend_request_id, "notification_id": payload.notification_id }); }); } + else if (type === context.JK.MessageType.FRIEND_REQUEST_ACCEPTED) { $notification.find('#div-actions').hide(); } + + else if (type === context.JK.MessageType.NEW_USER_FOLLOWER || type === context.JK.MessageType.NEW_BAND_FOLLOWER) { + $notification.find('#div-actions').hide(); + } + else if (type === context.JK.MessageType.SESSION_INVITATION) { var $action_btn = $notification.find('#btn-notification-action'); $action_btn.text('JOIN'); @@ -166,6 +172,7 @@ openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id }); }); } + else if (type === context.JK.MessageType.JOIN_REQUEST) { var $action_btn = $notification.find('#btn-notification-action'); $action_btn.text('APPROVE'); @@ -173,6 +180,7 @@ approveJoinRequest({ "join_request_id": payload.join_request_id, "notification_id": payload.notification_id }); }); } + else if (type === context.JK.MessageType.JOIN_REQUEST_APPROVED) { var $action_btn = $notification.find('#btn-notification-action'); $action_btn.text('JOIN'); @@ -180,9 +188,31 @@ openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id }); }); } + else if (type === context.JK.MessageType.JOIN_REQUEST_REJECTED) { $notification.find('#div-actions').hide(); } + + else if (type === context.JK.MessageType.MUSICIAN_SESSION_JOIN || type === context.JK.MessageType.BAND_SESSION_JOIN) { + var $action_btn = $notification.find('#btn-notification-action'); + $action_btn.text('LISTEN'); + $action_btn.click(function() { + listenToSession({ "session_id": payload.session_id, "notification_id": payload.notification_id }); + }); + } + + else if (type === context.JK.MessageType.MUSICIAN_RECORDING_SAVED || type === context.JK.MessageType.BAND_RECORDING_SAVED) { + var $action_btn = $notification.find('#btn-notification-action'); + $action_btn.text('LISTEN'); + $action_btn.click(function() { + listenToRecording({ "recording_id": payload.recording_id, "notification_id": payload.notification_id }); + }); + } + + else if (type === context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE) { + $notification.find('#div-actions').hide(); + } + else if (type === context.JK.MessageType.BAND_INVITATION) { var $action_btn = $notification.find('#btn-notification-action'); $action_btn.text('ACCEPT'); @@ -190,6 +220,7 @@ acceptBandInvitation({ "band_invitation_id": payload.band_invitation_id, "band_id": payload.band_id, "notification_id": payload.notification_id }); }); } + else if (type === context.JK.MessageType.BAND_INVITATION_ACCEPTED) { $notification.find('#div-actions').hide(); } @@ -346,12 +377,7 @@ // default handler for incoming notification function handleNotification(payload, type) { var sidebarText; - if (type === context.JK.MessageType.SESSION_INVITATION) { - sidebarText = payload.sender_name + " has invited you to a session."; - } - else { - sidebarText = payload.msg; - } + sidebarText = payload.msg; // increment displayed notification count incrementNotificationCount(); @@ -421,16 +447,32 @@ $('.sidebar .invite-friend-row').hoverIntent(inviteHoverIn, inviteHoverOut); + // friend notifications registerFriendUpdate(); registerFriendRequest(); registerFriendRequestAccepted(); - registerMusicianSessionJoin(); - registerMusicianSessionDepart(); - registerFriendSessionJoin(); + registerNewUserFollower(); + registerNewBandFollower(); + + // session invitations registerSessionInvitation(); + registerSessionEnded(); registerJoinRequest(); registerJoinRequestApproved(); registerJoinRequestRejected(); + registerSessionJoin(); + registerSessionDepart(); + registerMusicianSessionJoin(); + registerBandSessionJoin(); + + // recording notifications + registerMusicianRecordingSaved(); + registerBandRecordingSaved(); + registerRecordingStarted(); + registerRecordingEnded(); + registerRecordingMasterMixComplete(); + + // band notifications registerBandInvitation(); registerBandInvitationAccepted(); @@ -450,11 +492,9 @@ context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_UPDATE, function(header, payload) { logger.debug("Handling FRIEND_UPDATE msg " + JSON.stringify(payload)); - // update friends panel in sidebar friends[payload.user_id].online = payload.online; updateFriendList(friends); - // display notification var online_text = payload.online ? "online" : "offline"; app.notify({ "title": "Friend is now " + online_text, @@ -470,7 +510,6 @@ handleNotification(payload, header.type); - // display notification app.notify({ "title": "New Friend Request", "text": payload.msg, @@ -500,10 +539,8 @@ handleNotification(payload, header.type); - // refresh friends panel initializeFriendsPanel(); - // display notification app.notify({ "title": "Friend Request Accepted", "text": payload.msg, @@ -512,52 +549,35 @@ }); } - function registerMusicianSessionJoin() { - context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, function(header, payload) { - logger.debug("Handling MUSICIAN_SESSION_JOIN msg " + JSON.stringify(payload)); + function registerNewUserFollower() { + + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.NEW_USER_FOLLOWER, function(header, payload) { + logger.debug("Handling NEW_USER_FOLLOWER msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); - // display notification app.notify({ - "title": "Musician Joined Session", - "text": payload.username + " has joined the session.", + "title": "New Follower", + "text": payload.msg, "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) }); }); } - function registerMusicianSessionDepart() { - context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, function(header, payload) { - logger.debug("Handling MUSICIAN_SESSION_DEPART msg " + JSON.stringify(payload)); + function registerNewBandFollower() { + + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.NEW_BAND_FOLLOWER, function(header, payload) { + logger.debug("Handling NEW_BAND_FOLLOWER msg " + JSON.stringify(payload)); - if(payload.recordingId && context.JK.CurrentSessionModel.recordingModel.isRecording(payload.recordingId)) { - context.JK.CurrentSessionModel.recordingModel.onServerStopRecording(payload.recordingId); - /**app.notify({ - "title": "Recording Stopped", - "text": payload.username + " has left the session.", - "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) - }); */ - } - else { - app.notify({ - "title": "Musician Left Session", - "text": payload.username + " has left the session.", - "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) - }); - } - }); - } + handleNotification(payload, header.type); - function registerFriendSessionJoin() { - context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_SESSION_JOIN, function(header, payload) { - logger.debug("Handling FRIEND_SESSION_JOIN msg " + JSON.stringify(payload)); - - // display notification app.notify({ - "title": "Friend Joined Session", - "text": payload.username + " has joined a session.", + "title": "New Band Follower", + "text": payload.msg, "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) }); }); + } function registerSessionInvitation() { @@ -585,7 +605,6 @@ participantHtml += ""; - // display notification app.notify({ "title": "Session Invitation", "text": participantHtml @@ -608,13 +627,16 @@ context.location = '#/session/' + args.session_id; } + function registerSessionEnded() { + // TODO: this should clean up all notifications related to this session + } + function registerJoinRequest() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST, function(header, payload) { logger.debug("Handling JOIN_REQUEST msg " + JSON.stringify(payload)); handleNotification(payload, header.type); - // display notification app.notify({ "title": "New Join Request", "text": payload.msg, @@ -650,7 +672,6 @@ handleNotification(payload, header.type); - // display notification app.notify({ "title": "Join Request Approved", "text": payload.msg, @@ -669,7 +690,6 @@ handleNotification(payload, header.type); - // display notification app.notify({ "title": "Join Request Rejected", "text": payload.msg, @@ -678,13 +698,189 @@ }); } + function registerSessionJoin() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SESSION_JOIN, function(header, payload) { + logger.debug("Handling SESSION_JOIN msg " + JSON.stringify(payload)); + + // display notification + app.notify({ + "title": "New Session Participant", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }); + }); + } + + function registerSessionDepart() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SESSION_DEPART, function(header, payload) { + logger.debug("Handling SESSION_DEPART msg " + JSON.stringify(payload)); + + var recordingId = payload.recording_id; + + if(recordingId&& context.JK.CurrentSessionModel.recordingModel.isRecording(recordingId)) { + context.JK.CurrentSessionModel.recordingModel.onServerStopRecording(recordingId); + /**app.notify({ + "title": "Recording Stopped", + "text": payload.username + " has left the session.", + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }); */ + } + else { + app.notify({ + "title": "Musician Left Session", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }); + } + }); + } + + function registerMusicianSessionJoin() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, function(header, payload) { + logger.debug("Handling MUSICIAN_SESSION_JOIN msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); + + app.notify({ + "title": "Musician Joined Session", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }, { + "ok_text": "LISTEN", + "ok_callback": listenToSession, + "ok_callback_args": { + "session_id": payload.session_id + } + }); + }); + } + + function registerBandSessionJoin() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_SESSION_JOIN, function(header, payload) { + logger.debug("Handling BAND_SESSION_JOIN msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); + + // TODO: add LISTEN button linking to session + app.notify({ + "title": "Band Joined Session", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }, { + "ok_text": "LISTEN", + "ok_callback": listenToSession, + "ok_callback_args": { + "session_id": payload.session_id + } + }); + }); + } + + function listenToSession(args) { + deleteNotification(args.notification_id); + context.location = '#/session/' + args.session_id; + } + + function registerMusicianRecordingSaved() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_RECORDING_SAVED, function(header, payload) { + logger.debug("Handling MUSICIAN_RECORDING_SAVED msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); + + app.notify({ + "title": "Musician Recording Saved", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }, { + "ok_text": "LISTEN", + "ok_callback": listenToRecording, + "ok_callback_args": { + "recording_id": payload.recording_id + } + }); + }); + + } + + function registerBandRecordingSaved() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_RECORDING_SAVED, function(header, payload) { + logger.debug("Handling BAND_RECORDING_SAVED msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); + + app.notify({ + "title": "Band Recording Saved", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }, { + "ok_text": "LISTEN", + "ok_callback": listenToRecording, + "ok_callback_args": { + "recording_id": payload.recording_id + } + }); + }); + } + + function listenToRecording(args) { + deleteNotification(args.notification_id); + context.location = '#/recording/' + args.recording_id; + } + + function registerRecordingStarted() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.RECORDING_STARTED, function(header, payload) { + logger.debug("Handling RECORDING_STARTED msg " + JSON.stringify(payload)); + + app.notify({ + "title": "Recording Started", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }); + }); + } + + function registerRecordingEnded() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.RECORDING_ENDED, function(header, payload) { + logger.debug("Handling RECORDING_ENDED msg " + JSON.stringify(payload)); + + app.notify({ + "title": "Recording Ended", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }); + }); + } + + function registerRecordingMasterMixComplete() { + context.JK.JamServer.registerMessageCallback(context.JK.MessageType.RECORDING_MASTER_MIX_COMPLETE, function(header, payload) { + logger.debug("Handling RECORDING_MASTER_MIX_COMPLETE msg " + JSON.stringify(payload)); + + handleNotification(payload, header.type); + + app.notify({ + "title": "Recording Master Mix Complete", + "text": payload.msg, + "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) + }, { + "ok_text": "SHARE", + "ok_callback": shareRecording, + "ok_callback_args": { + "recording_id": payload.recording_id + } + }); + }); + } + + function shareRecording(args) { + var recordingId = args.recording_id; + } + function registerBandInvitation() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.BAND_INVITATION, function(header, payload) { logger.debug("Handling BAND_INVITATION msg " + JSON.stringify(payload)); handleNotification(payload, header.type); - // display notification app.notify({ "title": "Band Invitation", "text": payload.msg, @@ -717,7 +913,6 @@ handleNotification(payload, header.type); - // display notification app.notify({ "title": "Band Invitation Accepted", "text": payload.msg, diff --git a/web/app/controllers/api_invitations_controller.rb b/web/app/controllers/api_invitations_controller.rb index 48faa4fb5..266f97d6d 100644 --- a/web/app/controllers/api_invitations_controller.rb +++ b/web/app/controllers/api_invitations_controller.rb @@ -46,7 +46,7 @@ class ApiInvitationsController < ApiController User.save_session_settings(current_user, music_session) # send notification - Notification.send_session_invitation(receiver.id, current_user, music_session.id) + Notification.send_session_invitation(receiver, current_user, music_session.id) respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation) else diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb index 1fa1c4271..0565d95b5 100644 --- a/web/app/controllers/api_users_controller.rb +++ b/web/app/controllers/api_users_controller.rb @@ -23,6 +23,7 @@ class ApiUsersController < ApiController {:band_musicians => :user}, :bands, :instruments]) .find(params[:id]) + respond_with @user, responder: ApiResponder, :status => 200 end @@ -55,8 +56,6 @@ class ApiUsersController < ApiController def update @user = User.find(params[:id]) - - @user.first_name = params[:first_name] if params.has_key?(:first_name) @user.last_name = params[:last_name] if params.has_key?(:last_name) @user.gender = params[:gender] if params.has_key?(:gender) @@ -269,11 +268,11 @@ class ApiUsersController < ApiController id = params[:id] if !params[:user_id].nil? - User.create_user_following(params[:user_id], id) + @user.create_user_following(params[:user_id]) respond_with @user, responder: ApiResponder, :location => api_user_following_index_url(@user) elsif !params[:band_id].nil? - User.create_band_following(params[:band_id], id) + @user.create_band_following(params[:band_id]) respond_with @user, responder: ApiResponder, :location => api_band_following_index_url(@user) end end diff --git a/web/app/views/api_users/show.rabl b/web/app/views/api_users/show.rabl index 13360ac19..fb3e14d28 100644 --- a/web/app/views/api_users/show.rabl +++ b/web/app/views/api_users/show.rabl @@ -13,10 +13,10 @@ if @user == current_user attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email elsif current_user node :is_friend do |uu| - @user.friends?(current_user) + current_user.friends?(@user) end node :is_following do |uu| - @user.following?(current_user) + current_user.following?(@user) end end diff --git a/web/jenkins b/web/jenkins index 67733e8c2..cfc6734ab 100755 --- a/web/jenkins +++ b/web/jenkins @@ -9,17 +9,21 @@ if [ "$?" = "0" ]; then echo "build succeeded" if [ ! -z "$PACKAGE" ]; then - echo "publishing ubuntu package (.deb)" - DEBPATH=`find target/deb -name *.deb` - DEBNAME=`basename $DEBPATH` + if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* ]]; then + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` - curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME - if [ "$?" != "0" ]; then - echo "deb publish failed" - exit 1 + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + else + echo "Skipping publish since branch is neither master or develop..." fi - echo "done publishing deb" fi else echo "build failed" diff --git a/web/lib/music_session_manager.rb b/web/lib/music_session_manager.rb index 84c61f9a7..7a71bdcf9 100644 --- a/web/lib/music_session_manager.rb +++ b/web/lib/music_session_manager.rb @@ -25,7 +25,7 @@ MusicSessionManager < BaseManager music_session.legal_terms = legal_terms #genres = genres - @log.debug "Genres class: " + genres.class.to_s() + @log.debug "Genres class: " + genres.class.to_s unless genres.nil? genres.each do |genre_id| @@ -48,6 +48,10 @@ MusicSessionManager < BaseManager connection = ConnectionManager.new.join_music_session(user, client_id, music_session, as_musician, tracks) unless connection.errors.any? + unless band.nil? + Notification.send_band_session_join(music_session, band) + end + return_value = music_session else return_value = connection @@ -101,8 +105,14 @@ MusicSessionManager < BaseManager connection = ConnectionManager.new.join_music_session(user, client_id, music_session, as_musician, tracks) do |db_conn, connection| if as_musician && music_session.musician_access - Notification.send_friend_session_join(db_conn, connection, user) - Notification.send_musician_session_join(music_session, connection, user) + + # send to session participants + Notification.send_session_join(music_session, connection, user) + + # send "musician joined session" notification only if it's not a band session since there will be a "band joined session" notification + if music_session.band.nil? + Notification.send_musician_session_join(music_session, connection, user) + end end end @@ -127,7 +137,7 @@ MusicSessionManager < BaseManager ConnectionManager.new.leave_music_session(user, connection, music_session) do recording = music_session.stop_recording # stop any ongoing recording, if there is one recordingId = recording.id unless recording.nil? - Notification.send_musician_session_depart(music_session, connection.client_id, user, recordingId) + Notification.send_session_depart(music_session, connection.client_id, user, recordingId) end end end diff --git a/websocket-gateway/jenkins b/websocket-gateway/jenkins index c9d07babe..6715819d4 100755 --- a/websocket-gateway/jenkins +++ b/websocket-gateway/jenkins @@ -9,6 +9,8 @@ echo "starting build..." if [ "$?" = "0" ]; then echo "build succeeded" + if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* ]]; then + # generate gem version based on jenkins build number if [ -z $BUILD_NUMBER ]; then BUILD_NUMBER="1" @@ -20,14 +22,14 @@ module JamWebsockets VERSION = "$VERSION" end EOF - + gem build jam_websockets.gemspec GEMNAME="jam_websockets-${VERSION}.gem" echo "publishing gem" curl -f -T $GEMNAME $GEM_SERVER/$GEMNAME - + if [ "$?" != "0" ]; then echo "gem publish failed" exit 1 @@ -47,8 +49,10 @@ EOF fi echo "done publishing deb" - fi + else + echo "Skipping publish since branch is neither master or develop..." + fi else echo "build failed" exit 1 diff --git a/websocket-gateway/lib/jam_websockets/router.rb b/websocket-gateway/lib/jam_websockets/router.rb index d69e3377c..b61ad42ef 100644 --- a/websocket-gateway/lib/jam_websockets/router.rb +++ b/websocket-gateway/lib/jam_websockets/router.rb @@ -351,7 +351,7 @@ module JamWebsockets user = User.find_by_id(user_id) unless user_id.nil? recording = music_session.stop_recording unless music_session.nil? # stop any ongoing recording, if there is one recordingId = recording.id unless recording.nil? - Notification.send_musician_session_depart(music_session, cid, user, recordingId) unless music_session.nil? || user.nil? + Notification.send_session_depart(music_session, cid, user, recordingId) unless music_session.nil? || user.nil? } end end @@ -398,21 +398,17 @@ module JamWebsockets end if @message_factory.server_directed? client_msg - handle_server_directed(client_msg, client) elsif @message_factory.client_directed? client_msg - to_client_id = client_msg.route_to[MessageFactory::CLIENT_TARGET_PREFIX.length..-1] handle_client_directed(to_client_id, client_msg, client) elsif @message_factory.session_directed? client_msg - session_id = client_msg.target[MessageFactory::SESSION_TARGET_PREFIX.length..-1] handle_session_directed(session_id, client_msg, client) elsif @message_factory.user_directed? client_msg - user_id = client_msg.target[MessageFactory::USER_PREFIX_TARGET.length..-1] handle_user_directed(user_id, client_msg, client) @@ -487,7 +483,7 @@ module JamWebsockets unless context.nil? || music_session_upon_reentry.nil? || music_session_upon_reentry.destroyed? recording = music_session_upon_reentry.stop_recording recordingId = recording.id unless recording.nil? - Notification.send_musician_session_depart(music_session_upon_reentry, client.client_id, context.user, recordingId) + Notification.send_session_depart(music_session_upon_reentry, client.client_id, context.user, recordingId) end else music_session = MusicSession.find_by_id(music_session_id)