diff --git a/db/manifest b/db/manifest
index 6d546452d..f0f8fe03f 100755
--- a/db/manifest
+++ b/db/manifest
@@ -114,4 +114,5 @@ feed_autoincrement_primary_key.sql
music_sessions_plays.sql
plays_likes_counters.sql
add_upright_bass.sql
-music_session_history_public.sql
\ No newline at end of file
+music_session_history_public.sql
+track_claimed_recording.sql
\ No newline at end of file
diff --git a/db/up/track_claimed_recording.sql b/db/up/track_claimed_recording.sql
new file mode 100644
index 000000000..ca3fc62bc
--- /dev/null
+++ b/db/up/track_claimed_recording.sql
@@ -0,0 +1,3 @@
+ALTER TABLE recordings_likers ADD COLUMN claimed_recording_id VARCHAR(64) NOT NULL REFERENCES claimed_recordings(id);
+ALTER TABLE recordings_plays ADD COLUMN claimed_recording_id VARCHAR(64) NOT NULL REFERENCES claimed_recordings(id);
+ALTER TABLE recordings_likers ADD COLUMN favorite BOOLEAN NOT NULL DEFAULT TRUE;
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/models/claimed_recording.rb b/ruby/lib/jam_ruby/models/claimed_recording.rb
index 13870f433..bf01c096d 100644
--- a/ruby/lib/jam_ruby/models/claimed_recording.rb
+++ b/ruby/lib/jam_ruby/models/claimed_recording.rb
@@ -3,13 +3,14 @@ module JamRuby
attr_accessible :name, :description, :is_public, :is_downloadable, :genre_id, :recording_id, :user_id, as: :admin
- belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings, :foreign_key => 'recording_id'
- belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
- belongs_to :genre, :class_name => "JamRuby::Genre"
- has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
- has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
- has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
-
+ belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings, :foreign_key => 'recording_id'
+ belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
+ belongs_to :genre, :class_name => "JamRuby::Genre"
+ has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
+ has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
+ has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "claimed_recording_id"
+ has_many :plays, :class_name => "JamRuby::RecordingPlay", :foreign_key => "claimed_recording_id"
+ has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true
validates :description, no_profanity: true, length: {maximum: 8000}
@@ -23,6 +24,7 @@ module JamRuby
before_create :generate_share_token
SHARE_TOKEN_LENGTH = 8
+ FIXNUM_MAX = (2**(0.size * 8 -2) -1)
def user_belongs_to_recording
@@ -72,6 +74,50 @@ module JamRuby
token.gsub(/[^0-9A-Za-z]/, '')
end
+ # right now, the only thing that is brought back is ClaimedRecordings, and you can only query your own favorites
+ def self.index_favorites(user, params = {})
+ limit = params[:limit]
+ limit ||= 20
+ limit = limit.to_i
+
+ # validate sort
+ sort = params[:sort]
+ sort ||= 'date'
+ raise "not valid sort #{sort}" unless sort == "date"
+
+ start = params[:start].presence
+ start ||= 0
+ start = start.to_i
+
+
+ type_filter = params[:type]
+ type_filter ||= 'claimed_recording'
+ raise "not valid type #{type_filter}" unless type_filter == "claimed_recording"
+
+ target_user = params[:user]
+
+ raise PermissionError, "must specify current user" unless user
+ raise "user must be specified" unless target_user
+
+ if target_user != user.id
+ raise PermissionError, "unable to view another user's favorites"
+ end
+
+ query = ClaimedRecording.limit(limit).order('created_at DESC').offset(start)
+ query = query.joins(:likes)
+ query = query.where('favorite = true')
+ query = query.where("recordings_likers.liker_id = '#{target_user}'")
+ query = query.where("claimed_recordings.is_public = TRUE OR claimed_recordings.user_id = '#{target_user}'")
+
+ if query.length == 0
+ [query, nil]
+ elsif query.length < limit
+ [query, nil]
+ else
+ [query, start + limit]
+ end
+ end
+
private
def generate_share_token
diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb
index 8fc666e0f..8102edb38 100644
--- a/ruby/lib/jam_ruby/models/recording.rb
+++ b/ruby/lib/jam_ruby/models/recording.rb
@@ -29,7 +29,6 @@ module JamRuby
before_save :sanitize_active_admin
before_create :add_to_feed
-
def add_to_feed
feed = Feed.new
feed.recording = self
@@ -311,26 +310,6 @@ module JamRuby
save
end
-=begin
-# This is no longer remotely right.
- def self.search(query, options = { :limit => 10 })
-
- # only issue search if at least 2 characters are specified
- if query.nil? || query.length < 2
- return []
- end
-
- # create 'anded' statement
- query = Search.create_tsquery(query)
-
- if query.nil? || query.length == 0
- return []
- end
-
- return Recording.where("description_tsv @@ to_tsquery('jamenglish', ?)", query).limit(options[:limit])
- end
-=end
-
private
def self.validate_user_is_band_member(user, band)
unless band.users.exists? user
diff --git a/ruby/lib/jam_ruby/models/recording_liker.rb b/ruby/lib/jam_ruby/models/recording_liker.rb
index a2a6d3aae..7c997d401 100644
--- a/ruby/lib/jam_ruby/models/recording_liker.rb
+++ b/ruby/lib/jam_ruby/models/recording_liker.rb
@@ -6,6 +6,7 @@ module JamRuby
self.primary_key = 'id'
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id", :counter_cache => :like_count
+ belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id"
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "liker_id"
end
diff --git a/ruby/lib/jam_ruby/models/recording_play.rb b/ruby/lib/jam_ruby/models/recording_play.rb
index 5275c8ca5..56bd2d298 100644
--- a/ruby/lib/jam_ruby/models/recording_play.rb
+++ b/ruby/lib/jam_ruby/models/recording_play.rb
@@ -6,6 +6,7 @@ module JamRuby
self.primary_key = 'id'
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id", :counter_cache => :play_count
+ belongs_to :claimed_recording, :class_name => "JamRuby::ClaimedRecording", :foreign_key => "claimed_recording_id"
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "player_id"
end
diff --git a/ruby/spec/jam_ruby/models/claimed_recording_spec.rb b/ruby/spec/jam_ruby/models/claimed_recording_spec.rb
index 836b69ad9..f28e7a7e1 100644
--- a/ruby/spec/jam_ruby/models/claimed_recording_spec.rb
+++ b/ruby/spec/jam_ruby/models/claimed_recording_spec.rb
@@ -125,4 +125,91 @@ describe ClaimedRecording do
instance.remove_non_alpha_num("JDnfHsimMQ").should == 'JDnfHsimMQ'
end
end
+
+ describe "favorite_index" do
+
+ let(:other_user) { FactoryGirl.create(:user) }
+
+ it "returns nothing" do
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 0
+ start.should be_nil
+ end
+
+ it "angry when no user specified" do
+ expect { ClaimedRecording.index_favorites(@user, user:other_user ) }.to raise_error "unable to view another user's favorites"
+ end
+
+ it "user must be specified" do
+ expect { ClaimedRecording.index_favorites(@user) }.to raise_error "user must be specified"
+ end
+
+ it "finds favorite claimed_recording if true, not if false" do
+ claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
+
+ like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 1
+ start.should be_nil
+
+ like.favorite = false
+ like.save!
+
+ # remove from favorites
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 0
+ start.should be_nil
+ end
+
+ it "finds others public claimed recordings" do
+ claimed_recording1 = FactoryGirl.create(:claimed_recording, user: other_user)
+
+ like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 1
+ start.should be_nil
+ end
+
+ it "can find others private claimed recordings" do
+ claimed_recording1 = FactoryGirl.create(:claimed_recording, user: other_user)
+
+ like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: false)
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 0
+ start.should be_nil
+ end
+
+ it "can find own private claimed recordings" do
+ claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
+
+ like = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id)
+ favorites.length.should == 1
+ start.should be_nil
+ end
+
+ it "pagination" do
+ claimed_recording1 = FactoryGirl.create(:claimed_recording, user: @user)
+ claimed_recording2 = FactoryGirl.create(:claimed_recording, user: @user)
+
+ like1 = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording1, recording: claimed_recording1.recording, favorite: true)
+ like2 = FactoryGirl.create(:recording_like, user: @user, claimed_recording: claimed_recording2, recording: claimed_recording2.recording, favorite: true)
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1)
+ favorites.length.should == 1
+ start.should_not be_nil
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1, start: start)
+ favorites.length.should == 1
+ start.should_not be_nil
+
+ favorites, start = ClaimedRecording.index_favorites(@user, user: @user.id, limit:1, start: start)
+ favorites.length.should == 0
+ start.should be_nil
+ end
+ end
end
\ No newline at end of file
diff --git a/web/app/assets/javascripts/hoverRecording.js b/web/app/assets/javascripts/hoverRecording.js
index e73fda527..385e39533 100644
--- a/web/app/assets/javascripts/hoverRecording.js
+++ b/web/app/assets/javascripts/hoverRecording.js
@@ -40,6 +40,7 @@
var recordingHtml = context.JK.fillTemplate(template, {
recordingId: recording.id,
+ claimedRecordingId: claimedRecording.id
name: claimedRecording.name,
genre: claimedRecording.genre_id.toUpperCase(),
created_at: context.JK.formatDateTime(recording.created_at),
diff --git a/web/app/assets/javascripts/jam_rest.js b/web/app/assets/javascripts/jam_rest.js
index 5090066db..22f446469 100644
--- a/web/app/assets/javascripts/jam_rest.js
+++ b/web/app/assets/javascripts/jam_rest.js
@@ -83,21 +83,21 @@
});
}
- function addRecordingLike(recordingId, userId) {
+ function addRecordingLike(recordingId, claimedRecordingId, userId) {
return $.ajax({
url: '/api/recordings/' + recordingId + "/likes",
type: "POST",
- data : JSON.stringify({"user_id": userId}),
+ data : JSON.stringify({user_id: userId, claimed_recording: claimedRecordingId}),
dataType : 'json',
contentType: 'application/json'
});
}
- function addRecordingPlay(recordingId, userId) {
+ function addRecordingPlay(recordingId, claimedRecordingId, userId) {
return $.ajax({
url: '/api/recordings/' + recordingId + "/plays",
type: "POST",
- data : JSON.stringify({"user_id": userId}),
+ data : JSON.stringify({user_id: userId, claimed_recording: claimedRecordingId}),
dataType : 'json',
contentType: 'application/json'
});
diff --git a/web/app/assets/javascripts/web/recordings.js b/web/app/assets/javascripts/web/recordings.js
index 4644d5beb..cea7ffcfd 100644
--- a/web/app/assets/javascripts/web/recordings.js
+++ b/web/app/assets/javascripts/web/recordings.js
@@ -8,7 +8,7 @@
var $scope = $(".landing-details");
function like() {
- rest.addRecordingLike(recordingId, JK.currentUserId)
+ rest.addRecordingLike(recordingId, claimedRecordingId, JK.currentUserId)
.done(function(response) {
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
$("#btnLike", $scope).unbind("click");
@@ -16,7 +16,7 @@
}
function play() {
- rest.addRecordingPlay(recordingId, JK.currentUserId)
+ rest.addRecordingPlay(recordingId, claimedRecordingId, JK.currentUserId)
.done(function(response) {
$("#spnPlayCount", $scope).html(parseInt($("#spnPlayCount").text()) + 1);
});
diff --git a/web/app/controllers/api_favorites_controller.rb b/web/app/controllers/api_favorites_controller.rb
new file mode 100644
index 000000000..5a9845ba8
--- /dev/null
+++ b/web/app/controllers/api_favorites_controller.rb
@@ -0,0 +1,17 @@
+class ApiFavoritesController < ApiController
+
+ respond_to :json
+
+ before_filter :api_signed_in_user
+
+ def index
+ @claimed_recordings, @next = ClaimedRecording.index_favorites(current_user,
+ start: params[:since],
+ limit: params[:limit],
+ sort: params[:sort],
+ type: params[:type],
+ user: params[:user])
+
+ render "api_favorites/index", :layout => nil
+ end
+end
\ No newline at end of file
diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb
index 1947b7baa..12099ab48 100644
--- a/web/app/controllers/api_recordings_controller.rb
+++ b/web/app/controllers/api_recordings_controller.rb
@@ -121,6 +121,8 @@ class ApiRecordingsController < ApiController
liker = RecordingLiker.new
liker.recording_id = params[:id]
liker.liker_id = params[:user_id]
+ liker.claimed_recording_id = params[:claimed_recording_id]
+ liker.favorite = true
liker.ip_address = request.remote_ip
liker.save
@@ -142,6 +144,7 @@ class ApiRecordingsController < ApiController
play = RecordingPlay.new
play.recording_id = params[:id]
play.player_id = params[:user_id]
+ play.claimed_recording_id = params[:claimed_recording_id]
play.ip_address = request.remote_ip
play.save
diff --git a/web/app/views/api_favorites/index.rabl b/web/app/views/api_favorites/index.rabl
new file mode 100644
index 000000000..643b339bc
--- /dev/null
+++ b/web/app/views/api_favorites/index.rabl
@@ -0,0 +1,7 @@
+node :next do |page|
+ @next
+end
+
+node :entries do |page|
+ partial "api_claimed_recordings/show", object: @claimed_recordings
+end
\ No newline at end of file
diff --git a/web/app/views/clients/_hoverRecording.html.erb b/web/app/views/clients/_hoverRecording.html.erb
index 19272243b..50d75445e 100644
--- a/web/app/views/clients/_hoverRecording.html.erb
+++ b/web/app/views/clients/_hoverRecording.html.erb
@@ -38,7 +38,7 @@
{musicians}