* VRFS-1135 - initial implementation with no ways to control the returned results. it just returns most recent to oldest now, with a max of 20

This commit is contained in:
Seth Call 2014-02-15 21:19:03 +00:00
parent 865d8c17b6
commit 26a8b8013d
15 changed files with 222 additions and 15 deletions

View File

@ -106,4 +106,5 @@ track_connection_id_not_null.sql
recordings_all_discarded.sql
recordings_via_admin_web.sql
relax_band_model_varchar.sql
add_piano.sql
add_piano.sql
feed.sql

9
db/up/feed.sql Normal file
View File

@ -0,0 +1,9 @@
ALTER TABLE music_sessions_history ADD PRIMARY KEY (id);
CREATE TABLE feeds (
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
claimed_recording_id VARCHAR(64) UNIQUE REFERENCES claimed_recordings(id) ON DELETE CASCADE,
music_session_id VARCHAR(64) UNIQUE REFERENCES music_sessions_history(id) ON DELETE CASCADE,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);

View File

@ -123,6 +123,7 @@ require "jam_ruby/models/icecast_template_socket"
require "jam_ruby/models/icecast_server_group"
require "jam_ruby/models/icecast_mount_template"
require "jam_ruby/models/facebook_signup"
require "jam_ruby/models/feed"
include Jampb

View File

@ -9,6 +9,7 @@ module JamRuby
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'
has_one :feed, :class_name => "JamRuby::Feed", :inverse_of => :claimed_recording, :foreign_key => 'claimed_recording_id', :dependent => :destroy
validates :name, no_profanity: true, length: {minimum: 3, maximum: 64}, presence: true
@ -20,11 +21,17 @@ module JamRuby
validates_uniqueness_of :user_id, :scope => :recording_id
validate :user_belongs_to_recording
before_create :generate_share_token
before_create :add_to_feed
before_create :generate_share_token
SHARE_TOKEN_LENGTH = 8
def add_to_feed
feed = Feed.new
feed.claimed_recording = self
end
def user_belongs_to_recording
if user && recording && !recording.users.exists?(user)
errors.add(:user, ValidationMessages::NOT_PART_OF_RECORDING)

View File

@ -0,0 +1,12 @@
module JamRuby
class Feed < ActiveRecord::Base
belongs_to :claimed_recording, class_name: "JamRuby::ClaimedRecording", inverse_of: :feed, foreign_key: 'claimed_recording_id'
belongs_to :music_session_history, class_name: "JamRuby::MusicSessionHistory", inverse_of: :feed, foreign_key: 'music_session_id'
def self.index(params = {})
Feed.includes(:claimed_recording).includes(:music_session_history).order('created_at DESC').limit(20)
end
end
end

View File

@ -23,13 +23,21 @@ module JamRuby
has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "music_session_id"
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
has_one :feed, :class_name => "JamRuby::Feed", :inverse_of => :music_session_history, :foreign_key => 'music_session_id', :dependent => :destroy
before_create :generate_share_token
before_create :add_to_feed
SHARE_TOKEN_LENGTH = 8
SEPARATOR = '|'
def add_to_feed
feed = Feed.new
feed.music_session_history = self
end
def comment_count
self.comments.size
end

View File

@ -0,0 +1,24 @@
require 'spec_helper'
describe Feed do
it "no result" do
Feed.index().length.should == 0
end
it "one claimed recording" do
claimed_recording = FactoryGirl.create(:claimed_recording)
feeds = Feed.index()
feeds.length.should == 2 # the factory makes a music_session while making the recording/claimed_recording
feeds[0].music_session_history == claimed_recording.recording.music_session.music_session_history
feeds[1].claimed_recording == claimed_recording
end
it "one music session" do
music_session = FactoryGirl.create(:music_session)
feeds = Feed.index()
feeds.length.should == 1
feeds[0].music_session_history == music_session.music_session_history
end
end

View File

@ -256,6 +256,7 @@
if (bandId.length > 0) {
$("#band-setup-title").html("edit band");
$("#btn-band-setup-save").html("SAVE CHANGES");
$("#band-change-photo").html('Upload band photo.');
// retrieve and initialize band profile data points
loadBandDetails();
@ -276,8 +277,7 @@
$("#band-setup-title").html("set up band");
$("#btn-band-setup-save").html("CREATE BAND");
$("#band-change-photo").unbind('click');
$("#band-change-photo").html('Set up band and then add photo.');
$("#band-change-photo").html('Upload band photo (optional).');
}
}
@ -477,6 +477,13 @@
}
}
function navigateToBandPhoto(evt) {
evt.stopPropagation();
$("#hdn-band-id").val(bandId);
context.location = '/client#/band/setup/photo';
return false;
}
function removeInvitation(evt) {
delete selectedFriendIds[$(evt.currentTarget).parent().attr('user-id')];
$(evt.currentTarget).closest('.invitation').remove();
@ -526,12 +533,8 @@
return false;
});
$('#band-change-photo').click(function (evt) {
evt.stopPropagation();
$("#hdn-band-id").val(bandId);
context.location = '/client#/band/setup/photo';
return false;
});
$('#band-change-photo').click(navigateToBandPhoto);
$('#band-setup .avatar-profile').click(navigateToBandPhoto);
$('div[layout-id="band/setup"] .btn-email-invitation').click(function () {
invitationDialog.showEmailDialog();

View File

@ -0,0 +1,7 @@
class ApiFeedsController < ApiController
def index
@feeds = Feed.index(current_user)
end
end

View File

@ -0,0 +1,3 @@
object @feeds
extends "api_feeds/show"

View File

@ -0,0 +1,80 @@
object @feed
glue :music_session_history do
node :type do |i|
'music_session_history'
end
attributes :id, :description, :genres, :created_at, :session_removed_at
child(:music_session => :music_session) do
# only show mount info if fan_access is public. Eventually we'll also need to show this in other scenarios, like if invited
child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url
node(:mime_type) { |mount| mount.resolve_string(:mime_type) }
node(:bitrate) { |mount| mount.resolve_string(:bitrate) }
node(:subtype) { |mount| mount.resolve_string(:subtype) }
}
end
end
glue :claimed_recording do
node :type do |i|
'claimed_recording'
end
attributes :id, :name, :description, :is_public, :is_downloadable, :genre_id
node :share_url do |claimed_recording|
unless claimed_recording.share_token.nil?
share_token_url(claimed_recording.share_token.token)
end
end
child(:recording => :recording) {
attributes :id, :created_at, :duration, :comment_count, :like_count, :play_count
child(:band => :band) {
attributes :id, :name, :location, :photo_url
}
child(:owner => :owner) {
attributes :id, :name, :location, :photo_url
}
child(:mixes => :mixes) {
attributes :id, :is_completed
node :mp3_url do |mix|
mix[:url]
end
node :ogg_url do |mix|
mix[:url]
end
}
child(:recorded_tracks => :recorded_tracks) {
attributes :id, :fully_uploaded, :client_track_id, :client_id, :instrument_id
node :url do |recorded_track|
recorded_track[:url]
end
child(:user => :user) {
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :photo_url
}
}
child(:comments => :comments) {
attributes :comment, :created_at
child(:user => :creator) {
attributes :id, :first_name, :last_name, :photo_url
}
}
}
end

View File

@ -85,9 +85,9 @@ node(:claimed_recording, :if => lambda { |music_session| music_session.users.exi
}
end
# only show mount info if fan_acces is public. Eventually we'll also need to show this in other scenarios, like if invited
# only show mount info if fan_access is public. Eventually we'll also need to show this in other scenarios, like if invited
child({:mount => :mount}, :if => lambda { |music_session| music_session.fan_access}) {
attributes :id, :name, :sourced, :listeners, :bitrate, :subtype
attributes :id, :name, :sourced, :listeners, :bitrate, :subtype, :url
node(:mime_type) { |mount| mount.resolve_string(:mime_type) }
node(:bitrate) { |mount| mount.resolve_string(:bitrate) }
node(:subtype) { |mount| mount.resolve_string(:subtype) }

View File

@ -1,5 +1,5 @@
<!-- Profile -->
<div layout="screen" layout-id="band/setup" class="screen secondary">
<div layout="screen" layout-id="band/setup" class="screen secondary" id="band-setup">
<div class="content-head">
<div class="content-icon">
<%= image_tag "content/icon_bands.png", :size => "19x19" %>
@ -26,7 +26,7 @@
<%= image_tag "shared/avatar_generic_band.png", {:id => "band-avatar", :align=>"absmiddle", :height => 88, :width => 88 } %>
</a>
<br/><br/>
<a id="band-change-photo" href="#" class="small ml20">Upload Band Photo</a><br clear="all"><br/>
<a id="band-change-photo" href="#" class="small ml20">Upload band photo.</a><br clear="all"><br/>
</td>
</tr>
<tr>

View File

@ -344,7 +344,11 @@ SampleApp::Application.routes.draw do
match '/icecast/listener_add' => 'api_icecast#listener_add', :via => :post
match '/icecast/listener_remove' => 'api_icecast#listener_remove', :via => :post
# tweet on behalf of client
match '/twitter/tweet' => 'api_twitters#tweet', :via => :post
# feed
match '/feeds' => 'api_feeds#index', :via => :get
end
end

View File

@ -0,0 +1,48 @@
require 'spec_helper'
describe ApiFeedsController do
render_views
let(:user) { FactoryGirl.create(:user) }
let(:music_session) {FactoryGirl.create(:music_session, creator: user) }
let(:claimed_recording) {FactoryGirl.create(:claimed_recording) }
before(:each) do
MusicSession.delete_all
MusicSessionHistory.delete_all
Recording.delete_all
end
it "returns nothing" do
get :index
json = JSON.parse(response.body)
json.length.should == 0
end
it "returns a recording" do
claimed_recording.touch
# artifact of factory of :claimed_recording that this gets created
MusicSessionHistory.delete_all
get :index
json = JSON.parse(response.body, {:symbolize_names => true})
json.length.should == 1
claimed_recording = json[0]
claimed_recording[:type] == 'claimed_recording'
end
it "returns a music session" do
music_session.touch
# artifact of factory of :claimed_recording that this gets created
get :index
json = JSON.parse(response.body, {:symbolize_names => true})
json.length.should == 1
music_session = json[0]
music_session[:type] == 'music_session_history'
end
end