Merge update
This commit is contained in:
commit
6c825db79f
|
|
@ -7,3 +7,4 @@ HTML
|
|||
.DS_Store
|
||||
coverage
|
||||
dump.rdb
|
||||
working.png
|
||||
|
|
|
|||
|
|
@ -228,3 +228,4 @@ user_syncs_fix_dup_tracks_2408.sql
|
|||
jam_tracks.sql
|
||||
shopping_carts.sql
|
||||
recurly.sql
|
||||
deletable_recordings.sql
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
-- this is to make sure we don't delete any recordings for 7 days
|
||||
UPDATE recordings SET updated_at = NOW();
|
||||
|
||||
ALTER TABLE recordings ADD COLUMN deleted BOOLEAN DEFAULT FALSE NOT NULL;
|
||||
|
||||
|
||||
DROP VIEW user_syncs;
|
||||
|
||||
CREATE VIEW user_syncs AS
|
||||
SELECT DISTINCT b.id AS recorded_track_id,
|
||||
CAST(NULL as BIGINT) AS mix_id,
|
||||
CAST(NULL as BIGINT) as quick_mix_id,
|
||||
b.id AS unified_id,
|
||||
a.user_id AS user_id,
|
||||
b.fully_uploaded,
|
||||
recordings.created_at AS created_at,
|
||||
recordings.id AS recording_id
|
||||
FROM recorded_tracks a INNER JOIN recordings ON a.recording_id = recordings.id AND duration IS NOT NULL AND all_discarded = FALSE AND deleted = FALSE INNER JOIN recorded_tracks b ON a.recording_id = b.recording_id
|
||||
UNION ALL
|
||||
SELECT CAST(NULL as BIGINT) AS recorded_track_id,
|
||||
mixes.id AS mix_id,
|
||||
CAST(NULL as BIGINT) AS quick_mix_id,
|
||||
mixes.id AS unified_id,
|
||||
claimed_recordings.user_id AS user_id,
|
||||
NULL as fully_uploaded,
|
||||
recordings.created_at AS created_at,
|
||||
recordings.id AS recording_id
|
||||
FROM mixes INNER JOIN recordings ON mixes.recording_id = recordings.id INNER JOIN claimed_recordings ON recordings.id = claimed_recordings.recording_id WHERE claimed_recordings.discarded = FALSE AND deleted = FALSE
|
||||
UNION ALL
|
||||
SELECT CAST(NULL as BIGINT) AS recorded_track_id,
|
||||
CAST(NULL as BIGINT) AS mix_id,
|
||||
quick_mixes.id AS quick_mix_id,
|
||||
quick_mixes.id AS unified_id,
|
||||
quick_mixes.user_id,
|
||||
quick_mixes.fully_uploaded,
|
||||
recordings.created_at AS created_at,
|
||||
recordings.id AS recording_id
|
||||
FROM quick_mixes INNER JOIN recordings ON quick_mixes.recording_id = recordings.id AND duration IS NOT NULL AND all_discarded = FALSE AND deleted = FALSE;
|
||||
|
|
@ -54,6 +54,7 @@ require "jam_ruby/resque/scheduled/music_session_scheduler"
|
|||
require "jam_ruby/resque/scheduled/active_music_session_cleaner"
|
||||
require "jam_ruby/resque/scheduled/score_history_sweeper"
|
||||
require "jam_ruby/resque/scheduled/scheduled_music_session_cleaner"
|
||||
require "jam_ruby/resque/scheduled/recordings_cleaner"
|
||||
require "jam_ruby/resque/google_analytics_event"
|
||||
require "jam_ruby/resque/batch_email_job"
|
||||
require "jam_ruby/mq_router"
|
||||
|
|
|
|||
|
|
@ -11,9 +11,6 @@ module JamRuby
|
|||
# https://github.com/assistly/multipass-examples/blob/master/ruby.rb
|
||||
class DeskMultipass
|
||||
|
||||
API_KEY = "453ddfc0bab00130a9c13bc9a68cf24c"
|
||||
SITE_KEY = "jamkazam"
|
||||
|
||||
def initialize(user)
|
||||
@user = user
|
||||
generate_token_and_signature
|
||||
|
|
@ -29,7 +26,7 @@ module JamRuby
|
|||
|
||||
private
|
||||
def generate_token_and_signature
|
||||
key = Digest::SHA1.digest(API_KEY + SITE_KEY)[0...16]
|
||||
key = Digest::SHA1.digest(APP_CONFIG.desk_multipass_key + APP_CONFIG.desk_multipass_site)[0...16]
|
||||
|
||||
# Generate a random 16 byte IV
|
||||
iv = OpenSSL::Random.random_bytes(16)
|
||||
|
|
@ -48,7 +45,7 @@ module JamRuby
|
|||
|
||||
prepended = iv + encrypted
|
||||
token = Base64.encode64(prepended)
|
||||
signature = Base64.encode64(OpenSSL::HMAC.digest('sha1', API_KEY, token))
|
||||
signature = Base64.encode64(OpenSSL::HMAC.digest('sha1', APP_CONFIG.desk_multipass_key, token))
|
||||
|
||||
@token = CGI.escape(token)
|
||||
@signature = CGI.escape(signature)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ module JamRuby
|
|||
query = Feed.joins("LEFT OUTER JOIN recordings ON recordings.id = feeds.recording_id")
|
||||
.joins("LEFT OUTER JOIN music_sessions ON music_sessions.id = feeds.music_session_id")
|
||||
.limit(limit)
|
||||
.where('recordings is NULL OR recordings.all_discarded = false') # remove any 'all_discarded recordings from the search results'
|
||||
.where('recordings is NULL OR (recordings.all_discarded = false AND recordings.deleted = false)') # remove any 'all_discarded recordings from the search results' or 'deleted'
|
||||
|
||||
# handle sort
|
||||
if sort == 'date'
|
||||
|
|
|
|||
|
|
@ -198,13 +198,15 @@ module JamRuby
|
|||
self.last_downloaded_at = Time.now
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delete_s3_files
|
||||
s3_manager.delete(filename(type='ogg')) if self[:ogg_url]
|
||||
s3_manager.delete(filename(type='mp3')) if self[:mp3_url]
|
||||
s3_manager.delete(filename(type='ogg')) if self[:ogg_url] && s3_manager.exists?(filename(type='ogg'))
|
||||
s3_manager.delete(filename(type='mp3')) if self[:mp3_url] && s3_manager.exists?(filename(type='mp3'))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
|
||||
def self.construct_filename(created_at, recording_id, id, type='ogg')
|
||||
raise "unknown ID" unless id
|
||||
|
|
|
|||
|
|
@ -219,11 +219,12 @@ module JamRuby
|
|||
self.last_downloaded_at = Time.now
|
||||
end
|
||||
|
||||
def delete_s3_files
|
||||
s3_manager.delete(self[:url]) if self[:url] && s3_manager.exists?(self[:url])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def delete_s3_files
|
||||
s3_manager.delete(self[:url]) if self[:url]
|
||||
end
|
||||
|
||||
def self.construct_filename(created_at, recording_id, client_track_id)
|
||||
raise "unknown ID" unless client_track_id
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
module JamRuby
|
||||
class Recording < ActiveRecord::Base
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
|
||||
@@log = Logging.logger[Recording]
|
||||
|
||||
|
||||
attr_accessible :owner, :owner_id, :band, :band_id, :recorded_tracks_attributes, :mixes_attributes, :claimed_recordings_attributes, :name, :description, :genre, :is_public, :duration, as: :admin
|
||||
|
||||
has_many :users, :through => :recorded_tracks, :class_name => "JamRuby::User"
|
||||
|
|
@ -234,8 +230,6 @@ module JamRuby
|
|||
self
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Called when a user wants to "claim" a recording. To do this, the user must have been one of the tracks in the recording.
|
||||
def claim(user, name, description, genre, is_public, upload_to_youtube=false)
|
||||
upload_to_youtube = !!upload_to_youtube # Correct where nil is borking save
|
||||
|
|
@ -264,6 +258,8 @@ module JamRuby
|
|||
def keep(user)
|
||||
recorded_tracks_for_user(user).update_all(:discard => false)
|
||||
|
||||
Recording.where(:id => id).update_all(:updated_at => Time.now) # updated updated_at for benefit of RecordingsCleaner
|
||||
|
||||
User.where(:id => user.id).update_all(:first_recording_at => Time.now ) unless user.first_recording_at
|
||||
end
|
||||
|
||||
|
|
@ -272,6 +268,8 @@ module JamRuby
|
|||
def discard(user)
|
||||
recorded_tracks_for_user(user).update_all(:discard => true)
|
||||
|
||||
Recording.where(:id => id).update_all(:updated_at => Time.now) # updated updated_at for benefit of RecordingsCleaner
|
||||
|
||||
# check if all recorded_tracks for this recording are discarded
|
||||
if recorded_tracks.where('discard = false or discard is NULL').length == 0
|
||||
self.all_discarded = true # the feed won't pick this up; also background cleanup will find these and whack them later
|
||||
|
|
@ -308,6 +306,8 @@ module JamRuby
|
|||
.order('recorded_tracks.id')
|
||||
.where('recorded_tracks.fully_uploaded = TRUE')
|
||||
.where('recorded_tracks.id > ?', since)
|
||||
.where('all_discarded = false')
|
||||
.where('deleted = false')
|
||||
.where('claimed_recordings.user_id = ? AND claimed_recordings.discarded = FALSE', user).limit(limit).each do |recorded_track|
|
||||
downloads.push(
|
||||
{
|
||||
|
|
@ -328,6 +328,8 @@ module JamRuby
|
|||
.order('mixes.id')
|
||||
.where('mixes.completed_at IS NOT NULL')
|
||||
.where('mixes.id > ?', since)
|
||||
.where('all_discarded = false')
|
||||
.where('deleted = false')
|
||||
.where('claimed_recordings.user_id = ? AND claimed_recordings.discarded = FALSE', user)
|
||||
.limit(limit).each do |mix|
|
||||
downloads.push(
|
||||
|
|
@ -462,6 +464,7 @@ module JamRuby
|
|||
.where("upload_failures <= #{APP_CONFIG.max_track_upload_failures}") \
|
||||
.where("duration IS NOT NULL") \
|
||||
.where('all_discarded = false') \
|
||||
.where('deleted = false') \
|
||||
.order('recorded_items_all.id') \
|
||||
.limit(limit)
|
||||
|
||||
|
|
@ -537,10 +540,71 @@ module JamRuby
|
|||
end
|
||||
|
||||
# returns a ClaimedRecording that the user did not discard
|
||||
def claim_for_user(user)
|
||||
def claim_for_user(user, ignore_discarded = false)
|
||||
return nil unless user
|
||||
claim = claimed_recordings.find{|claimed_recording| claimed_recording.user == user }
|
||||
claim unless claim && claim.discarded
|
||||
if ignore_discarded
|
||||
claim
|
||||
else
|
||||
claim unless claim && claim.discarded
|
||||
end
|
||||
end
|
||||
|
||||
def self.when_will_be_discarded?
|
||||
|
||||
recorded_track_votes = recorded_tracks.map(&:discard)
|
||||
|
||||
discarded = 0
|
||||
recorded_track_votes.each do |discard_vote|
|
||||
if discard_vote == nil || discard_vote == true
|
||||
discarded = discarded + 1
|
||||
end
|
||||
end
|
||||
|
||||
if recorded_track_votes.length == discarded
|
||||
# all tracks are discarded, figure out due time for deletion
|
||||
# 3 days in seconds - amount of seconds since last updated
|
||||
((APP_CONFIG.recordings_stale_time * 3600 * 24) - (Time.now - updated_at).to_i).seconds.from_now
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
# finds all discarded recordings that are sufficiently stale (i.e., abandoned by all those involved, and hasn't been mucked with in a while)
|
||||
def self.discarded_and_stale
|
||||
|
||||
# we count up all tracks for the Recording, and count up all discarded/not-voted-on tracks
|
||||
# if they are equal, and if the recording is stale, let's return it.
|
||||
Recording
|
||||
.joins("INNER JOIN recorded_tracks ON recordings.id = recorded_tracks.recording_id")
|
||||
.joins(%Q{
|
||||
LEFT OUTER JOIN
|
||||
(SELECT id
|
||||
FROM recorded_tracks WHERE discard IS NULL OR discard = TRUE) AS discard_info
|
||||
ON recorded_tracks.id = discard_info.id
|
||||
})
|
||||
.group("recordings.id")
|
||||
.having('COUNT(recorded_tracks.id) = COUNT(discard_info.id)')
|
||||
.where("NOW() - recordings.updated_at > '#{APP_CONFIG.recordings_stale_time} day'::INTERVAL")
|
||||
.limit(1000)
|
||||
end
|
||||
|
||||
def mark_delete
|
||||
|
||||
mixes.each do |mix|
|
||||
mix.delete_s3_files
|
||||
end
|
||||
|
||||
quick_mixes.each do |quick_mix|
|
||||
quick_mix.delete_s3_files
|
||||
end
|
||||
|
||||
recorded_tracks.each do |recorded_track|
|
||||
recorded_track.delete_s3_files
|
||||
end
|
||||
|
||||
self.deleted = true
|
||||
self.save(:validate => false)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ module JamRuby
|
|||
end
|
||||
|
||||
def session_count
|
||||
self.music_sessions.size
|
||||
MusicSession.where("user_id = ? AND started_at IS NOT NULL", self.id).size
|
||||
end
|
||||
|
||||
# count up any session you are RSVP'ed to
|
||||
|
|
|
|||
|
|
@ -21,7 +21,15 @@ module JamRuby
|
|||
|
||||
raise 'no user id specified' if user_id.blank?
|
||||
|
||||
query = UserSync.includes(recorded_track: [{recording: [:owner, {claimed_recordings: [:share_token]}, {recorded_tracks: [:user]}, {comments:[:user]}, :likes, :plays, :mixes]}, user: [], instrument:[]], mix: [], quick_mix:[]).where(user_id: user_id).paginate(:page => page, :per_page => limit).order('created_at DESC, unified_id')
|
||||
query = UserSync
|
||||
.includes(recorded_track: [{recording: [:owner, {claimed_recordings: [:share_token]}, {recorded_tracks: [:user]}, {comments:[:user]}, :likes, :plays, :mixes]}, user: [], instrument:[]], mix: [], quick_mix:[])
|
||||
.joins("LEFT OUTER JOIN claimed_recordings ON claimed_recordings.user_id = user_syncs.user_id AND claimed_recordings.recording_id = user_syncs.recording_id")
|
||||
.where(user_id: user_id)
|
||||
.where(%Q{
|
||||
((claimed_recordings IS NULL OR claimed_recordings.discarded = TRUE) AND fully_uploaded = FALSE) OR (claimed_recordings IS NOT NULL AND claimed_recordings.discarded = FALSE)
|
||||
})
|
||||
.paginate(:page => page, :per_page => limit)
|
||||
.order('created_at DESC, unified_id')
|
||||
|
||||
|
||||
# allow selection of single user_sync, by ID
|
||||
|
|
@ -41,6 +49,31 @@ module JamRuby
|
|||
{ query:query, next: offset + limit}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.deletables(params)
|
||||
user_id = params[:user_id]
|
||||
recording_ids = params[:recording_ids]
|
||||
|
||||
limit = 1000
|
||||
|
||||
recording_ids = recording_ids.uniq
|
||||
|
||||
raise "too many recording_ids" if recording_ids.length > limit
|
||||
|
||||
found_recording_ids =
|
||||
UserSync
|
||||
.select('user_syncs.recording_id')
|
||||
.joins("LEFT OUTER JOIN claimed_recordings ON claimed_recordings.user_id = user_syncs.user_id")
|
||||
.where(%Q{
|
||||
((claimed_recordings IS NULL OR claimed_recordings.discarded = TRUE) AND fully_uploaded = FALSE) OR (claimed_recordings IS NOT NULL AND claimed_recordings.discarded = FALSE)
|
||||
})
|
||||
.where(user_id: user_id)
|
||||
.paginate(:page => 1, :per_page => limit)
|
||||
.group('user_syncs.recording_id').map(&:recording_id)
|
||||
|
||||
recording_ids - found_recording_ids
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -65,10 +65,9 @@ module JamRuby
|
|||
|
||||
cleanup_files
|
||||
|
||||
@@log.info("audiomixer job successful. mix_id #{quick_mix_id}")
|
||||
@@log.info("quickmixer job successful. mix_id #{quick_mix_id}")
|
||||
|
||||
rescue Exception => e
|
||||
puts "EEOUOU #{e}"
|
||||
post_error(@quick_mix, e)
|
||||
raise
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
require 'json'
|
||||
require 'resque'
|
||||
require 'resque-retry'
|
||||
require 'net/http'
|
||||
require 'digest/md5'
|
||||
|
||||
module JamRuby
|
||||
|
||||
# periodically scheduled to find recordings to cleanup
|
||||
class RecordingsCleaner
|
||||
extend Resque::Plugins::LonelyJob
|
||||
|
||||
@queue = :recordings_cleaner
|
||||
|
||||
@@log = Logging.logger[RecordingsCleaner]
|
||||
|
||||
def self.lock_timeout
|
||||
# this should be enough time to make sure the job has finished, but not so long that the system isn't recovering from a abandoned job
|
||||
1200
|
||||
end
|
||||
|
||||
def self.perform
|
||||
discarded_recordings = Recording.discarded_and_stale
|
||||
|
||||
discarded_recordings.each do |recording|
|
||||
@@log.debug("deleting recording #{recording.id}")
|
||||
recording.mark_delete
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -250,8 +250,6 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :recorded_video, :class => JamRuby::RecordedVideo do
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:recording_id) { |n| "recording_id-#{n}"}
|
||||
sequence(:client_video_source_id) { |n| "client_video_source_id-#{n}"}
|
||||
fully_uploaded true
|
||||
length 1
|
||||
|
|
@ -283,14 +281,17 @@ FactoryGirl.define do
|
|||
association :genre, factory: :genre
|
||||
association :user, factory: :user
|
||||
|
||||
before(:create) { |claimed_recording|
|
||||
claimed_recording.recording = FactoryGirl.create(:recording_with_track, owner: claimed_recording.user) unless claimed_recording.recording
|
||||
before(:create) { |claimed_recording, evaluator|
|
||||
claimed_recording.recording = FactoryGirl.create(:recording_with_track, owner: claimed_recording.user) unless evaluator.recording
|
||||
}
|
||||
|
||||
|
||||
end
|
||||
|
||||
factory :mix, :class => JamRuby::Mix do
|
||||
ignore do
|
||||
autowire true
|
||||
end
|
||||
started_at Time.now
|
||||
completed_at Time.now
|
||||
ogg_md5 'abc'
|
||||
|
|
@ -301,10 +302,12 @@ FactoryGirl.define do
|
|||
sequence(:mp3_url) { |n| "recordings/mp3/#{n}" }
|
||||
completed true
|
||||
|
||||
before(:create) {|mix|
|
||||
user = FactoryGirl.create(:user)
|
||||
mix.recording = FactoryGirl.create(:recording_with_track, owner: user)
|
||||
mix.recording.claimed_recordings << FactoryGirl.create(:claimed_recording, user: user, recording: mix.recording)
|
||||
before(:create) {|mix, evaluator|
|
||||
if evaluator.autowire
|
||||
user = FactoryGirl.create(:user)
|
||||
mix.recording = FactoryGirl.create(:recording_with_track, owner: user)
|
||||
mix.recording.claimed_recordings << FactoryGirl.create(:claimed_recording, user: user, recording: mix.recording)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -330,6 +333,19 @@ FactoryGirl.define do
|
|||
mix.recording.claimed_recordings << FactoryGirl.create(:claimed_recording, user: user, recording: mix.recording)
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
factory :quick_mix_completed do
|
||||
started_at 1.minute.ago
|
||||
completed_at Time.now
|
||||
ogg_md5 'a'
|
||||
ogg_length 1
|
||||
ogg_url 'recordings/ogg'
|
||||
mp3_md5 'a'
|
||||
mp3_length 1
|
||||
mp3_url 'recordings/mp3'
|
||||
completed true
|
||||
end
|
||||
end
|
||||
|
||||
factory :invited_user, :class => JamRuby::InvitedUser do
|
||||
|
|
@ -526,6 +542,13 @@ FactoryGirl.define do
|
|||
token_expires_at Time.now
|
||||
end
|
||||
|
||||
|
||||
factory :recording_comment, :class => JamRuby::RecordingComment do
|
||||
sequence(:comment) { |n| "comment-#{n}" }
|
||||
association :recording, factory: :recording
|
||||
association :user, factory: :recording
|
||||
end
|
||||
|
||||
factory :playable_play, :class => JamRuby::PlayablePlay do
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -464,5 +464,19 @@ describe Feed do
|
|||
end
|
||||
end
|
||||
|
||||
describe "deleted recording" do
|
||||
it "should not show" do
|
||||
claimed_recording = FactoryGirl.create(:claimed_recording)
|
||||
MusicSessionUserHistory.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
MusicSession.delete_all # the factory makes a music_session while making the recording/claimed_recording
|
||||
recording = claimed_recording.recording
|
||||
recording.mark_delete
|
||||
recording.reload
|
||||
recording.deleted.should == true
|
||||
feeds, next_page = Feed.index(user1)
|
||||
feeds.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -430,6 +430,19 @@ describe Recording do
|
|||
Recording.list_uploads(@user, 10, uploads["next"])["uploads"].length.should == 0
|
||||
end
|
||||
|
||||
|
||||
it "should not consider deleted recordings" do
|
||||
stub_const("APP_CONFIG", app_config)
|
||||
@recording = Recording.start(@music_session, @user)
|
||||
@recording.stop
|
||||
@recording.reload
|
||||
@genre = FactoryGirl.create(:genre)
|
||||
@recording.claim(@user, "Recording", "Recording Description", @genre, true)
|
||||
@recording.mark_delete
|
||||
uploads = Recording.list_uploads(@user)
|
||||
uploads["uploads"].length.should == 0
|
||||
end
|
||||
|
||||
it "should return a download only if claimed" do
|
||||
@recording = Recording.start(@music_session, @user)
|
||||
@recording.stop
|
||||
|
|
@ -444,6 +457,21 @@ describe Recording do
|
|||
downloads["downloads"].length.should == 1
|
||||
end
|
||||
|
||||
it "should not return a download if recording is deleted" do
|
||||
@recording = Recording.start(@music_session, @user)
|
||||
@recording.stop
|
||||
@recording.reload
|
||||
@genre = FactoryGirl.create(:genre)
|
||||
@recording.claim(@user, "Recording", "Recording Description", @genre, true)
|
||||
downloads = Recording.list_downloads(@user)
|
||||
downloads["downloads"].length.should == 0
|
||||
@recorded_track = RecordedTrack.where(:recording_id => @recording.id)[0]
|
||||
@recorded_track.update_attribute(:fully_uploaded, true)
|
||||
@recording.mark_delete
|
||||
downloads = Recording.list_downloads(@user)
|
||||
downloads["downloads"].length.should == 0
|
||||
end
|
||||
|
||||
it "should mark first_recording_at" do
|
||||
@recording = Recording.start(@music_session, @user)
|
||||
@recording.stop
|
||||
|
|
@ -638,6 +666,388 @@ describe Recording do
|
|||
uploads["uploads"].should have(0).items
|
||||
|
||||
end
|
||||
|
||||
describe "discarded_and_stale" do
|
||||
let(:recording1) {FactoryGirl.create(:recording_with_track)}
|
||||
let(:track1) {recording1.recorded_tracks[0]}
|
||||
|
||||
it "no results if no recordings" do
|
||||
Recording.discarded_and_stale.length.should == 0
|
||||
end
|
||||
|
||||
describe "with one recording" do
|
||||
before(:each) do
|
||||
track1.discard.should be_nil
|
||||
end
|
||||
|
||||
describe "that has no votes" do
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
# and we should find it now...
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.first.should eq(recording1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has discard vote" do
|
||||
|
||||
before(:each) do
|
||||
track1.discard = true
|
||||
track1.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
# and we should find it now...
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.first.should eq(recording1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has keep vote" do
|
||||
|
||||
before(:each) do
|
||||
track1.discard = false
|
||||
track1.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "still not found it has an old updated_at time, because it was kept" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
# and still not find it
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has two tracks, no votes" do
|
||||
|
||||
let(:track2) { FactoryGirl.create(:recorded_track, recording: recording1, user: recording1.owner) }
|
||||
|
||||
before(:each) do
|
||||
track1.discard = nil
|
||||
track1.save!
|
||||
|
||||
recording1.recorded_tracks << track2
|
||||
recording1.save!
|
||||
|
||||
track2.discard = nil
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
# and we should find it now...
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.first.should eq(recording1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has two tracks, two discard" do
|
||||
|
||||
let(:track2) { FactoryGirl.create(:recorded_track, recording: recording1, user: recording1.owner) }
|
||||
|
||||
before(:each) do
|
||||
track1.discard = true
|
||||
track1.save!
|
||||
|
||||
recording1.recorded_tracks << track2
|
||||
recording1.save!
|
||||
|
||||
track2.discard = true
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
# and we should find it now...
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.first.should eq(recording1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has two tracks, one discard, one keep" do
|
||||
|
||||
let(:track2) { FactoryGirl.create(:recorded_track, recording: recording1, user: recording1.owner) }
|
||||
|
||||
before(:each) do
|
||||
track1.discard = true
|
||||
track1.save!
|
||||
|
||||
recording1.recorded_tracks << track2
|
||||
recording1.save!
|
||||
|
||||
track2.discard = false
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "that has two tracks, two keeps" do
|
||||
|
||||
let(:track2) { FactoryGirl.create(:recorded_track, recording: recording1, user: recording1.owner) }
|
||||
|
||||
before(:each) do
|
||||
track1.discard = false
|
||||
track1.save!
|
||||
|
||||
recording1.recorded_tracks << track2
|
||||
recording1.save!
|
||||
|
||||
track2.discard = false
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "two recordings" do
|
||||
let(:recording2) {FactoryGirl.create(:recording_with_track)}
|
||||
let(:track2) {recording2.recorded_tracks[0]}
|
||||
|
||||
describe "both discard" do
|
||||
|
||||
before(:each) do
|
||||
track1.discard = true
|
||||
track1.save!
|
||||
|
||||
track2.discard = true
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 1
|
||||
stale.first.should eq(recording1)
|
||||
|
||||
Recording.where(:id => recording2.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "both keep" do
|
||||
|
||||
before(:each) do
|
||||
track1.discard = false
|
||||
track1.save!
|
||||
|
||||
track2.discard = false
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
Recording.where(:id => recording2.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
end
|
||||
|
||||
describe "one keep, one discard" do
|
||||
|
||||
before(:each) do
|
||||
track1.discard = false
|
||||
track1.save!
|
||||
|
||||
track2.discard = true
|
||||
track2.save!
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
Recording.where(:id => recording2.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 1
|
||||
stale.first.should eq(recording2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "two keeps, two discards" do
|
||||
|
||||
let(:track1_2) { FactoryGirl.create(:recorded_track, recording: recording1, user: recording1.owner) }
|
||||
let(:track2_2) { FactoryGirl.create(:recorded_track, recording: recording2, user: recording1.owner) }
|
||||
|
||||
before(:each) do
|
||||
track1.discard = false
|
||||
track1.save!
|
||||
recording1.recorded_tracks << track1_2
|
||||
recording1.save!
|
||||
track1_2.discard = false
|
||||
track1_2.save!
|
||||
|
||||
track2.discard = true
|
||||
track2.save!
|
||||
recording2.recorded_tracks << track2_2
|
||||
recording2.save!
|
||||
track2_2.discard = true
|
||||
track2_2.save!
|
||||
|
||||
end
|
||||
|
||||
it "not found if it has recent updated_at time" do
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
end
|
||||
|
||||
it "found if it has an old updated_at time" do
|
||||
# now age the recording
|
||||
Recording.where(:id => recording1.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 0
|
||||
|
||||
Recording.where(:id => recording2.id).update_all(:updated_at => (APP_CONFIG.recordings_stale_time + 1).days.ago)
|
||||
|
||||
stale = Recording.discarded_and_stale
|
||||
stale.length.should == 1
|
||||
stale.first.should eq(recording2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete" do
|
||||
let(:mix) {FactoryGirl.create(:mix)}
|
||||
let(:recording) {mix.recording}
|
||||
|
||||
before(:each) do
|
||||
|
||||
end
|
||||
|
||||
it "success" do
|
||||
FactoryGirl.create(:quick_mix, user: recording.owner, recording:recording, autowire: false)
|
||||
FactoryGirl.create(:recording_comment, recording: recording, user: recording.owner)
|
||||
FactoryGirl.create(:recording_like, recording: recording, claimed_recording: recording.claimed_recordings.first, favorite:true)
|
||||
FactoryGirl.create(:playable_play, playable_id: recording.id, playable_type: 'JamRuby::Recording')
|
||||
FactoryGirl.create(:recorded_video, user: recording.owner, recording: recording)
|
||||
recording.reload
|
||||
recording.claimed_recordings.length.should > 0
|
||||
recording.mixes.length.should > 0
|
||||
recording.quick_mixes.length.should > 0
|
||||
recording.recorded_tracks.length.should > 0
|
||||
recording.comments.length.should > 0
|
||||
recording.likes.length.should > 0
|
||||
recording.plays.length.should > 0
|
||||
recording.recorded_videos.length.should > 0
|
||||
recording.feed.should_not be_nil
|
||||
|
||||
claimed_recording = recording.claimed_recordings.first
|
||||
quick_mix = recording.quick_mixes.first
|
||||
track = recording.recorded_tracks.first
|
||||
comment = recording.comments.first
|
||||
like = recording.likes.first
|
||||
play = recording.plays.first
|
||||
feed = recording.feed
|
||||
video = recording.recorded_videos.first
|
||||
|
||||
recording.mark_delete
|
||||
|
||||
ClaimedRecording.find_by_id(claimed_recording.id).should_not be_nil
|
||||
Mix.find_by_id(mix.id).should_not be_nil
|
||||
QuickMix.find_by_id(quick_mix.id).should_not be_nil
|
||||
RecordedTrack.find_by_id(track.id).should_not be_nil
|
||||
RecordingComment.find_by_id(comment.id).should_not be_nil
|
||||
PlayablePlay.find_by_id(play.id).should_not be_nil
|
||||
RecordingLiker.find_by_id(like.id).should_not be_nil
|
||||
Feed.find_by_id(feed.id).should_not be_nil
|
||||
RecordedVideo.find_by_id(video.id).should_not be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,19 +20,41 @@ describe UserSync do
|
|||
data[:next].should be_nil
|
||||
end
|
||||
|
||||
it "one mix" do
|
||||
it "one mix and quick mix" do
|
||||
mix = FactoryGirl.create(:mix)
|
||||
mix.recording.duration = 1
|
||||
mix.recording.save!
|
||||
quick_mix = FactoryGirl.create(:quick_mix_completed, recording:mix.recording, user: mix.recording.recorded_tracks[0].user, autowire:false)
|
||||
|
||||
data = UserSync.index({user_id: mix.recording.recorded_tracks[0].user.id})
|
||||
data[:next].should be_nil
|
||||
user_syncs = data[:query]
|
||||
user_syncs.length.should == 2
|
||||
user_syncs.length.should == 3
|
||||
user_syncs[0].recorded_track.should == mix.recording.recorded_tracks[0]
|
||||
user_syncs[0].mix.should be_nil
|
||||
user_syncs[0].quick_mix.should be_nil
|
||||
user_syncs[1].mix.should == mix
|
||||
user_syncs[1].recorded_track.should be_nil
|
||||
user_syncs[1].quick_mix.should be_nil
|
||||
user_syncs[2].mix.should be_nil
|
||||
user_syncs[2].recorded_track.should be_nil
|
||||
user_syncs[2].quick_mix.should eq(quick_mix)
|
||||
end
|
||||
|
||||
# https://jamkazam.atlassian.net/browse/VRFS-2450
|
||||
it "no longer returned after fully uploaded and unclaimed" do
|
||||
mix = FactoryGirl.create(:mix)
|
||||
mix.recording.duration = 1
|
||||
mix.recording.save!
|
||||
quick_mix = FactoryGirl.create(:quick_mix_completed, recording:mix.recording, user: mix.recording.recorded_tracks[0].user, autowire:false, fully_uploaded: true)
|
||||
mix.recording.recorded_tracks[0].fully_uploaded = true
|
||||
mix.recording.recorded_tracks[0].save!
|
||||
mix.recording.claimed_recordings[0].discarded = true
|
||||
mix.recording.claimed_recordings[0].save!
|
||||
|
||||
data = UserSync.index({user_id: mix.recording.recorded_tracks[0].user.id})
|
||||
user_syncs = data[:query]
|
||||
user_syncs.length.should == 0
|
||||
end
|
||||
|
||||
it "two mixes, one not belonging to querier" do
|
||||
|
|
@ -65,8 +87,8 @@ describe UserSync do
|
|||
describe "one recording with two users" do
|
||||
let!(:recording1) {
|
||||
recording = FactoryGirl.create(:recording, owner: user1, band: nil, duration:1)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner, fully_uploaded:false)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2, fully_uploaded:false)
|
||||
recording.save!
|
||||
recording.reload
|
||||
recording
|
||||
|
|
@ -171,10 +193,10 @@ describe UserSync do
|
|||
describe "one recording with multi-track users" do
|
||||
let!(:recording1) {
|
||||
recording = FactoryGirl.create(:recording, owner: user1, band: nil, duration:1)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner, fully_uploaded:false)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner, fully_uploaded:false)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2, fully_uploaded:false)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2, fully_uploaded:false)
|
||||
recording.save!
|
||||
recording.reload
|
||||
recording
|
||||
|
|
@ -222,6 +244,7 @@ describe UserSync do
|
|||
recording = FactoryGirl.create(:recording, owner: user1, band: nil, duration:1)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: user2)
|
||||
claimed_recording = FactoryGirl.create(:claimed_recording, user: recording.owner, recording: recording, discarded:false)
|
||||
recording.save!
|
||||
recording.reload
|
||||
recording
|
||||
|
|
@ -267,8 +290,204 @@ describe UserSync do
|
|||
user_syncs = data[:query]
|
||||
user_syncs.length.should == 0
|
||||
data[:query].total_entries.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
it "does not return deleted recordings" do
|
||||
mix = FactoryGirl.create(:mix)
|
||||
mix.recording.duration = 1
|
||||
mix.recording.save!
|
||||
quick_mix = FactoryGirl.create(:quick_mix_completed, recording:mix.recording, user: mix.recording.recorded_tracks[0].user, autowire:false)
|
||||
|
||||
mix.recording.mark_delete
|
||||
data = UserSync.index({user_id: mix.recording.recorded_tracks[0].user.id})
|
||||
data[:next].should be_nil
|
||||
user_syncs = data[:query]
|
||||
user_syncs.length.should == 0
|
||||
end
|
||||
|
||||
describe "deletable" do
|
||||
describe "one mix and one quick mix" do
|
||||
|
||||
let!(:mix) { m = FactoryGirl.create(:mix); m.recording.duration = 1; m.recording.save!; m}
|
||||
let!(:quick_mix) { FactoryGirl.create(:quick_mix_completed, recording:mix.recording, user: mix.recording.recorded_tracks[0].user, autowire:false) }
|
||||
|
||||
it "unknown id" do
|
||||
recording_ids = ['1']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(recording_ids)
|
||||
end
|
||||
|
||||
it "unknown ids" do
|
||||
recording_ids = ['1', '2', '3']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(recording_ids)
|
||||
end
|
||||
|
||||
it "valid recording id" do
|
||||
recording_ids = [mix.recording.id]
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq([])
|
||||
end
|
||||
|
||||
it "valid recording id" do
|
||||
recording_ids = [mix.recording.id]
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq([])
|
||||
end
|
||||
|
||||
it "valid recording_id mixed with unknown ids" do
|
||||
recording_ids = [mix.recording.id, '1']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(['1'])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "two recordings" do
|
||||
|
||||
let!(:mix) { m = FactoryGirl.create(:mix); m.recording.duration = 1; m.recording.save!; m}
|
||||
let!(:quick_mix) { FactoryGirl.create(:quick_mix_completed, recording:mix.recording, user: mix.recording.recorded_tracks[0].user, autowire:false) }
|
||||
|
||||
let!(:mix2) { m = FactoryGirl.create(:mix); m.recording.duration = 1; m.recording.save!; m}
|
||||
let!(:quick_mix2) { FactoryGirl.create(:quick_mix_completed, recording:mix2.recording, user: mix2.recording.recorded_tracks[0].user, autowire:false) }
|
||||
|
||||
before(:each) do
|
||||
# fix up the user associated with the second mix/recording to be same as 1st
|
||||
mix2.recording.owner = mix.recording.owner
|
||||
mix2.recording.save!
|
||||
mix2.recording.recorded_tracks[0].user = mix.recording.owner
|
||||
mix2.recording.recorded_tracks[0].save!
|
||||
end
|
||||
|
||||
it "unknown id" do
|
||||
recording_ids = ['1']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(recording_ids)
|
||||
end
|
||||
|
||||
it "unknown ids" do
|
||||
recording_ids = ['1', '2', '3']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(recording_ids)
|
||||
end
|
||||
|
||||
it "valid recording id" do
|
||||
recording_ids = [mix.recording.id, mix2.recording.id]
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq([])
|
||||
end
|
||||
|
||||
it "valid recording id" do
|
||||
recording_ids = [mix.recording.id]
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq([])
|
||||
end
|
||||
|
||||
it "valid recording_id mixed with unknown ids" do
|
||||
recording_ids = [mix.recording.id, '1']
|
||||
|
||||
result = UserSync.deletables(user_id: mix.recording.recorded_tracks[0].user.id, recording_ids: recording_ids)
|
||||
|
||||
result.should eq(['1'])
|
||||
end
|
||||
end
|
||||
|
||||
it "resolved recordings" do
|
||||
|
||||
# start with a recording with a fully uploaded recorded_track, and no claim
|
||||
recording = FactoryGirl.create(:recording_with_track, owner: user1)
|
||||
recording.duration = 1
|
||||
recording.save!
|
||||
|
||||
recording_ids = [recording.id]
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq(recording_ids)
|
||||
|
||||
# set the recorded_track to not fully uploaded, which should make it not deletable
|
||||
recording.recorded_tracks[0].fully_uploaded = false
|
||||
recording.recorded_tracks[0].save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq([])
|
||||
|
||||
# mark recording as deleted, which should make it deletable
|
||||
recording.deleted = true
|
||||
recording.save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq(recording_ids)
|
||||
|
||||
# mark recording as fully discarded, which should make it deletable
|
||||
recording.all_discarded = true
|
||||
recording.deleted = false
|
||||
recording.save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq(recording_ids)
|
||||
|
||||
# claim the recording, and make the track not fully uploaded
|
||||
recording.recorded_tracks[0].fully_uploaded = false
|
||||
recording.all_discarded = false
|
||||
claim = FactoryGirl.create(:claimed_recording, user: user1, recording: recording)
|
||||
recording.save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq([])
|
||||
|
||||
# create a mix while still claiming the recording
|
||||
mix = FactoryGirl.create(:mix, autowire:false, recording:recording)
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq([])
|
||||
|
||||
# now take away the claim, and make sure the track is fully uploaded
|
||||
claim.discarded = true
|
||||
claim.save!
|
||||
# without a claimed recording, make the track fully uploaded, so as to not trigger 'need to upload' logic
|
||||
recording.recorded_tracks[0].fully_uploaded = true
|
||||
recording.recorded_tracks[0].save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq(recording_ids)
|
||||
|
||||
# if we make a quick mix, but still have no claim, we still should still need to delete the recording
|
||||
quick_mix = FactoryGirl.create(:quick_mix, autowire:false, user: user1, recording: recording, fully_uploaded: true)
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq(recording_ids)
|
||||
|
||||
# make the quick_mix be not fully_uploaded, which should make it not be marked for deleting because we need to upload it
|
||||
quick_mix.fully_uploaded = false
|
||||
quick_mix.save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq([])
|
||||
|
||||
quick_mix.fully_uploaded = true
|
||||
quick_mix.save!
|
||||
claim.discarded = false
|
||||
claim.save!
|
||||
|
||||
result = UserSync.deletables(user_id: user1.id, recording_ids: recording_ids)
|
||||
result.should eq([])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ def app_config
|
|||
2 # don't put to 1; it'll break tests
|
||||
end
|
||||
|
||||
def recordings_stale_time
|
||||
7
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def audiomixer_workspace_path
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
|
|
@ -92,7 +92,9 @@
|
|||
.done(function(openSlots) {
|
||||
if (openSlots) {
|
||||
if (openSlots.length === 0) {
|
||||
ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName);
|
||||
ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
|
||||
approve(rsvpId, params);
|
||||
});
|
||||
}
|
||||
else {
|
||||
var arrInstrumentIds = instrumentIds.split('|');
|
||||
|
|
@ -122,7 +124,9 @@
|
|||
}
|
||||
}
|
||||
else {
|
||||
ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName);
|
||||
ui.launchRsvpCreateSlotDialog(sessionData.id, instrumentIds.split('|'), userName, function() {
|
||||
approve(rsvpId, params);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
var nextPage = 1;
|
||||
var $includeType = null;
|
||||
var didLoadAllFeeds = false, isLoading = false;
|
||||
var $templateRecordingDiscardedSoon = null;
|
||||
|
||||
function defaultQuery() {
|
||||
var query = { limit: feedBatchSize };
|
||||
|
|
@ -441,6 +442,15 @@
|
|||
var $feedItem = $(context._.template($('#template-feed-recording').html(), options, {variable: 'data'}));
|
||||
var $controls = $feedItem.find('.recording-controls');
|
||||
|
||||
var $titleText = $feedItem.find('.title .title-text');
|
||||
|
||||
// if this item will be discarded, tack on a * to the RECORDING NAME
|
||||
var discardTime = feed['when_will_be_discarded?'];
|
||||
if(discardTime) {
|
||||
context.JK.helpBubble($titleText, 'recording-discarded-soon', {discardTime: discardTime}, {});
|
||||
$titleText.text($titleText.text() + '*');
|
||||
}
|
||||
|
||||
$controls.data('mix-state', feed.mix_info) // for recordingUtils helper methods
|
||||
$controls.data('server-info', feed.mix) // for recordingUtils helper methods
|
||||
$controls.data('view-context', 'feed')
|
||||
|
|
@ -589,6 +599,7 @@
|
|||
$includeDate.val(defaults.time_range)
|
||||
$includeType.val(defaults.type)
|
||||
|
||||
$templateRecordingDiscardedSoon = $('#template-help-recording-discarded-soon');
|
||||
events();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@
|
|||
// @FIXME -- this will need to be tweaked when we allow unfollowing
|
||||
$('div[data-band-id='+newFollowing.band_id+'] .search-m-follow').removeClass('button-orange').addClass('button-grey');
|
||||
},
|
||||
error: app.ajaxError
|
||||
error: app.ajaxError(arguments)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
if (response.internet_score && response.internet_score.length > 0) {
|
||||
if (response.internet_score[0].score && !isNaN(response.internet_score[0].score)) {
|
||||
var internetScore = parseInt(response.internet_score[0].score);
|
||||
fullScore = (response.internet_score + calculateAudioLatency(response.my_audio_latency) + calculateAudioLatency(response.last_jam_audio_latency)) / 2;
|
||||
fullScore = (internetScore + calculateAudioLatency(response.my_audio_latency) + calculateAudioLatency(response.last_jam_audio_latency)) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
instrumentHtml = '<td><div class="nowrap">';
|
||||
$.each(val.instrument_ids, function(index, val) {
|
||||
instrumentHtml += '<img src="' + context.JK.getInstrumentIcon24(val) + '" width="24" height="24" /> ';
|
||||
instrumentHtml += '<img src="' + context.JK.getInstrumentIcon24(val) + '" title="' + val + '" width="24" height="24" /> ';
|
||||
});
|
||||
instrumentHtml += '</div></td>';
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
instrumentHtml = '<td><div class="nowrap">';
|
||||
var instruments = val.instruments.split("|");
|
||||
$.each(instruments, function(index, instrument) {
|
||||
instrumentHtml += '<img src="' + context.JK.getInstrumentIcon24(instrument) + '" width="24" height="24" /> ';
|
||||
instrumentHtml += '<img src="' + context.JK.getInstrumentIcon24(instrument) + '" title="' + instrument + '" width="24" height="24" /> ';
|
||||
});
|
||||
|
||||
instrumentHtml += '</div></td>';
|
||||
|
|
|
|||
|
|
@ -1072,6 +1072,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
function deleteRecordingClaim(id) {
|
||||
return $.ajax({
|
||||
type: "DELETE",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/recordings/" + id + "/claim"
|
||||
});
|
||||
}
|
||||
|
||||
function claimRecording(options) {
|
||||
var recordingId = options["id"];
|
||||
|
||||
|
|
@ -1437,6 +1446,7 @@
|
|||
this.getClaimedRecording = getClaimedRecording;
|
||||
this.updateClaimedRecording = updateClaimedRecording;
|
||||
this.deleteClaimedRecording = deleteClaimedRecording;
|
||||
this.deleteRecordingClaim = deleteRecordingClaim;
|
||||
this.claimRecording = claimRecording;
|
||||
this.startPlayClaimedRecording = startPlayClaimedRecording;
|
||||
this.stopPlayClaimedRecording = stopPlayClaimedRecording;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
var $uploadPercent = $('#recording-manager-upload .percent', $parentElement);
|
||||
var $convertCommand = $('#recording-manager-convert', $parentElement);
|
||||
var $convertPercent = $('#recording-manager-convert .percent', $parentElement);
|
||||
var $deleteCommand = $('#recording-manager-delete', $parentElement);
|
||||
var $deletePercent = $('#recording-manager-delete .percent', $parentElement);
|
||||
var $fileManager = $('#recording-manager-launcher', $parentElement);
|
||||
|
||||
if($fileManager.length == 0) {throw "no file manager element"; }
|
||||
|
|
@ -32,12 +34,14 @@
|
|||
$downloadCommand.data('command-type', 'download')
|
||||
$uploadCommand.data('command-type', 'upload')
|
||||
$convertCommand.data('command-type', 'convert')
|
||||
$deleteCommand.data('command-type', 'delete')
|
||||
|
||||
// keys come from backend
|
||||
var lookup = {
|
||||
SyncDownload: { command: $downloadCommand, percent: $downloadPercent},
|
||||
SyncUpload: { command: $uploadCommand, percent: $uploadPercent},
|
||||
SyncConvert: { command: $convertCommand, percent: $convertPercent}
|
||||
SyncConvert: { command: $convertCommand, percent: $convertPercent},
|
||||
SyncDelete: { command: $deleteCommand, percent: $deletePercent}
|
||||
}
|
||||
|
||||
var $self = $(this);
|
||||
|
|
|
|||
|
|
@ -1237,7 +1237,7 @@
|
|||
$languageList = $screen.find('#session-language-list');
|
||||
$sessionPlusMusiciansLabel = $screen.find('label[for="session-plus-musicians"]');
|
||||
$editScheduledSessions = $screen.find('#edit_scheduled_sessions');
|
||||
$btnSelectFiles = $screen.find('.btn-select-files');
|
||||
$btnSelectFiles = $screen.find('#session-notation-file-selection');
|
||||
$selectedFilenames = $screen.find('#selected-filenames');
|
||||
$uploadSpinner = $screen.find('#file-upload-spinner');
|
||||
$policyTypes = $screen.find('input[name="session-policy-type"]');
|
||||
|
|
|
|||
|
|
@ -135,8 +135,7 @@
|
|||
});
|
||||
|
||||
if (showJoinLink) {
|
||||
// wire up the Join Link to the T&Cs dialog
|
||||
|
||||
// wire up the Join Link to the T&Cs dialog
|
||||
$('.join-link', $parentRow).click(function(evt) {
|
||||
if(!context.JK.guardAgainstBrowser(app)) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -138,23 +138,9 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if ("invitations" in session) {
|
||||
var invitation;
|
||||
// user has invitations for this session
|
||||
for (var i=0; i < session.invitations.length; i++) {
|
||||
invitation = session.invitations[i];
|
||||
// session contains an invitation for this user
|
||||
if (invitation.receiver_id === context.JK.currentUserId) {
|
||||
hasInvitation = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (session) {
|
||||
// if user has an invitation, always open terms and allow joining regardless of settings
|
||||
if (hasInvitation) {
|
||||
logger.debug("Found invitation for user " + context.JK.currentUserId + ", session " + sessionId);
|
||||
if (session.can_join) {
|
||||
logger.debug("Found invitation or approved RSVP for user " + context.JK.currentUserId + ", session " + sessionId);
|
||||
openJoinSessionTerms(sessionId);
|
||||
}
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ context.JK.SyncViewer = class SyncViewer
|
|||
@downloadCommandId = null
|
||||
@downloadMetadata = null
|
||||
@uploadCommandId = null
|
||||
@uploadMetadata = null;
|
||||
@uploadMetadata = null
|
||||
@cleanupCommandId = null
|
||||
@cleanupMetadata = null
|
||||
|
||||
|
||||
init: () =>
|
||||
@root = $($('#template-sync-viewer').html())
|
||||
|
|
@ -330,12 +333,15 @@ context.JK.SyncViewer = class SyncViewer
|
|||
for clientInfo in recording.local_tracks
|
||||
$track = @list.find(".recorded-track[data-recording-id='#{recording.recording_id}'][data-client-track-id='#{clientInfo.client_track_id}']")
|
||||
$track.data('client-info', clientInfo)
|
||||
$track.data('total-size', recording.size)
|
||||
|
||||
$track = @list.find(".mix[data-recording-id='#{recording.recording_id}']")
|
||||
$track.data('client-info', recording.mix)
|
||||
$track.data('total-size', recording.size)
|
||||
|
||||
$track = @list.find(".stream-mix[data-recording-id='#{recording.recording_id}']")
|
||||
$track.data('client-info', recording.stream_mix)
|
||||
$track.data('total-size', recording.size)
|
||||
|
||||
displayStreamMixHover: ($streamMix) =>
|
||||
$clientState = $streamMix.find('.client-state')
|
||||
|
|
@ -470,10 +476,10 @@ context.JK.SyncViewer = class SyncViewer
|
|||
sendCommand: ($retry, cmd) =>
|
||||
|
||||
if context.JK.CurrentSessionModel and context.JK.CurrentSessionModel.inSession()
|
||||
context.JK.confirmBubble($retry, 'sync-viewer-paused', {}, {offsetParent: $retry.closest('.dialog')})
|
||||
context.JK.ackBubble($retry, 'sync-viewer-paused', {}, {offsetParent: $retry.closest('.dialog')})
|
||||
else
|
||||
context.jamClient.OnTrySyncCommand(cmd)
|
||||
context.JK.confirmBubble($retry, 'sync-viewer-retry', {}, {offsetParent: $retry.closest('.dialog')})
|
||||
context.JK.ackBubble($retry, 'sync-viewer-retry', {}, {offsetParent: $retry.closest('.dialog')})
|
||||
|
||||
|
||||
retryDownloadRecordedTrack: (e) =>
|
||||
|
|
@ -564,7 +570,7 @@ context.JK.SyncViewer = class SyncViewer
|
|||
exportRecording: (e) =>
|
||||
$export = $(e.target)
|
||||
if context.JK.CurrentSessionModel and context.JK.CurrentSessionModel.inSession()
|
||||
context.JK.confirmBubble($export, 'sync-viewer-paused', {}, {offsetParent: $export.closest('.dialog')})
|
||||
context.JK.ackBubble($export, 'sync-viewer-paused', {}, {offsetParent: $export.closest('.dialog')})
|
||||
return
|
||||
|
||||
recordingId = $export.closest('.details').attr('data-recording-id')
|
||||
|
|
@ -573,7 +579,7 @@ context.JK.SyncViewer = class SyncViewer
|
|||
|
||||
cmd =
|
||||
{ type: 'export_recording',
|
||||
action: 'export'
|
||||
action: 'export',
|
||||
queue: 'upload',
|
||||
recording_id: recordingId}
|
||||
|
||||
|
|
@ -581,9 +587,60 @@ context.JK.SyncViewer = class SyncViewer
|
|||
context.jamClient.OnTrySyncCommand(cmd)
|
||||
return false;
|
||||
|
||||
deleteRecording: (e) =>
|
||||
$delete = $(e.target)
|
||||
if context.JK.CurrentSessionModel and context.JK.CurrentSessionModel.inSession()
|
||||
context.JK.ackBubble($delete, 'sync-viewer-paused', {}, {offsetParent: $delete.closest('.dialog')})
|
||||
return
|
||||
|
||||
$details = $delete.closest('.details')
|
||||
recordingId = $details.attr('data-recording-id')
|
||||
|
||||
if !recordingId? or recordingId == ""
|
||||
throw "deleteRecording can't find data-recording-id"
|
||||
|
||||
context.JK.Banner.showYesNo({
|
||||
title: "Confirm Deletion",
|
||||
html: "Are you sure you want to delete this recording?",
|
||||
yes: =>
|
||||
@rest.deleteRecordingClaim(recordingId).done((response)=>
|
||||
cmd =
|
||||
{ type: 'recording_directory',
|
||||
action: 'delete',
|
||||
queue: 'cleanup',
|
||||
recording_id: recordingId}
|
||||
|
||||
# now check if the sync is gone entirely, allowing us to delete it from the UI
|
||||
@rest.getUserSync({user_sync_id: recordingId}).done((userSync) =>
|
||||
# the user sync is still here. tell user it'll be done as soon as they've uploaded their files
|
||||
context.JK.ackBubble($delete, 'file-sync-delayed-deletion', {}, {offsetParent: $delete.closest('.dialog')})
|
||||
)
|
||||
.fail((xhr) =>
|
||||
if xhr.status == 404
|
||||
# the userSync is gone; remove from file manager dynamically
|
||||
$recordingHolder = $details.closest('.recording-holder')
|
||||
$recordingHolder.slideUp()
|
||||
else
|
||||
@app.ajaxError(arguments)
|
||||
)
|
||||
|
||||
context.jamClient.OnTrySyncCommand(cmd)
|
||||
)
|
||||
.fail(@app.ajaxError)
|
||||
})
|
||||
|
||||
return false;
|
||||
|
||||
displaySize: (size) =>
|
||||
# size is in bytes. divide by million, anxosd round to one decimal place
|
||||
megs = Math.round(size * 10 / (1024 * 1024) ) / 10
|
||||
"#{megs}M"
|
||||
|
||||
createRecordingWrapper: ($toWrap, recordingInfo) =>
|
||||
totalSize = $($toWrap.get(0)).data('total-size')
|
||||
recordingInfo.recording_landing_url = "/recordings/#{recordingInfo.id}"
|
||||
recordingInfo.totalSize = this.displaySize(totalSize)
|
||||
recordingInfo.claimedRecordingId = recordingInfo.my?.id
|
||||
$wrapperDetails = $(context._.template(@templateRecordingWrapperDetails.html(), recordingInfo, {variable: 'data'}))
|
||||
$wrapper = $('<div class="recording-holder"></div>')
|
||||
$toWrap.wrapAll($wrapper)
|
||||
|
|
@ -595,6 +652,7 @@ context.JK.SyncViewer = class SyncViewer
|
|||
$wrapper.append(this.createMix('fake', recordingInfo))
|
||||
|
||||
$wrapper.find('a.export').click(this.exportRecording)
|
||||
$wrapper.find('a.delete').click(this.deleteRecording)
|
||||
|
||||
separateByRecording: () =>
|
||||
$recordedTracks = @list.find('.sync')
|
||||
|
|
@ -747,6 +805,10 @@ context.JK.SyncViewer = class SyncViewer
|
|||
this.renderUploadRecordedTrack(commandId, commandMetadata)
|
||||
else
|
||||
this.renderGeneric(commandId, 'upload', commandMetadata)
|
||||
else if commandMetadata.queue == 'cleanup'
|
||||
@cleanupCommandId = commandId
|
||||
@cleanupMetadata = commandMetadata
|
||||
|
||||
|
||||
renderSingleRecording: (userSyncs) =>
|
||||
return if userSyncs.entries.length == 0
|
||||
|
|
@ -813,6 +875,9 @@ context.JK.SyncViewer = class SyncViewer
|
|||
recordingId = @uploadMetadata['recording_id']
|
||||
this.updateSingleRecording(recordingId) if recordingId?
|
||||
|
||||
else if commandId == @cleanupCommandId
|
||||
this.logResult(@cleanupMetadata, success, reason, false)
|
||||
|
||||
else
|
||||
@logger.error("unknown commandId in renderFinishCommand")
|
||||
|
||||
|
|
@ -849,7 +914,8 @@ context.JK.SyncViewer = class SyncViewer
|
|||
$matchingStreamMix = @list.find(".stream-mix.sync[data-recording-id='#{recordingId}']")
|
||||
if $matchingStreamMix.length > 0
|
||||
this.updateProgressOnSync($matchingStreamMix, 'upload', percentage)
|
||||
|
||||
else if commandId == @cleanupCommandId
|
||||
# ignore
|
||||
else
|
||||
@logger.error("unknown commandId in renderFinishCommand")
|
||||
|
||||
|
|
@ -860,7 +926,7 @@ context.JK.SyncViewer = class SyncViewer
|
|||
commandType = data['commandType']
|
||||
commandMetadata = data['commandMetadata']
|
||||
|
||||
category = commandType == 'download' ? 'download' : 'upload'
|
||||
category = commandMetadata.queue
|
||||
|
||||
if category == 'download' && (@downloadCommandId != null && @downloadCommandId != commandId)
|
||||
@logger.warn("received command-start for download but previous command did not send stop")
|
||||
|
|
@ -876,17 +942,20 @@ context.JK.SyncViewer = class SyncViewer
|
|||
commandId = data['commandId']
|
||||
|
||||
if commandId == @downloadCommandId
|
||||
category = 'download'
|
||||
this.renderFinishCommand(commandId, data)
|
||||
@downloadCommandId = null
|
||||
@downloadMetadata = null;
|
||||
else if commandId == @uploadCommandId
|
||||
category = 'upload'
|
||||
this.renderFinishCommand(commandId, data)
|
||||
@uploadCommandId = null
|
||||
@uploadMetadata = null;
|
||||
@uploadMetadata = null
|
||||
else if commandId == @cleanupCommandId
|
||||
this.renderFinishCommand(commandId, data)
|
||||
@cleanupCommandId = null
|
||||
@cleanupMetadata = null
|
||||
|
||||
else
|
||||
@logger.warn("received command-stop for unknown command: #{commandId} #{@downloadCommandId} #{@uploadCommandId}" )
|
||||
@logger.warn("received command-stop for unknown command: #{commandId} #{@downloadCommandId} #{@uploadCommandId} #{@cleanupCommandId}" )
|
||||
|
||||
fileManagerCmdProgress: (e, data) =>
|
||||
#console.log("fileManagerCmdProgress", data)
|
||||
|
|
@ -899,6 +968,8 @@ context.JK.SyncViewer = class SyncViewer
|
|||
else if commandId == @uploadCommandId
|
||||
category = 'upload'
|
||||
this.renderPercentage(commandId, category, data.percentage)
|
||||
else if commandId == @cleanupCommandId
|
||||
# do nothing
|
||||
else
|
||||
@logger.warn("received command-percentage for unknown command")
|
||||
|
||||
|
|
@ -918,6 +989,8 @@ context.JK.SyncViewer = class SyncViewer
|
|||
return 'CLEANUP TRACK'
|
||||
else if metadata.type == 'stream_mix' && metadata.action == 'upload'
|
||||
return 'UPLOADING STREAM MIX'
|
||||
else if metadata.type == 'recording_directory' && metadata.action == 'delete'
|
||||
return 'DELETE RECORDING'
|
||||
else
|
||||
return "#{metadata.action} #{metadata.type}".toUpperCase()
|
||||
|
||||
|
|
@ -938,6 +1011,7 @@ context.JK.SyncViewer = class SyncViewer
|
|||
when 'no-match-in-queue' then 'restart JamKazam'
|
||||
when 'already-done' then 'ignored, already done'
|
||||
when 'failed-convert' then 'failed previously'
|
||||
when 'minimum-protection-time' then 'too soon to delete'
|
||||
else reason
|
||||
|
||||
displaySuccess = if success then 'yes' else 'no'
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@
|
|||
* @param data (optional) data for your template, if applicable
|
||||
* @param options (optional) You can override the default BeautyTips options: https://github.com/dillon-sellars/BeautyTips
|
||||
*/
|
||||
context.JK.confirmBubble = function($element, templateName, data, options) {
|
||||
context.JK.ackBubble = function($element, templateName, data, options) {
|
||||
if(!options) options = {};
|
||||
options.spikeGirth = 0;
|
||||
options.spikeLength = 0;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
|
||||
&.musician-bubble {
|
||||
width:425px;
|
||||
width:438px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
left: 17%;
|
||||
width: 50%;
|
||||
|
||||
#recording-manager-delete {
|
||||
display:none;
|
||||
}
|
||||
// if it's the native client, then show the File Manager span. if it's not (normal browser) hide it.
|
||||
// even if it's the native client, once a command is running, hide File Manager
|
||||
&.native-client {
|
||||
|
|
|
|||
|
|
@ -73,6 +73,24 @@
|
|||
margin-top:4px;
|
||||
}
|
||||
}
|
||||
label[for="keep"] {
|
||||
display: inline;
|
||||
float:right;
|
||||
line-height: 26px;
|
||||
padding-right: 5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
select[name="keep"] {
|
||||
float:right;
|
||||
}
|
||||
div[purpose="keep"] {
|
||||
clear:both;
|
||||
float:right;
|
||||
.icheckbox_minimal {
|
||||
float:right;
|
||||
margin-top:4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,5 +40,13 @@
|
|||
}
|
||||
clear: left;
|
||||
}
|
||||
|
||||
.google_login_button {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.signed_in_to_google {
|
||||
color: yellow;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,13 +194,23 @@
|
|||
|
||||
.export {
|
||||
float:right;
|
||||
margin-right:3px;
|
||||
margin-right:10px;
|
||||
font-size:12px;
|
||||
}
|
||||
.timeago {
|
||||
float:right;
|
||||
font-size:12px;
|
||||
}
|
||||
.totalsize {
|
||||
float:right;
|
||||
margin-right:10px;
|
||||
font-size:12px;
|
||||
}
|
||||
.delete {
|
||||
float:right;
|
||||
margin-right:10px;
|
||||
font-size:12px;
|
||||
}
|
||||
}
|
||||
|
||||
.log-list {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class ApiClaimedRecordingsController < ApiController
|
|||
raise PermissionError, 'only owner of claimed_recording can update it'
|
||||
end
|
||||
@claimed_recording.discard(current_user)
|
||||
render :json => {}, :status => 200
|
||||
respond_with @claimed_recording
|
||||
end
|
||||
|
||||
def download
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
class ApiRecordingsController < ApiController
|
||||
before_filter :api_signed_in_user, :except => [ :add_like ]
|
||||
before_filter :lookup_recording, :only => [ :show, :stop, :claim, :discard, :keep ]
|
||||
|
||||
before_filter :lookup_recording, :only => [ :show, :stop, :claim, :discard, :keep, :delete_claim ]
|
||||
before_filter :lookup_recorded_track, :only => [ :download, :upload_next_part, :upload_sign, :upload_part_complete, :upload_complete ]
|
||||
before_filter :lookup_recorded_video, :only => [ :video_upload_sign, :video_upload_start, :video_upload_complete ]
|
||||
before_filter :lookup_stream_mix, :only => [ :upload_next_part_stream_mix, :upload_sign_stream_mix, :upload_part_complete_stream_mix, :upload_complete_stream_mix ]
|
||||
|
|
@ -94,6 +95,20 @@ class ApiRecordingsController < ApiController
|
|||
end
|
||||
end
|
||||
|
||||
def delete_claim
|
||||
claim = @recording.claim_for_user(current_user)
|
||||
|
||||
if claim
|
||||
claim.discard(current_user)
|
||||
if claim.errors.any?
|
||||
response.status = :unprocessable_entity
|
||||
respond_with claim
|
||||
end
|
||||
end
|
||||
|
||||
respond_with @recording
|
||||
end
|
||||
|
||||
def add_comment
|
||||
if params[:id].blank?
|
||||
render :json => { :message => "Recording ID is required" }, :status => 400
|
||||
|
|
@ -229,118 +244,8 @@ class ApiRecordingsController < ApiController
|
|||
else
|
||||
render :status => 422
|
||||
end
|
||||
end
|
||||
|
||||
def upload_next_part_stream_mix
|
||||
length = params[:length]
|
||||
md5 = params[:md5]
|
||||
|
||||
@quick_mix.upload_next_part(length, md5)
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
|
||||
response.status = :unprocessable_entity
|
||||
# this is not typical, but please don't change this line unless you are sure it won't break anything
|
||||
# this is needed because after_rollback in the RecordedTrackObserver touches the model and something about it's
|
||||
# state doesn't cause errors to shoot out like normal.
|
||||
render :json => { :errors => @quick_mix.errors }, :status => 422
|
||||
else
|
||||
result = {
|
||||
:part => @quick_mix.next_part_to_upload,
|
||||
:offset => @quick_mix.file_offset.to_s
|
||||
}
|
||||
|
||||
render :json => result, :status => 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def upload_sign_stream_mix
|
||||
render :json => @quick_mix.upload_sign(params[:md5]), :status => 200
|
||||
end
|
||||
|
||||
def upload_part_complete_stream_mix
|
||||
part = params[:part]
|
||||
offset = params[:offset]
|
||||
|
||||
@quick_mix.upload_part_complete(part, offset)
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @quick_mix
|
||||
else
|
||||
render :json => {}, :status => 200
|
||||
end
|
||||
end
|
||||
|
||||
def upload_complete_stream_mix
|
||||
@quick_mix.upload_complete
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @quick_mix
|
||||
return
|
||||
else
|
||||
render :json => {}, :status => 200
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def upload_next_part_stream_mix
|
||||
length = params[:length]
|
||||
md5 = params[:md5]
|
||||
|
||||
@quick_mix.upload_next_part(length, md5)
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
|
||||
response.status = :unprocessable_entity
|
||||
# this is not typical, but please don't change this line unless you are sure it won't break anything
|
||||
# this is needed because after_rollback in the RecordedTrackObserver touches the model and something about it's
|
||||
# state doesn't cause errors to shoot out like normal.
|
||||
render :json => { :errors => @quick_mix.errors }, :status => 422
|
||||
else
|
||||
result = {
|
||||
:part => @quick_mix.next_part_to_upload,
|
||||
:offset => @quick_mix.file_offset.to_s
|
||||
}
|
||||
|
||||
render :json => result, :status => 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def upload_sign_stream_mix
|
||||
render :json => @quick_mix.upload_sign(params[:md5]), :status => 200
|
||||
end
|
||||
|
||||
def upload_part_complete_stream_mix
|
||||
part = params[:part]
|
||||
offset = params[:offset]
|
||||
|
||||
@quick_mix.upload_part_complete(part, offset)
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @quick_mix
|
||||
else
|
||||
render :json => {}, :status => 200
|
||||
end
|
||||
end
|
||||
|
||||
def upload_complete_stream_mix
|
||||
@quick_mix.upload_complete
|
||||
|
||||
if @quick_mix.errors.any?
|
||||
response.status = :unprocessable_entity
|
||||
respond_with @quick_mix
|
||||
return
|
||||
else
|
||||
render :json => {}, :status => 200
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def upload_next_part_stream_mix
|
||||
length = params[:length]
|
||||
md5 = params[:md5]
|
||||
|
|
|
|||
|
|
@ -38,4 +38,9 @@ class ApiUserSyncsController < ApiController
|
|||
@next = data[:next]
|
||||
render "api_user_syncs/index", :layout => nil
|
||||
end
|
||||
|
||||
def deletables
|
||||
data = UserSync.deletables({user_id:current_user.id, recording_ids: params[:recording_ids]})
|
||||
render json: {recording_ids: data}, status: 200
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ class RecordingsController < ApplicationController
|
|||
def show
|
||||
@claimed_recording = ClaimedRecording.find_by_id(params[:id])
|
||||
if @claimed_recording.nil?
|
||||
recording = Recording.find(params[:id])
|
||||
@claimed_recording = recording.candidate_claimed_recording
|
||||
recording = Recording.find_by_id(params[:id])
|
||||
@claimed_recording = recording.candidate_claimed_recording if recording
|
||||
end
|
||||
render :layout => "web"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -150,6 +150,10 @@ class SessionsController < ApplicationController
|
|||
render 'oauth_complete', :layout => "landing"
|
||||
end
|
||||
|
||||
def has_google_auth
|
||||
render :json => {has_google_auth: (!!current_user && !!UserAuthorization.google_auth(current_user).first)}
|
||||
end
|
||||
|
||||
def redirect_after_signin(default)
|
||||
redirect_to(params['redirect-to'].blank? ? default : params['redirect-to'])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,20 +25,27 @@ module MusicSessionHelper
|
|||
else
|
||||
unique_users = music_session.unique_users
|
||||
if sharer && unique_users.exists?(sharer)
|
||||
"LIVE SESSION: #{sharer.name}#{additional_member_count(unique_users)}"
|
||||
"LIVE SESSION: #{sharer.name}#{additional_member_count(unique_users, sharer)}"
|
||||
else
|
||||
"LIVE SESSION: #{music_session.creator.name}#{additional_member_count(unique_users)}"
|
||||
"LIVE SESSION: #{music_session.creator.name}#{additional_member_count(unique_users, music_session.creator)}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def additional_member_count(unique_users)
|
||||
def additional_member_count(unique_users, target_user)
|
||||
length = unique_users.length
|
||||
if length < 2
|
||||
""
|
||||
else
|
||||
" & #{length} OTHERS"
|
||||
other_length = length - 1
|
||||
if other_length == 1
|
||||
other_user_in_array = unique_users - [target_user]
|
||||
other_user = other_user_in_array[0]
|
||||
" & #{other_user.name}"
|
||||
else
|
||||
" & #{length - 1} OTHERS"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -23,22 +23,29 @@ module RecordingHelper
|
|||
if claimed_recording.recording.band
|
||||
"RECORDING: #{claimed_recording.recording.band.name}"
|
||||
else
|
||||
unique_users = claimed_recording.recording.users
|
||||
if sharer && unique_users.exists?(sharer)
|
||||
"RECORDING: #{sharer.name}#{additional_member_count(unique_users)}"
|
||||
unique_users = claimed_recording.recording.users.uniq
|
||||
if sharer && unique_users.include?(sharer)
|
||||
"RECORDING: #{sharer.name}#{additional_member_count(unique_users, sharer)}"
|
||||
else
|
||||
"RECORDING: #{claimed_recording.user.name}#{additional_member_count(unique_users)}"
|
||||
"RECORDING: #{claimed_recording.user.name}#{additional_member_count(unique_users, claimed_recording.user)}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def additional_member_count(unique_users)
|
||||
def additional_member_count(unique_users, target_user)
|
||||
length = unique_users.length
|
||||
if length < 2
|
||||
""
|
||||
else
|
||||
" & #{length} OTHERS"
|
||||
other_length = length - 1
|
||||
if other_length == 1
|
||||
other_user_in_array = unique_users - [target_user]
|
||||
other_user = other_user_in_array[0]
|
||||
" & #{other_user.name}"
|
||||
else
|
||||
" & #{length - 1} OTHERS"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
object @claimed_recording
|
||||
|
||||
attributes :id, :name, :description, :is_public, :genre_id
|
||||
attributes :id, :name, :description, :is_public, :genre_id, :discarded
|
||||
|
||||
node :share_url do |claimed_recording|
|
||||
unless claimed_recording.share_token.nil?
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ glue :recording do
|
|||
'recording'
|
||||
end
|
||||
|
||||
attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count, :has_mix?, :mix_state
|
||||
attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count, :has_mix?, :mix_state, :when_will_be_discarded?
|
||||
|
||||
node do |recording|
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ else
|
|||
|
||||
attributes :id, :name, :description, :musician_access, :approval_required, :fan_access, :fan_chat, :band_id, :user_id, :claimed_recording_initiator_id, :track_changes_counter, :max_score
|
||||
|
||||
node :can_join do |session|
|
||||
session.can_join?(current_user, true)
|
||||
end
|
||||
|
||||
node :genres do |item|
|
||||
[item.genre.description] # XXX: need to return single genre; not array
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ else
|
|||
:language, :recurring_mode, :language_description, :scheduled_start_date, :access_description, :timezone, :timezone_id, :timezone_description,
|
||||
:musician_access_description, :fan_access_description, :session_removed_at, :legal_policy, :open_rsvps, :is_unstructured_rsvp?
|
||||
|
||||
node :can_join do |session|
|
||||
session.can_join?(current_user, true)
|
||||
end
|
||||
|
||||
node :share_url do |history|
|
||||
unless history.share_token.nil?
|
||||
share_token_url(history.share_token.token)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
object @recording
|
||||
|
||||
attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count
|
||||
attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count, :when_will_be_discarded?
|
||||
|
||||
node :mix do |recording|
|
||||
if recording.mix
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@
|
|||
|
||||
<script type="text/template" id="template-help-sync-viewer-paused">
|
||||
<div class="help-sync-viewer-paused">
|
||||
JamKazam prevents file uploads, downloads, and recording exports while in a session.
|
||||
JamKazam prevents file uploads, downloads, and recording management while in a session.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
|
@ -139,5 +139,21 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-recording-discarded-soon">
|
||||
<div class="help-recording-discarded-soon">
|
||||
This recording will be discarded {% $.timeago(data.discardTime) %}. If you want to keep this recording, click the (edit) link.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
||||
<script type="text/template" id="template-help-command-enqueued">
|
||||
<div class="help-recording-command-enqueued">
|
||||
Your request will be executed as soon as possible.
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-file-sync-delayed-deletion">
|
||||
<div class="file-sync-delayed-deletion">
|
||||
The files associated with this recording will be deleted as soon as your client has uploaded your tracks and stream mix from this recording.
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -11,4 +11,7 @@
|
|||
<span id="recording-manager-download" class="recording-manager-command">
|
||||
<span>downloading</span><span class="percent">0</span>
|
||||
</span>
|
||||
<span id="recording-manager-delete" class="recording-manager-command-hidden">
|
||||
<span>delete</span><span class="percent">0</span>
|
||||
</span>
|
||||
</span>
|
||||
|
|
@ -204,7 +204,7 @@
|
|||
<div>
|
||||
<div class="spinner-small upload-spinner" id="file-upload-spinner"></div>
|
||||
<div class="select-files-section">
|
||||
<a class="button-orange btn-select-files" href="#">SELECT FILES...</a>
|
||||
<a id="session-notation-file-selection" class="button-orange btn-select-files" href="#">SELECT FILES...</a>
|
||||
<input type="file" class="hidden" id="session-select-files" value="Select Files..."
|
||||
accept=".pdf, .png, .jpg, .jpeg, .gif, .xml, .mxl, .txt" multiple>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -88,12 +88,16 @@ script type="text/template" id='template-sync-viewer-no-syncs'
|
|||
| You have no recordings.
|
||||
|
||||
script type="text/template" id="template-sync-viewer-recording-wrapper-details"
|
||||
.details data-recording-id="{{data.id}}"
|
||||
.details data-recording-id="{{data.id}}" data-claimed-recording-id="{{data.claimedRecordingId}}"
|
||||
a.session-detail-page href="{{data.recording_landing_url}}" rel="external"
|
||||
span.name
|
||||
| {{data.my ? data.my.name : 'Unknown Name'}}
|
||||
span.timeago
|
||||
| {{$.timeago(data.created_at)}}
|
||||
span.totalsize
|
||||
| SIZE: {{data.totalSize}}
|
||||
a.delete href="#"
|
||||
| DELETE
|
||||
a.export href="#"
|
||||
| EXPORT
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
.dialog.configure-tracks{ layout: 'dialog', 'layout-id' => 'edit-recording', id: 'edit-recording-dialog'}
|
||||
.content-head
|
||||
= image_tag "content/icon_add.png", {:width => 19, :height => 19, :class => 'content-icon' }
|
||||
%h1 Edit Recording
|
||||
.dialog-inner
|
||||
%form
|
||||
.field
|
||||
%label{for: 'name'} Recording name:
|
||||
%input{type: 'text', name: 'name'}
|
||||
.field
|
||||
%label{for: 'description'} Description:
|
||||
%textarea{name: 'description', rows: '4'}
|
||||
.field.genre-selector
|
||||
%label{for: 'genre'} Genre:
|
||||
%select{name:'genre'}
|
||||
.field{purpose: 'is_public'}
|
||||
%input{type: 'checkbox', name: 'is_public'}
|
||||
%label{for: 'is_public'} Public Recording
|
||||
|
||||
.buttons
|
||||
%a.button-grey.cancel-btn {'layout-action' => 'cancel'} CANCEL
|
||||
%a.button-orange.delete-btn DELETE
|
||||
%a.button-orange.save-btn UPDATE
|
||||
%br{clear: 'all'}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#edit-recording-dialog.dialog.configure-tracks layout='dialog' layout-id='edit-recording'
|
||||
.content-head
|
||||
= image_tag "content/icon_add.png", {:width => 19, :height => 19, :class => 'content-icon' }
|
||||
h1 Edit Recording
|
||||
.dialog-inner
|
||||
form
|
||||
.field
|
||||
label for='name' Recording name:
|
||||
input type='text' name='name'
|
||||
.field
|
||||
label for='description' Description:
|
||||
textarea name='description' rows='4'
|
||||
.field.genre-selector
|
||||
label for='genre' Genre:
|
||||
select name='genre'
|
||||
.field purpose='is_public'
|
||||
input type='checkbox' name='is_public'
|
||||
label for='is_public' Public Recording
|
||||
|
||||
.buttons
|
||||
.left
|
||||
a.button-grey.cancel-btn layout-action='cancel' CANCEL
|
||||
.right
|
||||
a.button-orange.delete-btn DELETE
|
||||
a.button-orange.save-btn UPDATE
|
||||
br clear='all'
|
||||
|
|
@ -23,12 +23,16 @@
|
|||
.field.w100.left{:purpose => "description"}
|
||||
%label{:for => "description"} Description:
|
||||
%textarea#claim-recording-description.w100{:name => "description"}
|
||||
.field.left{:purpose => "save_video"}
|
||||
%input{:checked => "checked", :name => "save_video", :type => "checkbox"}/
|
||||
%label{:for => "save_video"} Save Video to Computer
|
||||
.field.left{:purpose => "upload_to_youtube"}
|
||||
%input{:checked => "checked", :name => "upload_to_youtube", :type => "checkbox"}/
|
||||
%label{:for => "upload_to_youtube"} Upload Video to YouTube
|
||||
/ TODO VRFS-1849: Uncomment this when rest of feature developed:
|
||||
/ .field.left{:purpose => "save_video"}
|
||||
/ %input{:checked => "checked", :name => "save_video", :type => "checkbox"}/
|
||||
/ %label{:for => "save_video"} Save Video to Computer
|
||||
/ .field.left{:purpose => "upload_to_youtube"}
|
||||
/ %span
|
||||
/ %input{:checked => "checked", :name => "upload_to_youtube", :type => "checkbox"}/
|
||||
/ %label{:for => "upload_to_youtube"} Upload Video to YouTube
|
||||
/ %span
|
||||
/ = render(:partial => "shared/google_login")
|
||||
.field.left{:purpose => "is_public"}
|
||||
%input{:checked => "checked", :name => "is_public", :type => "checkbox"}/
|
||||
%label{:for => "is_public"} Public Recording
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
<% else %>
|
||||
<%= render "layouts/social_meta" %>
|
||||
<% end %>
|
||||
<%= yield(:extra_js) %>
|
||||
</head>
|
||||
<body class="jam" data-client-type="<%= @nativeClient ? 'client' : 'browser' %>">
|
||||
<%= yield %>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<% end %>
|
||||
|
||||
<div class="recordings-page">
|
||||
<% if @claimed_recording.is_public || @claimed_recording.recording.has_access?(current_user) %>
|
||||
<% if !@claimed_recording.recording.deleted && (@claimed_recording.is_public || @claimed_recording.recording.has_access?(current_user)) %>
|
||||
<div class="landing-band">
|
||||
<% unless @claimed_recording.recording.band.blank? %>
|
||||
<div class="landing-avatar">
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if @claimed_recording.is_public || @claimed_recording.recording.has_access?(current_user) %>
|
||||
<% if !@claimed_recording.recording.deleted && (@claimed_recording.is_public || @claimed_recording.recording.has_access?(current_user)) %>
|
||||
<% if signed_in? %>
|
||||
<% unless @claimed_recording.recording.band.nil? %>
|
||||
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @claimed_recording.recording.band, :recent_history => @claimed_recording.recording.band.recent_history} %>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
-content_for :extra_js do
|
||||
javascript:
|
||||
// Check for google authorization using AJAX and show/hide the
|
||||
// google login button / "signed in" label as appropriate:
|
||||
$(window).on('focus', function() {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: "/auth/has_google_auth"
|
||||
}).success(function(data) {
|
||||
if(data.has_google_auth) {
|
||||
$("input.google_login_button").addClass("hidden")
|
||||
$("span.signed_in_to_google").removeClass("hidden")
|
||||
if (window._oauth_win) {
|
||||
window._oauth_win.close()
|
||||
}
|
||||
} else {
|
||||
$("span.signed_in_to_google").addClass("hidden")
|
||||
$("input.google_login_button").removeClass("hidden")
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
-google_auth = (current_user.nil?) ? nil : !!JamRuby::UserAuthorization.google_auth(current_user).first
|
||||
span.signed_in_to_google class=((!google_auth) ? "hidden" : "") ="(Signed in)"
|
||||
input.google_login_button class=((google_auth) ? "hidden" : "") type='image' onclick='window._oauth_win = window.open("/auth/google_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");' src="/assets/google_signin.png" height="30px"
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
/ type and artist
|
||||
.left.ml20.w15
|
||||
.title
|
||||
%a{:href => "/recordings/{{data.candidate_claimed_recording.id}}", :rel => "external", :hoveraction => "recording", :'recording-id' => '{{data.candidate_claimed_recording.id}}'} RECORDING
|
||||
%a.title-text{:href => "/recordings/{{data.candidate_claimed_recording.id}}", :rel => "external", :hoveraction => "recording", :'recording-id' => '{{data.candidate_claimed_recording.id}}'} RECORDING
|
||||
%a.edit-recording-dialog{href: "#"} (edit)
|
||||
.artist
|
||||
%a.artist{:hoveraction => '{{data.feed_item.helpers.artist_hoveraction}}', :profileaction => "{{data.feed_item.helpers.artist_hoveraction}}", :'{{data.feed_item.helpers.artist_datakey}}' => '{{data.feed_item.helpers.artist_id}}'}
|
||||
|
|
|
|||
|
|
@ -152,6 +152,9 @@ if defined?(Bundler)
|
|||
config.multipass_callback_url = "http://jamkazam.desk.com/customer/authentication/multipass/callback"
|
||||
end
|
||||
|
||||
config.desk_multipass_key = "453ddfc0bab00130a9c13bc9a68cf24c" # found in https://jamkazam.desk.com/admin/channels/support-center/auth_settings
|
||||
config.desk_multipass_site = "jamkazam" # found in https://jamkazam.desk.com/admin/channels/support-center/auth_settings
|
||||
|
||||
# perf_data configs
|
||||
config.perf_data_signed_url_timeout = 3600 * 24 # 1 day
|
||||
|
||||
|
|
@ -273,5 +276,7 @@ if defined?(Bundler)
|
|||
config.scoring_timeout_threshold = 5 # how many consequetive bad scores before you are put into the doghouse
|
||||
config.scoring_get_work_interval = 1000 # how much time between normal getwork requests
|
||||
config.scoring_get_work_backoff_interval = 60 * 1000 # how much time between failed getwork requests
|
||||
|
||||
config.recordings_stale_time = 3 # num days of inactivity before we decide that a recording is no longer going to be claimed
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ SampleApp::Application.routes.draw do
|
|||
# oauth
|
||||
match '/auth/:provider/callback', :to => 'sessions#oauth_callback'
|
||||
match '/auth/failure', :to => 'sessions#failure'
|
||||
match '/auth/has_google_auth', :to => 'sessions#has_google_auth'
|
||||
|
||||
# session info page
|
||||
match '/sessions/:id/details' => 'music_sessions#session_info', :via => :get, :as => 'music_scheduled_session_detail'
|
||||
|
|
@ -335,6 +336,7 @@ SampleApp::Application.routes.draw do
|
|||
# downloads/uploads
|
||||
match '/users/:id/syncs' => 'api_user_syncs#index', :via => :get
|
||||
match '/users/:id/syncs/:user_sync_id' => 'api_user_syncs#show', :via => :get
|
||||
match '/users/:id/syncs/deletables' => 'api_user_syncs#deletables', :via => :post
|
||||
|
||||
|
||||
# bands
|
||||
|
|
@ -413,6 +415,7 @@ SampleApp::Application.routes.draw do
|
|||
match '/recordings/:id' => 'api_recordings#show', :via => :get, :as => 'api_recordings_detail'
|
||||
match '/recordings/:id/stop' => 'api_recordings#stop', :via => :post, :as => 'api_recordings_stop'
|
||||
match '/recordings/:id/claim' => 'api_recordings#claim', :via => :post, :as => 'api_recordings_claim'
|
||||
match '/recordings/:id/claim' => 'api_recordings#delete_claim', :via => :delete, :as => 'api_recordings_delete_claim'
|
||||
match '/recordings/:id/comments' => 'api_recordings#add_comment', :via => :post, :as => 'api_recordings_add_comment'
|
||||
match '/recordings/:id/likes' => 'api_recordings#add_like', :via => :post, :as => 'api_recordings_add_like'
|
||||
match '/recordings/:id/discard' => 'api_recordings#discard', :via => :post, :as => 'api_recordings_discard'
|
||||
|
|
|
|||
|
|
@ -57,4 +57,9 @@ ActiveMusicSessionCleaner:
|
|||
ScoreHistorySweeper:
|
||||
cron: 0 * * * *
|
||||
class: "JamRuby::ScoreHistorySweeper"
|
||||
description: "Creates 'ScoreHistory' tables from Scores"
|
||||
description: "Creates 'ScoreHistory' tables from Scores"
|
||||
|
||||
RecordingsCleaner:
|
||||
cron: 0 * * * *
|
||||
class: "JamRuby::RecordingsCleaner"
|
||||
description: "Cleans up recordings that no one wants after 7 days"
|
||||
|
|
@ -25,6 +25,12 @@ describe ApiUserSyncsController do
|
|||
json[:entries].length.should == 0
|
||||
end
|
||||
|
||||
it "deletables" do
|
||||
post :deletables, { :format => 'json', :id => user1.id, recording_ids: ['1'] }
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:recording_ids].should eq(['1'])
|
||||
end
|
||||
|
||||
describe "one recording with two users" do
|
||||
let!(:recording1) {
|
||||
recording = FactoryGirl.create(:recording, owner: user1, band: nil, duration:1)
|
||||
|
|
@ -40,23 +46,12 @@ describe ApiUserSyncsController do
|
|||
}
|
||||
|
||||
it "no claimed_recordings" do
|
||||
# every is supposed to upload immediately, but no downloads until you try claim it. The assertions below validate this
|
||||
|
||||
# if there are no claims, then no one wants the recording. no usersyncs
|
||||
get :index, { :format => 'json', :id => user1.id }
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:next].should be_nil
|
||||
json[:entries].length.should == 2
|
||||
|
||||
recorded_track1 = json[:entries][0]
|
||||
recorded_track1[:upload][:should_upload].should be_true
|
||||
recorded_track1[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track1[:download][:should_download].should be_false
|
||||
recorded_track1[:download][:too_many_downloads].should be_false
|
||||
|
||||
recorded_track2 = json[:entries][1]
|
||||
recorded_track2[:upload][:should_upload].should be_true
|
||||
recorded_track2[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track2[:download][:should_download].should be_false
|
||||
recorded_track2[:download][:too_many_downloads].should be_false
|
||||
json[:entries].length.should == 0
|
||||
end
|
||||
|
||||
it "recording isn't over" do
|
||||
|
|
@ -73,6 +68,9 @@ describe ApiUserSyncsController do
|
|||
|
||||
FactoryGirl.create(:claimed_recording, user: user1, recording: recording1, discarded:false)
|
||||
|
||||
recording1.recorded_tracks[0].fully_uploaded = false
|
||||
recording1.recorded_tracks[0].save!
|
||||
|
||||
get :index, { :format => 'json', :id => user1.id }
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:next].should be_nil
|
||||
|
|
@ -94,7 +92,7 @@ describe ApiUserSyncsController do
|
|||
get :index, { :format => 'json', :id => user2.id }
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:next].should be_nil
|
||||
json[:entries].length.should == 2
|
||||
json[:entries].length.should == 1
|
||||
|
||||
recorded_track1 = json[:entries][0]
|
||||
recorded_track1[:upload][:should_upload].should be_true
|
||||
|
|
@ -102,32 +100,17 @@ describe ApiUserSyncsController do
|
|||
recorded_track1[:download][:should_download].should be_false
|
||||
recorded_track1[:download][:too_many_downloads].should be_false
|
||||
|
||||
recorded_track2 = json[:entries][1]
|
||||
recorded_track2[:upload][:should_upload].should be_true
|
||||
recorded_track2[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track2[:download][:should_download].should be_false
|
||||
recorded_track2[:download][:too_many_downloads].should be_false
|
||||
end
|
||||
|
||||
it "one user decides to discard the recording" do
|
||||
FactoryGirl.create(:claimed_recording, user: user1, recording: recording1, discarded:true)
|
||||
FactoryGirl.create(:claimed_recording, user: user2, recording: recording1, discarded:false)
|
||||
|
||||
# it's a length of zero because recorded_tracks default to 'fully_uploaded = true'. so nothing to do for this user
|
||||
get :index, { :format => 'json', :id => user1.id }
|
||||
json = JSON.parse(response.body, :symbolize_names => true)
|
||||
json[:next].should be_nil
|
||||
json[:entries].length.should == 2
|
||||
|
||||
recorded_track1 = json[:entries][0]
|
||||
recorded_track1[:upload][:should_upload].should be_true
|
||||
recorded_track1[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track1[:download][:should_download].should be_false
|
||||
recorded_track1[:download][:too_many_downloads].should be_false
|
||||
|
||||
recorded_track2 = json[:entries][1]
|
||||
recorded_track2[:upload][:should_upload].should be_true
|
||||
recorded_track2[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track2[:download][:should_download].should be_false
|
||||
recorded_track2[:download][:too_many_downloads].should be_false
|
||||
json[:entries].length.should == 0
|
||||
|
||||
controller.current_user = user2
|
||||
get :index, { :format => 'json', :id => user2.id }
|
||||
|
|
@ -135,16 +118,17 @@ describe ApiUserSyncsController do
|
|||
json[:next].should be_nil
|
||||
json[:entries].length.should == 2
|
||||
|
||||
|
||||
recorded_track1 = json[:entries][0]
|
||||
recorded_track1[:upload][:should_upload].should be_true
|
||||
recorded_track1[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track1[:download][:should_download].should be_false
|
||||
recorded_track1[:download][:should_download].should be_true
|
||||
recorded_track1[:download][:too_many_downloads].should be_false
|
||||
|
||||
recorded_track2 = json[:entries][1]
|
||||
recorded_track2[:upload][:should_upload].should be_true
|
||||
recorded_track2[:upload][:too_many_upload_failures].should be_false
|
||||
recorded_track2[:download][:should_download].should be_false
|
||||
recorded_track2[:download][:should_download].should be_true
|
||||
recorded_track2[:download][:too_many_downloads].should be_false
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -60,11 +60,18 @@ describe MusicSessionHelper do
|
|||
|
||||
describe "additional_member_count" do
|
||||
it "no unique users" do
|
||||
helper.additional_member_count([]).should == ""
|
||||
helper.additional_member_count([], @user).should == ""
|
||||
end
|
||||
|
||||
it "has 2 users" do
|
||||
helper.additional_member_count(['', '']).should == " & 2 OTHERS"
|
||||
user2 = FactoryGirl.create(:user)
|
||||
helper.additional_member_count([@user, user2], @user).should == " & #{user2.name}"
|
||||
end
|
||||
|
||||
it "has 3 users" do
|
||||
user2 = FactoryGirl.create(:user)
|
||||
user3 = FactoryGirl.create(:user)
|
||||
helper.additional_member_count([@user, user2, user3], @user).should == " & 2 OTHERS"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -79,15 +79,45 @@ describe MusicSessionHelper do
|
|||
result.start_with?("RECORDING").should be_true
|
||||
result.end_with?(@claimed_recording.user.name).should be_true
|
||||
end
|
||||
|
||||
# regression: https://jamkazam.atlassian.net/browse/VRFS-2468
|
||||
it "correct number of others when multiple tracks for 2 users" do
|
||||
second_user = FactoryGirl.create(:user)
|
||||
track1 = FactoryGirl.create(:recorded_track, user: second_user, recording: @recording)
|
||||
track2 = FactoryGirl.create(:recorded_track, user: second_user, recording: @recording)
|
||||
result = helper.title_for_claimed_recording(@claimed_recording)
|
||||
result.include?("& #{second_user.name}").should be_true
|
||||
|
||||
end
|
||||
|
||||
# regression: https://jamkazam.atlassian.net/browse/VRFS-2468
|
||||
it "correct number of others when multiple tracks for 3 users" do
|
||||
second_user = FactoryGirl.create(:user)
|
||||
track1 = FactoryGirl.create(:recorded_track, user: second_user, recording: @recording)
|
||||
track2 = FactoryGirl.create(:recorded_track, user: second_user, recording: @recording)
|
||||
third_user = FactoryGirl.create(:user)
|
||||
track1 = FactoryGirl.create(:recorded_track, user: third_user, recording: @recording)
|
||||
track2 = FactoryGirl.create(:recorded_track, user: third_user, recording: @recording)
|
||||
result = helper.title_for_claimed_recording(@claimed_recording)
|
||||
result.include?("& 2 OTHERS").should be_true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "additional_member_count" do
|
||||
it "no unique users" do
|
||||
helper.additional_member_count([]).should == ""
|
||||
helper.additional_member_count([], @user).should == ""
|
||||
end
|
||||
|
||||
it "has 2 users" do
|
||||
helper.additional_member_count(['', '']).should == " & 2 OTHERS"
|
||||
user2 = FactoryGirl.create(:user)
|
||||
helper.additional_member_count([@user, user2], @user).should == " & #{user2.name}"
|
||||
end
|
||||
|
||||
it "has 3 users" do
|
||||
user2 = FactoryGirl.create(:user)
|
||||
user3 = FactoryGirl.create(:user)
|
||||
helper.additional_member_count([@user, user2, user3], @user).should == " & 2 OTHERS"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue