diff --git a/admin/Gemfile b/admin/Gemfile
index cb7f6563c..7c8ba4476 100644
--- a/admin/Gemfile
+++ b/admin/Gemfile
@@ -37,7 +37,8 @@ gem 'carrierwave', '0.9.0'
gem 'carrierwave_direct'
gem 'uuidtools', '2.1.2'
gem 'bcrypt-ruby', '3.0.1'
-gem 'jquery-rails', '2.3.0' # pinned because jquery-ui-rails was split from jquery-rails, but activeadmin doesn't support this gem yet
+gem 'jquery-rails' # , '2.3.0' # pinned because jquery-ui-rails was split from jquery-rails, but activeadmin doesn't support this gem yet
+gem 'jquery-ui-rails'
gem 'rails3-jquery-autocomplete'
gem 'activeadmin', '0.6.2'
gem 'mime-types', '1.25'
@@ -48,7 +49,8 @@ gem 'country-select'
gem 'aasm', '3.0.16'
gem 'postgres-copy', '0.6.0'
gem 'aws-sdk', '1.29.1'
-gem 'bugsnag'
+gem 'bugsnag'
+gem 'gon'
gem 'resque'
gem 'resque-retry'
gem 'resque-failed-job-mailer'
diff --git a/admin/app/admin/crash_dumps.rb b/admin/app/admin/crash_dumps.rb
index e21edcfb3..97170df90 100644
--- a/admin/app/admin/crash_dumps.rb
+++ b/admin/app/admin/crash_dumps.rb
@@ -3,6 +3,7 @@ ActiveAdmin.register JamRuby::CrashDump, :as => 'Crash Dump' do
filter :timestamp
filter :user_email, :as => :string
filter :client_id
+ menu :parent => 'Debug'
index do
column "Timestamp" do |post|
diff --git a/admin/app/admin/errored_mix.rb b/admin/app/admin/errored_mix.rb
new file mode 100644
index 000000000..8d6270385
--- /dev/null
+++ b/admin/app/admin/errored_mix.rb
@@ -0,0 +1,52 @@
+ActiveAdmin.register JamRuby::Mix, :as => 'Errored Mixes' do
+
+ config.filters = true
+ config.per_page = 50
+ config.clear_action_items!
+ config.sort_order = "created_at_desc"
+ menu :parent => 'Sessions'
+
+ controller do
+
+ def scoped_collection
+ Mix.where('error_reason is not NULL and completed = FALSE')
+ end
+
+ def mix_again
+ @mix = Mix.find(params[:id])
+ @mix.enqueue
+ render :json => {}
+ end
+ end
+
+ index :as => :block do |mix|
+ div :for => mix do
+ h3 "Mix (Users: #{mix.recording.users.map { |u| u.name }.join ','}) (When: #{mix.created_at.strftime('%b %d %Y, %H:%M')})"
+ columns do
+ column do
+ panel 'Mix Details' do
+ attributes_table_for(mix) do
+ row :recording do |mix| auto_link(mix.recording, mix.recording.id) end
+ row :created_at do |mix| mix.created_at.strftime('%b %d %Y, %H:%M') end
+ row :s3_url do |mix| mix.url end
+ row :manifest do |mix| mix.manifest end
+ row :completed do |mix| "#{mix.completed ? "finished" : "not finished"}" end
+ if mix.completed
+ row :completed_at do |mix| mix.completed_at.strftime('%b %d %Y, %H:%M') end
+ elsif mix.error_count > 0
+ row :error_count do |mix| "#{mix.error_count} times failed" end
+ row :error_reason do |mix| "last reason failed: #{mix.error_reason}" end
+ row :error_detail do |mix| "last error detail: #{mix.error_detail}" end
+ row :mix_again do |mix| div :class => 'mix-again' do
+ span do link_to "Mix Again", '#', :class => 'mix-again', :'data-mix-id' => mix.id end
+ span do div :class => 'mix-again-dialog' do end end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/admin/app/admin/isp_scoring_data.rb b/admin/app/admin/isp_scoring_data.rb
index da2201eb4..02756ffc0 100644
--- a/admin/app/admin/isp_scoring_data.rb
+++ b/admin/app/admin/isp_scoring_data.rb
@@ -2,4 +2,6 @@ ActiveAdmin.register JamRuby::IspScoreBatch, :as => 'Isp Score Data' do
config.sort_order = 'created_at_desc'
+ menu :parent => 'Debug'
+
end
diff --git a/admin/app/admin/jam_ruby_invited_users.rb b/admin/app/admin/jam_ruby_invited_users.rb
index 928bef738..e89660e1c 100644
--- a/admin/app/admin/jam_ruby_invited_users.rb
+++ b/admin/app/admin/jam_ruby_invited_users.rb
@@ -1,5 +1,5 @@
ActiveAdmin.register JamRuby::InvitedUser, :as => 'Invited Users' do
- menu :label => 'Invite Users'
+ menu :label => 'Invite', :parent => 'Users'
config.sort_order = 'created_at'
diff --git a/admin/app/admin/jam_ruby_users.rb b/admin/app/admin/jam_ruby_users.rb
index d6c8587ac..6332400ed 100644
--- a/admin/app/admin/jam_ruby_users.rb
+++ b/admin/app/admin/jam_ruby_users.rb
@@ -1,6 +1,6 @@
ActiveAdmin.register JamRuby::User, :as => 'Users' do
- menu :label => 'Jam User'
+ menu :label => 'Users', :parent => 'Users'
config.sort_order = 'created_at DESC'
diff --git a/admin/app/admin/mix.rb b/admin/app/admin/mix.rb
new file mode 100644
index 000000000..f2c86e7ec
--- /dev/null
+++ b/admin/app/admin/mix.rb
@@ -0,0 +1,48 @@
+ActiveAdmin.register JamRuby::Mix, :as => 'Mixes' do
+
+ config.filters = true
+ config.per_page = 50
+ config.clear_action_items!
+ config.sort_order = "created_at_desc"
+ menu :parent => 'Sessions'
+
+ controller do
+
+ def mix_again
+ @mix = Mix.find(params[:id])
+ @mix.enqueue
+ render :json => {}
+ end
+ end
+
+ index :as => :block do |mix|
+ div :for => mix do
+ h3 "Mix (Users: #{mix.recording.users.map { |u| u.name }.join ','}) (When: #{mix.created_at.strftime('%b %d %Y, %H:%M')})"
+ columns do
+ column do
+ panel 'Mix Details' do
+ attributes_table_for(mix) do
+ row :recording do |mix| auto_link(mix.recording, mix.recording.id) end
+ row :created_at do |mix| mix.created_at.strftime('%b %d %Y, %H:%M') end
+ row :s3_url do |mix| mix.url end
+ row :manifest do |mix| mix.manifest end
+ row :completed do |mix| "#{mix.completed ? "finished" : "not finished"}" end
+ if mix.completed
+ row :completed_at do |mix| mix.completed_at.strftime('%b %d %Y, %H:%M') end
+ elsif mix.error_count > 0
+ row :error_count do |mix| "#{mix.error_count} times failed" end
+ row :error_reason do |mix| "last reason failed: #{mix.error_reason}" end
+ row :error_detail do |mix| "last error detail: #{mix.error_detail}" end
+ row :mix_again do |mix| div :class => 'mix-again' do
+ span do link_to "Mix Again", '#', :class => 'mix-again', :'data-mix-id' => mix.id end
+ span do div :class => 'mix-again-dialog' do end end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/admin/app/admin/music_session_history.rb b/admin/app/admin/music_session_history.rb
index 69b5fe594..2de49e4b0 100644
--- a/admin/app/admin/music_session_history.rb
+++ b/admin/app/admin/music_session_history.rb
@@ -1,8 +1,10 @@
-ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History', :sort_order => 'created_at DESC' do
+ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History' do
config.filters = false
config.per_page = 50
config.clear_action_items!
+ config.sort_order = 'created_at_desc'
+ menu :parent => 'Sessions', :label => 'Sessions'
controller do
def scoped_collection
diff --git a/admin/app/admin/promo_buzz.rb b/admin/app/admin/promo_buzz.rb
index e3d0035b1..f4404e4b8 100644
--- a/admin/app/admin/promo_buzz.rb
+++ b/admin/app/admin/promo_buzz.rb
@@ -1,6 +1,6 @@
ActiveAdmin.register JamRuby::PromoBuzz, :as => 'Buzz' do
- menu :label => 'Home Page Buzz'
+ menu :label => 'Buzz', :parent => 'Home Page'
config.sort_order = 'position ASC aasm_state DESC updated_at DESC'
config.batch_actions = false
diff --git a/admin/app/admin/promo_latest.rb b/admin/app/admin/promo_latest.rb
index 4f759a555..22ae49575 100644
--- a/admin/app/admin/promo_latest.rb
+++ b/admin/app/admin/promo_latest.rb
@@ -1,6 +1,6 @@
ActiveAdmin.register JamRuby::PromoLatest, :as => 'Latest' do
- menu :label => 'Home Page Latest'
+ menu :label => 'Latest', :parent => 'Home Page'
config.batch_actions = false
config.sort_order = ''
diff --git a/admin/app/admin/user.rb b/admin/app/admin/user.rb
deleted file mode 100644
index f67079634..000000000
--- a/admin/app/admin/user.rb
+++ /dev/null
@@ -1,8 +0,0 @@
- ActiveAdmin.register JamRuby::User do
- # define routes for "autocomplete :admin_user, :email"
- collection_action :autocomplete_user_email, :method => :get
-
- controller do
- autocomplete :invited_user, :email
- end
-end
diff --git a/admin/app/admin/user_progression.rb b/admin/app/admin/user_progression.rb
index ab8f73c84..cbd54744c 100644
--- a/admin/app/admin/user_progression.rb
+++ b/admin/app/admin/user_progression.rb
@@ -1,7 +1,7 @@
ActiveAdmin.register JamRuby::User, :as => 'User Progression' do
PROGRESSION_DATE = '%Y-%m-%d %H:%M' unless defined?(PROGRESSION_DATE)
- menu :label => 'User Progression'
+ menu :label => 'Progression', :parent => 'Users'
config.sort_order = 'updated_at DESC'
config.batch_actions = false
diff --git a/admin/app/assets/javascripts/active_admin.js b/admin/app/assets/javascripts/active_admin.js
index 7498ec940..0ebd669c5 100644
--- a/admin/app/assets/javascripts/active_admin.js
+++ b/admin/app/assets/javascripts/active_admin.js
@@ -1,2 +1,11 @@
-//= require active_admin/base
-//= require autocomplete-rails
\ No newline at end of file
+// //= require active_admin/base
+//= require jquery
+//= require jquery_ujs
+//= require jquery.ui.core
+//= require jquery.ui.widget
+//= require jquery.ui.datepicker
+//= require jquery.ui.dialog
+//= require active_admin/application
+//= require autocomplete-rails
+//= require base
+//= require_tree .
diff --git a/admin/app/assets/javascripts/admin_rest.js b/admin/app/assets/javascripts/admin_rest.js
new file mode 100644
index 000000000..e41ea253a
--- /dev/null
+++ b/admin/app/assets/javascripts/admin_rest.js
@@ -0,0 +1,38 @@
+(function(context,$) {
+
+ /**
+ * Javascript wrappers for the REST API
+ */
+
+ "use strict";
+
+ context.JK = context.JK || {};
+ context.JK.RestAdmin = function() {
+
+ var self = this;
+ var logger = context.JK.logger;
+
+ function tryMixAgain(options) {
+ var mixId = options['mix_id']
+ return $.ajax({
+ type: "POST",
+ dataType: "json",
+ url: gon.global.prefix + 'api/mix/' + mixId + '/enqueue',
+ contentType: 'application/json',
+ processData: false
+ });
+ }
+
+ function initialize() {
+ return self;
+ }
+
+ // Expose publics
+ this.initialize = initialize;
+ this.tryMixAgain = tryMixAgain;
+
+ return this;
+ };
+
+
+})(window,jQuery);
\ No newline at end of file
diff --git a/admin/app/assets/javascripts/application.js b/admin/app/assets/javascripts/application.js
index 9097d830e..fb7cad79b 100644
--- a/admin/app/assets/javascripts/application.js
+++ b/admin/app/assets/javascripts/application.js
@@ -12,4 +12,3 @@
//
//= require jquery
//= require jquery_ujs
-//= require_tree .
diff --git a/admin/app/assets/javascripts/base.js b/admin/app/assets/javascripts/base.js
new file mode 100644
index 000000000..1ee58192f
--- /dev/null
+++ b/admin/app/assets/javascripts/base.js
@@ -0,0 +1,23 @@
+(function(context,$) {
+
+ context.JK = {}
+
+ var console_methods = [
+ 'log', 'debug', 'info', 'warn', 'error', 'assert',
+ 'clear', 'dir', 'dirxml', 'trace', 'group',
+ 'groupCollapsed', 'groupEnd', 'time', 'timeEnd',
+ 'timeStamp', 'profile', 'profileEnd', 'count',
+ 'exception', 'table'
+ ];
+
+ if ('undefined' === typeof(context.console)) {
+ context.console = {};
+ $.each(console_methods, function(index, value) {
+ context.console[value] = $.noop;
+ });
+ }
+
+ context.JK.logger = context.console;
+
+
+})(window, jQuery);
\ No newline at end of file
diff --git a/admin/app/assets/javascripts/logger.js b/admin/app/assets/javascripts/logger.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/admin/app/assets/javascripts/mix_again.js b/admin/app/assets/javascripts/mix_again.js
new file mode 100644
index 000000000..5086e7a14
--- /dev/null
+++ b/admin/app/assets/javascripts/mix_again.js
@@ -0,0 +1,22 @@
+(function(context,$) {
+
+
+ var restAdmin = context.JK.RestAdmin();
+
+ $(function() {
+ // convert mix again links to ajax
+ $('a.mix-again').click(function() {
+ var $link = $(this);
+ restAdmin.tryMixAgain({mix_id: $link.attr('data-mix-id')})
+ .done(function(response) {
+ $link.closest('div.mix-again').find('div.mix-again-dialog').html('
Mix enqueued
Resque Web').dialog();
+ })
+ .error(function(jqXHR) {
+ $link.closest('div.mix-again').find('div.mix-again-dialog').html('Mix failed: ' + jqXHR.responseText).dialog();
+ })
+
+ return false;
+ })
+
+ });
+})(window, jQuery);
\ No newline at end of file
diff --git a/admin/app/assets/stylesheets/active_admin.css.scss b/admin/app/assets/stylesheets/active_admin.css.scss
index 0f919ef50..4798f7467 100644
--- a/admin/app/assets/stylesheets/active_admin.css.scss
+++ b/admin/app/assets/stylesheets/active_admin.css.scss
@@ -7,6 +7,9 @@
// For example, to change the sidebar width:
// $sidebar-width: 242px;
+/*
+*= require jquery.ui.all
+*/
// Active Admin's got SASS!
@import "active_admin/mixins";
@import "active_admin/base";
diff --git a/admin/app/assets/stylesheets/application.css b/admin/app/assets/stylesheets/application.css
index 3192ec897..290b7aab4 100644
--- a/admin/app/assets/stylesheets/application.css
+++ b/admin/app/assets/stylesheets/application.css
@@ -9,5 +9,6 @@
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
+ *= require jquery.ui.all
*= require_tree .
*/
diff --git a/admin/app/assets/stylesheets/custom.css.scss b/admin/app/assets/stylesheets/custom.css.scss
index bbaf0546b..97651a7af 100644
--- a/admin/app/assets/stylesheets/custom.css.scss
+++ b/admin/app/assets/stylesheets/custom.css.scss
@@ -1,3 +1,4 @@
+
.version-info {
font-size:small;
color:lightgray;
diff --git a/admin/app/controllers/application_controller.rb b/admin/app/controllers/application_controller.rb
index e8065d950..ba9580ff2 100644
--- a/admin/app/controllers/application_controller.rb
+++ b/admin/app/controllers/application_controller.rb
@@ -1,3 +1,10 @@
class ApplicationController < ActionController::Base
protect_from_forgery
+
+ before_filter :prepare_gon
+
+ def prepare_gon
+ gon.another = 'hello'
+ gon.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
+ end
end
diff --git a/admin/config/application.rb b/admin/config/application.rb
index f3b218211..7294326de 100644
--- a/admin/config/application.rb
+++ b/admin/config/application.rb
@@ -33,7 +33,7 @@ module JamAdmin
# Activate observers that should always be running.
config.active_record.observers = "JamRuby::InvitedUserObserver"
- config.assets.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
+ #config.assets.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
@@ -80,14 +80,16 @@ module JamAdmin
config.storage_type = :fog
# these only need to be set if store_artifact_to_files = false
- config.aws_artifact_access_key_id = ENV['AWS_KEY']
- config.aws_artifact_secret_access_key = ENV['AWS_SECRET']
- config.aws_artifact_region = 'us-east-1'
- config.aws_artifact_bucket_public = 'jamkazam-dev-public'
- config.aws_artifact_bucket = 'jamkazam-dev'
- config.aws_artifact_cache = '315576000'
+ config.aws_access_key_id = ENV['AWS_KEY']
+ config.aws_secret_access_key = ENV['AWS_SECRET']
+ config.aws_region = 'us-east-1'
+ config.aws_bucket_public = 'jamkazam-dev-public'
+ config.aws_bucket = 'jamkazam-dev'
+ config.aws_cache = '315576000'
# for carrierwave_direct
config.action_controller.allow_forgery_protection = false
+
+ config.redis_host = "localhost:6379"
end
end
diff --git a/admin/config/environment.rb b/admin/config/environment.rb
index 4942864e3..d7cd279be 100644
--- a/admin/config/environment.rb
+++ b/admin/config/environment.rb
@@ -1,5 +1,7 @@
# Load the rails application
require File.expand_path('../application', __FILE__)
+APP_CONFIG = Rails.application.config
+
# Initialize the rails application
JamAdmin::Application.initialize!
diff --git a/admin/config/environments/production.rb b/admin/config/environments/production.rb
index 30cd4e4e1..a071fa961 100644
--- a/admin/config/environments/production.rb
+++ b/admin/config/environments/production.rb
@@ -71,6 +71,6 @@ JamAdmin::Application.configure do
# Show the logging configuration on STDOUT
config.show_log_configuration = false
- config.aws_artifact_bucket_public = 'jamkazam-public'
- config.aws_artifact_bucket = 'jamkazam'
+ config.aws_bucket_public = 'jamkazam-public'
+ config.aws_bucket = 'jamkazam'
end
diff --git a/admin/config/initializers/active_admin.rb b/admin/config/initializers/active_admin.rb
index 1b7899669..ab2394c35 100644
--- a/admin/config/initializers/active_admin.rb
+++ b/admin/config/initializers/active_admin.rb
@@ -2,6 +2,7 @@ class Footer < ActiveAdmin::Component
def build
super(id: "footer")
para "version info: web=#{::JamAdmin::VERSION} lib=#{JamRuby::VERSION} db=#{JamDb::VERSION}"
+ render :inline => include_gon
end
end
diff --git a/admin/config/initializers/carrierwave.rb b/admin/config/initializers/carrierwave.rb
index 8a3a54052..f00908608 100644
--- a/admin/config/initializers/carrierwave.rb
+++ b/admin/config/initializers/carrierwave.rb
@@ -10,13 +10,13 @@ CarrierWave.configure do |config|
config.storage = :fog
config.fog_credentials = {
:provider => 'AWS',
- :aws_access_key_id => JamAdmin::Application.config.aws_artifact_access_key_id,
- :aws_secret_access_key => JamAdmin::Application.config.aws_artifact_secret_access_key,
- :region => JamAdmin::Application.config.aws_artifact_region,
+ :aws_access_key_id => JamAdmin::Application.config.aws_access_key_id,
+ :aws_secret_access_key => JamAdmin::Application.config.aws_secret_access_key,
+ :region => JamAdmin::Application.config.aws_region,
}
- config.fog_directory = JamAdmin::Application.config.aws_artifact_bucket_public # required
+ config.fog_directory = JamAdmin::Application.config.aws_bucket_public # required
config.fog_public = true # optional, defaults to true
- config.fog_attributes = {'Cache-Control'=>"max-age=#{JamAdmin::Application.config.aws_artifact_cache}"} # optional, defaults to {}
+ config.fog_attributes = {'Cache-Control'=>"max-age=#{JamAdmin::Application.config.aws_cache}"} # optional, defaults to {}
end
end
diff --git a/admin/config/initializers/gon.rb b/admin/config/initializers/gon.rb
new file mode 100644
index 000000000..9eb7ab9da
--- /dev/null
+++ b/admin/config/initializers/gon.rb
@@ -0,0 +1 @@
+Gon.global.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
\ No newline at end of file
diff --git a/admin/config/initializers/resque.rb b/admin/config/initializers/resque.rb
new file mode 100644
index 000000000..5c3c402fc
--- /dev/null
+++ b/admin/config/initializers/resque.rb
@@ -0,0 +1 @@
+Resque.redis = Rails.application.config.redis_host
\ No newline at end of file
diff --git a/admin/config/routes.rb b/admin/config/routes.rb
index 44f4c475e..a86cb918a 100644
--- a/admin/config/routes.rb
+++ b/admin/config/routes.rb
@@ -15,6 +15,7 @@ JamAdmin::Application.routes.draw do
ActiveAdmin.routes(self)
match '/api/artifacts' => 'artifacts#update_artifacts', :via => :post
+ match '/api/mix/:id/enqueue' => 'admin/mixes#mix_again', :via => :post
mount Resque::Server.new, :at => "/resque"
diff --git a/admin/lib/tasks/custom_routes.rake b/admin/lib/tasks/custom_routes.rake
new file mode 100644
index 000000000..539f9c66d
--- /dev/null
+++ b/admin/lib/tasks/custom_routes.rake
@@ -0,0 +1,12 @@
+desc 'Print out all defined routes in match order, with names. Target specific controller with CONTROLLER=x.'
+task custom_routes: :environment do
+ require 'rails/application/route_inspector'
+
+ inspector = Rails::Application::RouteInspector.new
+ puts inspector.format(Rails.application.routes.routes)
+
+ #all_routes = Rails.application.routes.routes
+
+ #inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
+ #puts inspector.format(ActionDispatch::Routing::ConsoleFormatter.new, ENV['CONTROLLER'])
+end
\ No newline at end of file
diff --git a/db/manifest b/db/manifest
index 0ba311dfe..5a9d3c4c8 100755
--- a/db/manifest
+++ b/db/manifest
@@ -86,4 +86,6 @@ music_sessions_have_claimed_recording.sql
discardable_recorded_tracks2.sql
icecast.sql
home_page_promos.sql
-mix_job_watch.sql
\ No newline at end of file
+mix_job_watch.sql
+music_session_constraints.sql
+mixes_drop_manifest_add_retry.sql
\ No newline at end of file
diff --git a/db/up/mixes_drop_manifest_add_retry.sql b/db/up/mixes_drop_manifest_add_retry.sql
new file mode 100644
index 000000000..d7ce1dafa
--- /dev/null
+++ b/db/up/mixes_drop_manifest_add_retry.sql
@@ -0,0 +1,2 @@
+ALTER TABLE mixes DROP COLUMN manifest;
+ALTER TABLE mixes ADD COLUMN should_retry BOOLEAN NOT NULL DEFAULT FALSE;
\ No newline at end of file
diff --git a/db/up/music_session_constraints.sql b/db/up/music_session_constraints.sql
new file mode 100644
index 000000000..72f2bccd4
--- /dev/null
+++ b/db/up/music_session_constraints.sql
@@ -0,0 +1,9 @@
+alter table music_sessions_comments drop constraint music_sessions_comments_music_session_id_fkey;
+alter table music_sessions_comments add constraint ms_comments_ms_history_fkey foreign key (music_session_id)
+references music_sessions_history(music_session_id) match simple
+ON UPDATE NO ACTION ON DELETE CASCADE;
+
+alter table music_sessions_likers drop constraint music_sessions_likers_music_session_id_fkey;
+alter table music_sessions_likers add constraint ms_likers_ms_history_fkey foreign key (music_session_id)
+references music_sessions_history(music_session_id) match simple
+ON UPDATE NO ACTION ON DELETE CASCADE;
diff --git a/ruby/lib/jam_ruby.rb b/ruby/lib/jam_ruby.rb
index 41885bfcf..0a36ead74 100755
--- a/ruby/lib/jam_ruby.rb
+++ b/ruby/lib/jam_ruby.rb
@@ -29,6 +29,7 @@ require "jam_ruby/lib/s3_util"
require "jam_ruby/lib/s3_manager"
require "jam_ruby/lib/profanity"
require "jam_ruby/resque/audiomixer"
+require "jam_ruby/resque/scheduled/audiomixer_retry"
require "jam_ruby/mq_router"
require "jam_ruby/base_manager"
require "jam_ruby/connection_manager"
@@ -64,6 +65,8 @@ require "jam_ruby/models/band_musician"
require "jam_ruby/models/connection"
require "jam_ruby/models/friendship"
require "jam_ruby/models/music_session"
+require "jam_ruby/models/music_session_comment"
+require "jam_ruby/models/music_session_liker"
require "jam_ruby/models/music_session_history"
require "jam_ruby/models/music_session_user_history"
require "jam_ruby/models/music_session_perf_data"
@@ -80,6 +83,9 @@ require "jam_ruby/models/user_follower"
require "jam_ruby/models/user_following"
require "jam_ruby/models/search"
require "jam_ruby/models/recording"
+require "jam_ruby/models/recording_comment"
+require "jam_ruby/models/recording_liker"
+require "jam_ruby/models/recording_play"
require "jam_ruby/models/recorded_track"
require "jam_ruby/models/recorded_track_observer"
require "jam_ruby/models/mix"
diff --git a/ruby/lib/jam_ruby/models/icecast_limit.rb b/ruby/lib/jam_ruby/models/icecast_limit.rb
index 0249cb2b1..b3670b8bd 100644
--- a/ruby/lib/jam_ruby/models/icecast_limit.rb
+++ b/ruby/lib/jam_ruby/models/icecast_limit.rb
@@ -13,7 +13,6 @@ module JamRuby
def init
- #puts "Init self.client #{self.clients}"
self.clients ||= 10000
self.sources ||= 1000
self.queue_size ||= 102400
@@ -36,4 +35,4 @@ module JamRuby
end
end
-end
\ No newline at end of file
+end
diff --git a/ruby/lib/jam_ruby/models/mix.rb b/ruby/lib/jam_ruby/models/mix.rb
index 8ab73473d..8f712a7fb 100644
--- a/ruby/lib/jam_ruby/models/mix.rb
+++ b/ruby/lib/jam_ruby/models/mix.rb
@@ -9,22 +9,40 @@ module JamRuby
self.primary_key = 'id'
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :mixes
- def self.schedule(recording, manifest)
+
+
+ def self.schedule(recording)
raise if recording.nil?
- raise if manifest.nil?
mix = Mix.new
mix.recording = recording
- mix.manifest = manifest.to_json
mix.save
- mix.url = construct_filename(recording.id, mix.id)
+ mix.url = construct_filename(mix.created_at, recording.id, mix.id)
if mix.save
- Resque.enqueue(AudioMixer, mix.id, mix.sign_put)
+ mix.enqueue
end
mix
end
+ def enqueue
+ begin
+ Resque.enqueue(AudioMixer, self.id, self.sign_put)
+ rescue
+ # implies redis is down. we don't update started_at
+ false
+ end
+
+ Mix.where(:id => self.id).update_all(:started_at => Time.now)
+
+ true
+ end
+
+ def can_download?(some_user)
+ !ClaimedRecording.find_by_user_id_and_recording_id(some_user.id, recording_id).nil?
+ end
+
+
def errored(reason, detail)
self.error_reason = reason
self.error_detail = detail
@@ -44,8 +62,25 @@ module JamRuby
end
end
+ # valid for 1 day; because the s3 urls eventually expire
+ def manifest
+ one_day = 60 * 60 * 24
+
+ manifest = { "files" => [], "timeline" => [] }
+ mix_params = []
+ recording.recorded_tracks.each do |recorded_track|
+ manifest["files"] << { "filename" => recorded_track.sign_url(one_day), "codec" => "vorbis", "offset" => 0 }
+ mix_params << { "level" => 100, "balance" => 0 }
+ end
+
+ manifest["timeline"] << { "timestamp" => 0, "mix" => mix_params }
+ manifest["output"] = { "codec" => "vorbis" }
+ manifest["recording_id"] = self.id
+ manifest
+ end
+
def s3_url
- s3_manager.s3_url(filename)
+ s3_manager.s3_url(url)
end
def is_completed
@@ -54,11 +89,17 @@ module JamRuby
def sign_url(expiration_time = 120)
# expire link in 1 minute--the expectation is that a client is immediately following this link
- s3_manager.sign_url(filename, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
+ s3_manager.sign_url(self.url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
end
def sign_put(expiration_time = 3600 * 24)
- s3_manager.sign_url(filename, {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put)
+ s3_manager.sign_url(self.url, {:expires => expiration_time, :content_type => 'audio/ogg', :secure => false}, :put)
+ end
+
+ def self.queue_jobs_needing_retry
+ Mix.find_each(:conditions => 'should_retry = TRUE or started_at is NULL', :batch_size => 100) do |mix|
+ mix.enqueue
+ end
end
private
@@ -69,14 +110,12 @@ module JamRuby
def filename
# construct a path for s3
- Mix.construct_filename(self.recording.id, self.id)
+ Mix.construct_filename(self.created_at, self.recording.id, self.id)
end
- def self.construct_filename(recording_id, id)
+ def self.construct_filename(created_at, recording_id, id)
raise "unknown ID" unless id
- "recordings/#{recording_id}/mix-#{id}.ogg"
+ "recordings/#{created_at.strftime('%m-%d-%Y')}/#{recording_id}/mix-#{id}.ogg"
end
-
-
end
end
diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb
index e419d39ba..1a2df5603 100644
--- a/ruby/lib/jam_ruby/models/music_session.rb
+++ b/ruby/lib/jam_ruby/models/music_session.rb
@@ -37,6 +37,7 @@ module JamRuby
validate :creator_is_musician
validate :no_new_playback_while_playing
+
def creator_is_musician
unless creator.musician?
errors.add(:creator, ValidationMessages::MUST_BE_A_MUSICIAN)
diff --git a/ruby/lib/jam_ruby/models/music_session_comment.rb b/ruby/lib/jam_ruby/models/music_session_comment.rb
new file mode 100644
index 000000000..cda5589bd
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/music_session_comment.rb
@@ -0,0 +1,12 @@
+module JamRuby
+ class MusicSessionComment < ActiveRecord::Base
+
+ self.table_name = "music_sessions_comments"
+
+ self.primary_key = 'id'
+
+ belongs_to :music_session, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "music_session_id"
+ belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "creator_id"
+
+ end
+end
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/models/music_session_history.rb b/ruby/lib/jam_ruby/models/music_session_history.rb
index f87154c31..1a6fd8418 100644
--- a/ruby/lib/jam_ruby/models/music_session_history.rb
+++ b/ruby/lib/jam_ruby/models/music_session_history.rb
@@ -15,8 +15,19 @@ module JamRuby
:foreign_key => :band_id,
:inverse_of => :music_session_history)
+ has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
+ has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "music_session_id"
+
GENRE_SEPARATOR = '|'
+ def comment_count
+ self.comments.size
+ end
+
+ def like_count
+ self.likes.size
+ end
+
def self.index(current_user, user_id, band_id = nil, genre = nil)
hide_private = false
if current_user.id != user_id
diff --git a/ruby/lib/jam_ruby/models/music_session_liker.rb b/ruby/lib/jam_ruby/models/music_session_liker.rb
new file mode 100644
index 000000000..a7d89fc72
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/music_session_liker.rb
@@ -0,0 +1,12 @@
+module JamRuby
+ class MusicSessionLiker < ActiveRecord::Base
+
+ self.table_name = "music_sessions_likers"
+
+ self.primary_key = 'id'
+
+ belongs_to :music_session, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "music_session_id"
+ belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "liker_id"
+
+ end
+end
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/models/recorded_track.rb b/ruby/lib/jam_ruby/models/recorded_track.rb
index 90731961a..b67ec410d 100644
--- a/ruby/lib/jam_ruby/models/recorded_track.rb
+++ b/ruby/lib/jam_ruby/models/recorded_track.rb
@@ -86,13 +86,13 @@ module JamRuby
recorded_track.next_part_to_upload = 0
recorded_track.file_offset = 0
recorded_track.save
- recorded_track.url = construct_filename(recording.id, track.client_track_id)
+ recorded_track.url = construct_filename(recorded_track.created_at, recording.id, track.client_track_id)
recorded_track.save
recorded_track
end
def sign_url(expiration_time = 120)
- s3_manager.sign_url(url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
+ s3_manager.sign_url(self.url, {:expires => expiration_time, :response_content_type => 'audio/ogg', :secure => false})
end
def upload_start(length, md5)
@@ -128,7 +128,7 @@ module JamRuby
end
def upload_sign(content_md5)
- s3_manager.upload_sign(filename, content_md5, next_part_to_upload, upload_id)
+ s3_manager.upload_sign(url, content_md5, next_part_to_upload, upload_id)
end
def upload_part_complete(part, offset)
@@ -154,17 +154,17 @@ module JamRuby
private
def delete_s3_files
- s3_manager.delete(filename)
+ s3_manager.delete(url)
end
def filename
# construct a path for s3
- RecordedTrack.construct_filename(self.recording.id, self.client_track_id)
+ RecordedTrack.construct_filename(self.created_at, self.recording.id, self.client_track_id)
end
- def self.construct_filename(recording_id, client_track_id)
+ def self.construct_filename(created_at, recording_id, client_track_id)
raise "unknown ID" unless client_track_id
- "recordings/#{recording_id}/track-#{client_track_id}.ogg"
+ "recordings/#{created_at.strftime('%m-%d-%Y')}/#{recording_id}/track-#{client_track_id}.ogg"
end
end
end
diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb
index d17861c16..dfc0b2195 100644
--- a/ruby/lib/jam_ruby/models/recording.rb
+++ b/ruby/lib/jam_ruby/models/recording.rb
@@ -7,17 +7,34 @@ module JamRuby
has_many :claimed_recordings, :class_name => "JamRuby::ClaimedRecording", :inverse_of => :recording
has_many :users, :through => :recorded_tracks, :class_name => "JamRuby::User"
+ has_many :mixes, :class_name => "JamRuby::Mix", :inverse_of => :recording
+ has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id
+ has_many :comments, :class_name => "JamRuby::RecordingComment", :foreign_key => "recording_id"
+ has_many :likes, :class_name => "JamRuby::RecordingLiker", :foreign_key => "recording_id"
+ has_many :plays, :class_name => "JamRuby::RecordingPlay", :foreign_key => "recording_id"
+
belongs_to :owner, :class_name => "JamRuby::User", :inverse_of => :owned_recordings
belongs_to :band, :class_name => "JamRuby::Band", :inverse_of => :recordings
belongs_to :music_session, :class_name => "JamRuby::MusicSession", :inverse_of => :recordings
- has_many :mixes, :class_name => "JamRuby::Mix", :inverse_of => :recording
- has_many :recorded_tracks, :class_name => "JamRuby::RecordedTrack", :foreign_key => :recording_id
+
validates :music_session, :presence => true
validate :not_already_recording, :on => :create
validate :not_still_finalizing_previous, :on => :create
validate :not_playback_recording, :on => :create
validate :already_stopped_recording
+ def comment_count
+ self.comments.size
+ end
+
+ def like_count
+ self.likes.size
+ end
+
+ def play_count
+ self.plays.size
+ end
+
def not_already_recording
if music_session.is_recording?
errors.add(:music_session, ValidationMessages::ALREADY_BEING_RECORDED)
@@ -193,7 +210,7 @@ module JamRuby
downloads.push(
{
:type => "mix",
- :id => mix.id,
+ :id => mix.id.to_s,
:recording_id => mix.recording_id,
:length => mix.length,
:md5 => mix.md5,
@@ -268,7 +285,7 @@ module JamRuby
return unless recorded_track.fully_uploaded
end
- self.mixes << Mix.schedule(self, base_mix_manifest)
+ self.mixes << Mix.schedule(self)
save
end
@@ -293,21 +310,6 @@ module JamRuby
end
=end
- def base_mix_manifest
- manifest = { "files" => [], "timeline" => [] }
- mix_params = []
- recorded_tracks.each do |recorded_track|
- return nil unless recorded_track.fully_uploaded
- manifest["files"] << { "filename" => recorded_track.sign_url(60 * 60 * 24), "codec" => "vorbis", "offset" => 0 }
- mix_params << { "level" => 100, "balance" => 0 }
- end
-
- manifest["timeline"] << { "timestamp" => 0, "mix" => mix_params }
- manifest["output"] = { "codec" => "vorbis" }
- manifest["recording_id"] = self.id
- manifest
- end
-
private
def self.validate_user_is_band_member(user, band)
unless band.users.exists? user
diff --git a/ruby/lib/jam_ruby/models/recording_comment.rb b/ruby/lib/jam_ruby/models/recording_comment.rb
new file mode 100644
index 000000000..8b7e5ae62
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/recording_comment.rb
@@ -0,0 +1,12 @@
+module JamRuby
+ class RecordingComment < ActiveRecord::Base
+
+ self.table_name = "recordings_comments"
+
+ self.primary_key = 'id'
+
+ belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id"
+ belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "creator_id"
+
+ end
+end
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/models/recording_liker.rb b/ruby/lib/jam_ruby/models/recording_liker.rb
new file mode 100644
index 000000000..041465d2b
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/recording_liker.rb
@@ -0,0 +1,12 @@
+module JamRuby
+ class RecordingLiker < ActiveRecord::Base
+
+ self.table_name = "recordings_likers"
+
+ self.primary_key = 'id'
+
+ belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id"
+ belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "liker_id"
+
+ end
+end
\ No newline at end of file
diff --git a/ruby/lib/jam_ruby/models/recording_play.rb b/ruby/lib/jam_ruby/models/recording_play.rb
new file mode 100644
index 000000000..e2e24e55f
--- /dev/null
+++ b/ruby/lib/jam_ruby/models/recording_play.rb
@@ -0,0 +1,12 @@
+module JamRuby
+ class RecordingPlay < ActiveRecord::Base
+
+ self.table_name = "recordings_plays"
+
+ self.primary_key = 'id'
+
+ belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id"
+ belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "player_id"
+
+ end
+end
diff --git a/ruby/lib/jam_ruby/resque/audiomixer.rb b/ruby/lib/jam_ruby/resque/audiomixer.rb
index a8fedade0..5aab4abc7 100644
--- a/ruby/lib/jam_ruby/resque/audiomixer.rb
+++ b/ruby/lib/jam_ruby/resque/audiomixer.rb
@@ -6,12 +6,11 @@ require 'digest/md5'
module JamRuby
+ # executes a mix of tracks, creating a final output mix
class AudioMixer
@queue = :audiomixer
- #extend Resque::Plugins::Retry
-
@@log = Logging.logger[AudioMixer]
attr_accessor :mix_id, :manifest, :manifest_file, :output_filename, :error_out_filename, :postback_output_url,
@@ -49,6 +48,7 @@ module JamRuby
raise "no timeline specified" unless @manifest[:timeline]
raise "no recording_id specified" unless @manifest[:recording_id]
raise "no mix_id specified" unless @manifest[:mix_id]
+
end
@@ -79,9 +79,9 @@ module JamRuby
@error_detail = "url #{filename}, error=#{e}"
raise e
end
-
end
+ @@log.debug("downloaded #{download_filename}")
filename = download_filename
file[:filename] = download_filename
end
@@ -103,7 +103,7 @@ module JamRuby
# write the manifest object to file, to pass into audiomixer
def prepare_manifest
- @manifest_file = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-manifest-#{@manifest['recording_id']}", '.json'], nil)
+ @manifest_file = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-manifest-#{@manifest[:recording_id]}", '.json'], nil)
File.open(@manifest_file,"w") do |f|
f.write(@manifest.to_json)
end
@@ -113,7 +113,7 @@ module JamRuby
# make a suitable location to store the output mix, and pass the chosen filepath into the manifest
def prepare_output
- @output_filename = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-output-#{@manifest['recording_id']}", '.ogg'], nil)
+ @output_filename = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-output-#{@manifest[:recording_id]}", '.ogg'], nil)
# update manifest so that audiomixer writes here
@manifest[:output][:filename] = @output_filename
@@ -123,7 +123,7 @@ module JamRuby
# make a suitable location to store an output error file, which will be populated on failure to help diagnose problems.
def prepare_error_out
- @error_out_filename = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-error-out-#{@manifest['recording_id']}", '.ogg'], nil)
+ @error_out_filename = Dir::Tmpname.make_tmpname( ["#{Dir.tmpdir}/audiomixer-error-out-#{@manifest[:recording_id]}", '.ogg'], nil)
# update manifest so that audiomixer writes here
@manifest[:error_out] = @error_out_filename
@@ -203,7 +203,13 @@ module JamRuby
mix = Mix.find(mix_id)
begin
- @manifest = symbolize_keys(JSON.parse(mix.manifest))
+ # bailout check
+ if mix.completed
+ @@log.debug("mix is already completed. bailing")
+ return
+ end
+
+ @manifest = symbolize_keys(mix.manifest)
@manifest[:mix_id] = mix_id # slip in the mix_id so that the job can add it to the ogg comments
# sanity check the manifest
@@ -215,25 +221,16 @@ module JamRuby
# write the manifest to file, so that it can be passed to audiomixer as an filepath argument
prepare
- result = execute(@manifest_file)
+ execute(@manifest_file)
- if result
- if $? == 0
- postback
- post_success(mix)
- @@log.info("audiomixer job successful. mix_id #{mix_id}")
- else
- parse_error_out
- error_msg = "audiomixer job failed status=#{$?} error_reason=#{error_reason} error_detail=#{error_detail}"
- @@log.info(error_msg)
- raise error_msg
- end
+ if $? == 0
+ postback
+ post_success(mix)
+ @@log.info("audiomixer job successful. mix_id #{mix_id}")
else
- @@log.error("unable to find audiomixer")
+ parse_error_out
error_msg = "audiomixer job failed status=#{$?} error_reason=#{error_reason} error_detail=#{error_detail}"
@@log.info(error_msg)
- @error_reason = "unable-find-appmixer"
- @error_detail = APP_CONFIG.audiomixer_path
raise error_msg
end
rescue Exception => e
@@ -250,8 +247,20 @@ module JamRuby
private
def execute(manifest_file)
+
+ unless File.exist? APP_CONFIG.audiomixer_path
+ @@log.error("unable to find audiomixer")
+ error_msg = "audiomixer job failed status=#{$?} error_reason=#{error_reason} error_detail=#{error_detail}"
+ @@log.info(error_msg)
+ @error_reason = "unable-find-appmixer"
+ @error_detail = APP_CONFIG.audiomixer_path
+ raise error_msg
+ end
+
+
audiomixer_cmd = "#{APP_CONFIG.audiomixer_path} #{manifest_file}"
+
@@log.debug("executing #{audiomixer_cmd}")
system(audiomixer_cmd)
diff --git a/ruby/lib/jam_ruby/resque/scheduled/audiomixer_retry.rb b/ruby/lib/jam_ruby/resque/scheduled/audiomixer_retry.rb
new file mode 100644
index 000000000..855bdd747
--- /dev/null
+++ b/ruby/lib/jam_ruby/resque/scheduled/audiomixer_retry.rb
@@ -0,0 +1,22 @@
+require 'json'
+require 'resque'
+require 'resque-retry'
+require 'net/http'
+require 'digest/md5'
+
+module JamRuby
+
+ # periodically scheduled to find jobs that need retrying
+ class AudioMixerRetry
+
+ @queue = :audiomixer_retry
+
+ @@log = Logging.logger[AudioMixerRetry]
+
+ def self.perform
+ Mix.queue_jobs_needing_retry
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/ruby/spec/jam_ruby/models/icecast_limit_spec.rb b/ruby/spec/jam_ruby/models/icecast_limit_spec.rb
index 98ed30ab1..98e316145 100644
--- a/ruby/spec/jam_ruby/models/icecast_limit_spec.rb
+++ b/ruby/spec/jam_ruby/models/icecast_limit_spec.rb
@@ -11,11 +11,9 @@ describe IcecastLimit do
it "save" do
limit.clients = 9999
limit.save
- puts limit.inspect
- limit.dumpXml
+ #limit.dumpXml
limit.errors.any?.should be_false
v = IcecastLimit.find(limit.id)
- puts v.inspect
end
diff --git a/ruby/spec/jam_ruby/models/mix_spec.rb b/ruby/spec/jam_ruby/models/mix_spec.rb
index 4e436115d..bb361bc99 100755
--- a/ruby/spec/jam_ruby/models/mix_spec.rb
+++ b/ruby/spec/jam_ruby/models/mix_spec.rb
@@ -14,27 +14,17 @@ describe Mix do
@recording.stop
@recording.claim(@user, "name", "description", Genre.first, true, true)
@recording.errors.any?.should be_false
- @mix = Mix.schedule(@recording, {})
+ @mix = Mix.schedule(@recording)
@mix.reload
end
it "should create a mix for a user's recording properly" do
@mix.recording_id.should == @recording.id
- @mix.manifest.should == {}.to_json
@mix.mix_server.should be_nil
- @mix.started_at.should be_nil
+ @mix.started_at.should_not be_nil
@mix.completed_at.should be_nil
end
- it "should fail to create a mix if the userid doesn't own the recording" do
- @user2 = FactoryGirl.create(:user)
- expect { Mix.schedule(@recording) }.to raise_error
- end
-
- it "should fail if the recording doesn't exist" do
- expect { @mix2 = Mix.schedule(Recording.find('lskdjflsd')) }.to raise_error
- end
-
it "should record when a mix has finished" do
Mix.find(@mix.id).finish(10000, "md5hash")
@mix.reload
@@ -59,7 +49,7 @@ describe Mix do
recordings = Recording.list_downloads(@user)["downloads"]
recordings.length.should == 1
recordings[0][:type].should == "mix"
- recordings[0][:id].should == @mix.id
+ recordings[0][:id].should == @mix.id.to_s
recordings = Recording.list_downloads(@user2)["downloads"]
recordings.length.should == 0
diff --git a/ruby/spec/jam_ruby/models/recorded_track_spec.rb b/ruby/spec/jam_ruby/models/recorded_track_spec.rb
index ed2b74701..c8e3b2c8a 100644
--- a/ruby/spec/jam_ruby/models/recorded_track_spec.rb
+++ b/ruby/spec/jam_ruby/models/recorded_track_spec.rb
@@ -42,7 +42,7 @@ describe RecordedTrack do
it "gets a url for the track" do
@recorded_track = RecordedTrack.create_from_track(@track, @recording)
@recorded_track.save.should be_true
- @recorded_track.url.should == "recordings/#{@recording.id}/track-#{@track.client_track_id}.ogg"
+ @recorded_track.url.should == "recordings/#{@recorded_track.created_at.strftime('%m-%d-%Y')}/#{@recording.id}/track-#{@track.client_track_id}.ogg"
end
it "signs url" do
diff --git a/ruby/spec/jam_ruby/resque/audiomixer_spec.rb b/ruby/spec/jam_ruby/resque/audiomixer_spec.rb
index c74f18dc3..8d62c373d 100644
--- a/ruby/spec/jam_ruby/resque/audiomixer_spec.rb
+++ b/ruby/spec/jam_ruby/resque/audiomixer_spec.rb
@@ -175,13 +175,15 @@ describe AudioMixer do
AudioMixer.any_instance.stub(:postback) # don't actually post resulting off file up
end
-
describe "perform" do
# this case does not talk to redis, does not run the real audiomixer, and does not actually talk with s3
# but it does talk to the database and verifies all the other logic
it "success" do
- @mix = Mix.schedule(@recording, local_files_manifest)
+ Mix.any_instance.stub(:manifest).and_return(local_files_manifest) # don't actually post resulting off file up
+ @mix = Mix.schedule(@recording)
+ @mix.reload
+ @mix.started_at.should_not be_nil
AudioMixer.perform(@mix.id, @mix.sign_url(60 * 60 * 24))
@mix.reload
@mix.completed.should be_true
@@ -191,7 +193,8 @@ describe AudioMixer do
it "errored" do
local_files_manifest[:files][0][:filename] = '/some/path/to/nowhere'
- @mix = Mix.schedule(@recording, local_files_manifest)
+ Mix.any_instance.stub(:manifest).and_return(local_files_manifest)
+ @mix = Mix.schedule(@recording)
expect{ AudioMixer.perform(@mix.id, @mix.sign_url(60 * 60 * 24)) }.to raise_error
@mix.reload
@mix.completed.should be_false
@@ -208,13 +211,15 @@ describe AudioMixer do
end
it "should have been enqueued because mix got scheduled" do
- @mix = Mix.schedule(@recording, local_files_manifest)
+ Mix.any_instance.stub(:manifest).and_return(local_files_manifest)
+ @mix = Mix.schedule(@recording)
AudioMixer.should have_queue_size_of(1)
end
it "should actually run the job" do
with_resque do
- @mix = Mix.schedule(@recording, local_files_manifest)
+ Mix.any_instance.stub(:manifest).and_return(local_files_manifest)
+ @mix = Mix.schedule(@recording)
end
@mix.reload
@@ -222,6 +227,23 @@ describe AudioMixer do
@mix.length.should == 0
@mix.md5.should == 'd41d8cd98f00b204e9800998ecf8427e' # that's the md5 of a touched file, which is what the stubbed :execute does
end
+
+ it "bails out with no error if already completed" do
+ with_resque do
+ Mix.any_instance.stub(:manifest).and_return(local_files_manifest)
+ @mix = Mix.schedule(@recording)
+ end
+
+ @mix.reload
+ @mix.completed.should be_true
+
+ with_resque do
+ @mix.enqueue
+ end
+
+ @mix.reload
+ @mix.completed.should be_true
+ end
end
end
@@ -258,7 +280,8 @@ describe AudioMixer do
it "completes" do
with_resque do
- @mix = Mix.schedule(@recording, s3_manifest)
+ Mix.any_instance.stub(:manifest).and_return(s3_manifest)
+ @mix = Mix.schedule(@recording)
end
@mix.reload
@@ -270,7 +293,8 @@ describe AudioMixer do
it "fails" do
with_resque do
s3_manifest[:files][0][:filename] = @s3_manager.url('audiomixer/bogus.ogg', :secure => false) # take off some of the trailing chars of the url
- expect{ Mix.schedule(@recording, s3_manifest) }.to raise_error
+ Mix.any_instance.stub(:manifest).and_return(s3_manifest)
+ expect{ Mix.schedule(@recording) }.to raise_error
end
@mix = Mix.order('id desc').limit(1).first()
diff --git a/web/Gemfile b/web/Gemfile
index f57f9b144..149bbd86e 100644
--- a/web/Gemfile
+++ b/web/Gemfile
@@ -90,12 +90,12 @@ end
group :test, :cucumber do
gem 'capybara'
-if ENV['JAMWEB_QT5'] == '1'
- # necessary on platforms such as arch linux, where pacman -S qt5-webkit is your easiet option
- gem "capybara-webkit", :git => 'git://github.com/thoughtbot/capybara-webkit.git'
-else
+#if ENV['JAMWEB_QT5'] == '1'
+# # necessary on platforms such as arch linux, where pacman -S qt5-webkit is your easiet option
+# gem "capybara-webkit", :git => 'git://github.com/thoughtbot/capybara-webkit.git'
+#else
gem "capybara-webkit"
-end
+#end
gem 'capybara-screenshot'
gem 'cucumber-rails', :require => false #, '1.3.0', :require => false
gem 'guard-spork', '0.3.2'
diff --git a/web/app/controllers/api_mixes_controller.rb b/web/app/controllers/api_mixes_controller.rb
index a04687fb0..60944c480 100644
--- a/web/app/controllers/api_mixes_controller.rb
+++ b/web/app/controllers/api_mixes_controller.rb
@@ -10,14 +10,6 @@ class ApiMixesController < ApiController
respond_to :json
- def schedule
- begin
- Mix.schedule(params[:recording_id], current_user, params[:description], params[:manifest])
- respond_with responder: ApiResponder, :status => 204
- rescue
- render :json => { :message => "mix could not be scheduled" }, :status => 403
- end
- end
def next
begin
@@ -39,7 +31,9 @@ class ApiMixesController < ApiController
end
def download
- # XXX: needs to permission check
+ @mix = Mix.find(params[:id])
+ raise PermissionError, "You can only download a mix you didn't claim" unless @mix.can_download? current_user
+
redirect_to @mix.sign_url
end
diff --git a/web/app/controllers/api_music_sessions_controller.rb b/web/app/controllers/api_music_sessions_controller.rb
index ab93d3c29..79b8cfe84 100644
--- a/web/app/controllers/api_music_sessions_controller.rb
+++ b/web/app/controllers/api_music_sessions_controller.rb
@@ -234,6 +234,52 @@ class ApiMusicSessionsController < ApiController
end
end
+ def add_comment
+ if params[:id].blank?
+ render :json => { :message => "Session ID is required" }, :status => 400
+ end
+
+ if params[:user_id].blank?
+ render :json => { :message => "User ID is required" }, :status => 400
+ end
+
+ if params[:comment].blank?
+ render :json => { :message => "Comment is required" }, :status => 400
+ end
+
+ comment = MusicSessionComment.new
+ comment.music_session_id = params[:id]
+ comment.creator_id = params[:user_id]
+ comment.comment = params[:comment]
+ comment.save
+
+ if comment.errors.any?
+ render :json => { :message => "Unexpected error occurred" }, :status => 500
+ else
+ render :json => {}, :status => 201
+ end
+ end
+
+ def add_like
+ if params[:id].blank?
+ render :json => { :message => "Session ID is required" }, :status => 400
+ end
+
+ if params[:user_id].blank?
+ render :json => { :message => "User ID is required" }, :status => 400
+ end
+
+ liker = MusicSessionLiker.new
+ liker.music_session_id = params[:id]
+ liker.liker_id = params[:user_id]
+ liker.save
+
+ if liker.errors.any?
+ render :json => { :message => "Unexpected error occurred" }, :status => 500
+ else
+ render :json => {}, :status => 201
+ end
+ end
def claimed_recording_start
@music_session.claimed_recording_start(current_user, ClaimedRecording.find(params[:claimed_recording_id]))
diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb
index d87f1f9c3..3a8986fb2 100644
--- a/web/app/controllers/api_recordings_controller.rb
+++ b/web/app/controllers/api_recordings_controller.rb
@@ -80,6 +80,74 @@ class ApiRecordingsController < ApiController
end
end
+ def add_comment
+ if params[:id].blank?
+ render :json => { :message => "Recording ID is required" }, :status => 400
+ end
+
+ if params[:user_id].blank?
+ render :json => { :message => "User ID is required" }, :status => 400
+ end
+
+ if params[:comment].blank?
+ render :json => { :message => "Comment is required" }, :status => 400
+ end
+
+ comment = RecordingComment.new
+ comment.recording_id = params[:id]
+ comment.creator_id = params[:user_id]
+ comment.comment = params[:comment]
+ comment.save
+
+ if comment.errors.any?
+ render :json => { :message => "Unexpected error occurred" }, :status => 500
+ else
+ render :json => {}, :status => 201
+ end
+ end
+
+ def add_like
+ if params[:id].blank?
+ render :json => { :message => "Recording ID is required" }, :status => 400
+ end
+
+ if params[:user_id].blank?
+ render :json => { :message => "User ID is required" }, :status => 400
+ end
+
+ liker = RecordingLiker.new
+ liker.recording_id = params[:id]
+ liker.liker_id = params[:user_id]
+ liker.save
+
+ if liker.errors.any?
+ render :json => { :message => "Unexpected error occurred" }, :status => 500
+ else
+ render :json => {}, :status => 201
+ end
+ end
+
+ def add_play
+ if params[:id].blank?
+ render :json => { :message => "Recording ID is required" }, :status => 400
+ end
+
+ if params[:user_id].blank?
+ render :json => { :message => "User ID is required" }, :status => 400
+ end
+
+ play = RecordingPlay.new
+ play.recording_id = params[:id]
+ play.player_id = params[:user_id]
+ play.save
+
+ if play.errors.any?
+ render :json => { :message => "Unexpected error occurred" }, :status => 500
+ else
+ render :json => {}, :status => 201
+ end
+ end
+
# discard will tell the server the user has no interest in the recording
def discard
@recording.discard(current_user)
diff --git a/web/app/views/api_recordings/show.rabl b/web/app/views/api_recordings/show.rabl
index 9fd83dfcf..0ece6725a 100644
--- a/web/app/views/api_recordings/show.rabl
+++ b/web/app/views/api_recordings/show.rabl
@@ -1,6 +1,6 @@
object @recording
-attributes :id, :band, :created_at, :duration
+attributes :id, :band, :created_at, :duration, :comment_count, :like_count, :play_count
child(:recorded_tracks => :recorded_tracks) {
attributes :id, :fully_uploaded, :url, :client_track_id, :client_id, :instrument_id
diff --git a/web/config/god/audiowatcher.rb b/web/config/god/queued_jobs.rb
similarity index 72%
rename from web/config/god/audiowatcher.rb
rename to web/config/god/queued_jobs.rb
index f4f12fa61..e2aa8b733 100644
--- a/web/config/god/audiowatcher.rb
+++ b/web/config/god/queued_jobs.rb
@@ -1,6 +1,9 @@
-rails_env = ENV['RAILS_ENV'] || "production"
-rails_root = ENV['RAILS_ROOT'] || "/data/github/current"
-num_workers = rails_env == 'production' ? 5 : 2
+# this probably needs to be removed from jam-web source, and moved only to chef
+
+rails_root = ENV['RAILS_ROOT'] || '.'
+rails_env = ENV['RAILS_ENV'] || "development"
+num_workers = ENV['NUM_WORKERS'] || 2
+queues = ENV['QUEUE'] || '*'
num_workers.times do |num|
God.watch do |w|
@@ -8,11 +11,11 @@ num_workers.times do |num|
w.name = "resque-#{num}"
w.group = 'resque'
w.interval = 30.seconds
- w.env = {"QUEUE"=>"critical,high,low", "RAILS_ENV"=>rails_env}
- w.start = "/usr/bin/rake -f #{rails_root}/Rakefile environment resque:work"
+ w.env = {"QUEUE"=>queues, "RAILS_ENV"=>rails_env}
+ w.start = "/usr/local/bin/bundle exec rake environment resque:work"
- w.uid = 'git'
- w.gid = 'git'
+ #w.uid = 'jam-resque'
+ #w.gid = 'jam-resque'
# restart if memory gets too high
w.transition(:up, :restart) do |on|
diff --git a/web/config/initializers/eventmachine.rb b/web/config/initializers/eventmachine.rb
index 3a194ee35..f09eb1811 100644
--- a/web/config/initializers/eventmachine.rb
+++ b/web/config/initializers/eventmachine.rb
@@ -35,7 +35,7 @@ module JamWebEventMachine
end
end
- if Rails.application.config.websocket_gateway_enable
+ if Rails.application.config.websocket_gateway_enable && !$rails_rake_task
Thread.new { JamWebsockets::Server.new.run :port => Rails.application.config.websocket_gateway_port,
:emwebsocket_debug => Rails.application.config.websocket_gateway_internal_debug,
@@ -82,4 +82,4 @@ module JamWebEventMachine
end
end
-JamWebEventMachine.start unless $rails_rake_task
+JamWebEventMachine.start
diff --git a/web/config/routes.rb b/web/config/routes.rb
index fb2e6941f..990ca7426 100644
--- a/web/config/routes.rb
+++ b/web/config/routes.rb
@@ -89,7 +89,9 @@ SampleApp::Application.routes.draw do
match '/sessions' => 'api_music_sessions#index', :via => :get
match '/sessions' => 'api_music_sessions#create', :via => :post
match '/sessions/:id/perf' => 'api_music_sessions#perf_upload', :via => :put
-
+ match '/sessions/:id/comments' => 'api_music_sessions#add_comment', :via => :post
+ match '/sessions/:id/likes' => 'api_music_sessions#add_like', :via => :post
+
# music session tracks
match '/sessions/:id/tracks' => 'api_music_sessions#track_create', :via => :post
match '/sessions/:id/tracks' => 'api_music_sessions#track_sync', :via => :put
@@ -278,6 +280,9 @@ 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/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/plays' => 'api_recordings#add_play', :via => :post, :as => 'api_recordings_add_play'
match '/recordings/:id/discard' => 'api_recordings#discard', :via => :post, :as => 'api_recordings_discard'
match '/recordings/:id/tracks/:track_id/download' => 'api_recordings#download', :via => :get, :as => 'api_recordings_download'
match '/recordings/:id/tracks/:track_id/upload_next_part' => 'api_recordings#upload_next_part', :via => :get
@@ -291,8 +296,6 @@ SampleApp::Application.routes.draw do
match '/claimed_recordings/:id' => 'api_claimed_recordings#update', :via => :put
match '/claimed_recordings/:id' => 'api_claimed_recordings#delete', :via => :delete
- # Mixes
- match '/mixes/schedule' => 'api_mixes#schedule', :via => :post
match '/mixes/next' => 'api_mixes#next', :via => :get
match '/mixes/:id/finish' => 'api_mixes#finish', :via => :put
match '/mixes/:id/download' => 'api_mixes#download', :via => :get
diff --git a/web/config/scheduler.yml b/web/config/scheduler.yml
new file mode 100644
index 000000000..815996110
--- /dev/null
+++ b/web/config/scheduler.yml
@@ -0,0 +1,5 @@
+# add job scheduler classes here
+AudioMixerRetry:
+ cron: 0 * * * *
+ class: "JamRuby::AudioMixerRetry"
+ description: "Retries mixes that set the should_retry flag or never started"
\ No newline at end of file
diff --git a/web/lib/tasks/scheduler.rake b/web/lib/tasks/scheduler.rake
new file mode 100644
index 000000000..55e00cfdf
--- /dev/null
+++ b/web/lib/tasks/scheduler.rake
@@ -0,0 +1,29 @@
+# Resque tasks
+require 'resque/tasks'
+require 'resque_scheduler/tasks'
+require 'resque'
+require 'resque_scheduler'
+
+task :scheduler => :environment do
+
+ # If you want to be able to dynamically change the schedule,
+ # uncomment this line. A dynamic schedule can be updated via the
+ # Resque::Scheduler.set_schedule (and remove_schedule) methods.
+ # When dynamic is set to true, the scheduler process looks for
+ # schedule changes and applies them on the fly.
+ # Note: This feature is only available in >=2.0.0.
+ #Resque::Scheduler.dynamic = true
+
+ # The schedule doesn't need to be stored in a YAML, it just needs to
+ # be a hash. YAML is usually the easiest.
+ Resque.schedule = YAML.load_file(File.join(File.dirname(__FILE__), '../..', 'config/scheduler.yml'))
+
+ # If your schedule already has +queue+ set for each job, you don't
+ # need to require your jobs. This can be an advantage since it's
+ # less code that resque-scheduler needs to know about. But in a small
+ # project, it's usually easier to just include you job classes here.
+ # So, something like this:
+ #require 'jobs'
+
+ Rake::Task['resque:scheduler'].invoke
+end
diff --git a/web/lib/tasks/start.rake b/web/lib/tasks/start.rake
index 64e2b0285..69fc66ce2 100644
--- a/web/lib/tasks/start.rake
+++ b/web/lib/tasks/start.rake
@@ -2,10 +2,6 @@
# bundle exec rake audiomixer
task :audiomixer do
-
-
- Rails.application.config.websocket_gateway_enable = false # prevent websocket gateway from starting
-
Rake::Task['environment'].invoke
ENV['QUEUE'] = 'audiomixer'
diff --git a/web/script/package/audiomixer-worker-upstart-run.sh b/web/script/package/audiomixer-worker-upstart-run.sh
deleted file mode 100755
index 5bdc1dd11..000000000
--- a/web/script/package/audiomixer-worker-upstart-run.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash -l
-
-# default config values
-PORT=3000
-BUILD_NUMBER=`cat /var/lib/jam-web/BUILD_NUMBER`
-
-
-CONFIG_FILE="/etc/jam-web/audiomixer-worker-upstart.conf"
-if [ -e "$CONFIG_FILE" ]; then
- . "$CONFIG_FILE"
-fi
-
-# I don't like doing this, but the next command (bundle exec) retouches/generates
-# the gemfile. This unfortunately means the next debian update doesn't update this file.
-# Ultimately this means an old Gemfile.lock is left behind for a new package,
-# and bundle won't run because it thinks it has the wrong versions of gems
-rm -f Gemfile.lock
-
-RAILS_ENV=production BUILD_NUMBER=$BUILD_NUMBER QUEUE=audiomixer exec bundle exec rake environment resque:work
diff --git a/web/script/package/audiomixer-worker.conf b/web/script/package/audiomixer-worker.conf
deleted file mode 100755
index 82617f234..000000000
--- a/web/script/package/audiomixer-worker.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-description "audiomixer-worker"
-
-start on startup
-start on runlevel [2345]
-stop on runlevel [016]
-
-exec start-stop-daemon --start --chdir /var/lib/jam-web --exec /var/lib/jam-web/script/package/audiomixer-worker-upstart-run.sh
diff --git a/web/script/package/post-install.sh b/web/script/package/post-install.sh
index 367b48f80..6eb848202 100755
--- a/web/script/package/post-install.sh
+++ b/web/script/package/post-install.sh
@@ -17,42 +17,4 @@ mkdir -p /var/log/$NAME
chown -R $USER:$GROUP /var/lib/$NAME
chown -R $USER:$GROUP /etc/$NAME
-chown -R $USER:$GROUP /var/log/$NAME
-
-
-# do the same for audiomixer-worker
-NAME="audiomxer-worker"
-
-USER="$NAME"
-GROUP="$NAME"
-
-# copy upstart file
-cp /var/lib/$NAME/script/package/$NAME.conf /etc/init/$NAME.conf
-
-mkdir -p /var/lib/$NAME/log
-mkdir -p /var/lib/$NAME/tmp
-mkdir -p /etc/$NAME
-mkdir -p /var/log/$NAME
-
-chown -R $USER:$GROUP /var/lib/$NAME
-chown -R $USER:$GROUP /etc/$NAME
-chown -R $USER:$GROUP /var/log/$NAME
-
-
-# do the same for icecast-worker
-NAME="icecast-worker"
-
-USER="$NAME"
-GROUP="$NAME"
-
-# copy upstart file
-cp /var/lib/$NAME/script/package/$NAME.conf /etc/init/$NAME.conf
-
-mkdir -p /var/lib/$NAME/log
-mkdir -p /var/lib/$NAME/tmp
-mkdir -p /etc/$NAME
-mkdir -p /var/log/$NAME
-
-chown -R $USER:$GROUP /var/lib/$NAME
-chown -R $USER:$GROUP /etc/$NAME
-chown -R $USER:$GROUP /var/log/$NAME
+chown -R $USER:$GROUP /var/log/$NAME
\ No newline at end of file
diff --git a/web/script/package/post-uninstall.sh b/web/script/package/post-uninstall.sh
index 1bc060100..9d3ee0c14 100755
--- a/web/script/package/post-uninstall.sh
+++ b/web/script/package/post-uninstall.sh
@@ -24,55 +24,4 @@ then
fi
userdel $NAME
-fi
-
-
-
-NAME="audiomixer-worker"
-
-set -e
-if [ "$1" = "remove" ]
-then
- set +e
- # stop the process, if any is found. we don't want this failing to cause an error, though.
- sudo stop $NAME
- set -e
-
- if [ -f /etc/init/$NAME.conf ]; then
- rm /etc/init/$NAME.conf
- fi
-fi
-
-if [ "$1" = "purge" ]
-then
- if [ -d /var/lib/$NAME ]; then
- rm -rf /var/lib/$NAME
- fi
-
- userdel $NAME
-fi
-
-
-NAME="icecast-worker"
-
-set -e
-if [ "$1" = "remove" ]
-then
- set +e
- # stop the process, if any is found. we don't want this failing to cause an error, though.
- sudo stop $NAME
- set -e
-
- if [ -f /etc/init/$NAME.conf ]; then
- rm /etc/init/$NAME.conf
- fi
-fi
-
-if [ "$1" = "purge" ]
-then
- if [ -d /var/lib/$NAME ]; then
- rm -rf /var/lib/$NAME
- fi
-
- userdel $NAME
-fi
+fi
\ No newline at end of file
diff --git a/web/script/package/pre-install.sh b/web/script/package/pre-install.sh
index c7653dbd6..996f30251 100755
--- a/web/script/package/pre-install.sh
+++ b/web/script/package/pre-install.sh
@@ -33,81 +33,5 @@ then
"$USER" >/dev/null
fi
-# NIS no longer a possible problem; stop ignoring errors
-set -e
-
-
-
-# do the same for audiomixer-worker
-NAME="audiomixer-worker"
-
-set -eu
-
-HOME="/var/lib/$NAME"
-USER="$NAME"
-GROUP="$NAME"
-
-# if NIS is used, then errors can occur but be non-fatal
-if which ypwhich >/dev/null 2>&1 && ypwhich >/dev/null 2>&1
-then
- set +e
-fi
-
-if ! getent group "$GROUP" >/dev/null
-then
- addgroup --system "$GROUP" >/dev/null
-fi
-
-# creating user if it isn't already there
-if ! getent passwd "$USER" >/dev/null
-then
- adduser \
- --system \
- --home $HOME \
- --shell /bin/false \
- --disabled-login \
- --ingroup "$GROUP" \
- --gecos "$USER" \
- "$USER" >/dev/null
-fi
-
-# NIS no longer a possible problem; stop ignoring errors
-set -e
-
-
-
-# do the same for icecast-worker
-NAME="icecast-worker"
-
-set -eu
-
-HOME="/var/lib/$NAME"
-USER="$NAME"
-GROUP="$NAME"
-
-# if NIS is used, then errors can occur but be non-fatal
-if which ypwhich >/dev/null 2>&1 && ypwhich >/dev/null 2>&1
-then
- set +e
-fi
-
-if ! getent group "$GROUP" >/dev/null
-then
- addgroup --system "$GROUP" >/dev/null
-fi
-
-# creating user if it isn't already there
-if ! getent passwd "$USER" >/dev/null
-then
- adduser \
- --system \
- --home $HOME \
- --shell /bin/false \
- --disabled-login \
- --ingroup "$GROUP" \
- --gecos "$USER" \
- "$USER" >/dev/null
-fi
-
# NIS no longer a possible problem; stop ignoring errors
set -e
\ No newline at end of file
diff --git a/web/spec/features/recordings_spec.rb b/web/spec/features/recordings_spec.rb
index 44c56716c..bbc2313ad 100644
--- a/web/spec/features/recordings_spec.rb
+++ b/web/spec/features/recordings_spec.rb
@@ -145,6 +145,7 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
end
it "claim recording with unique names/descriptions" do
+ pending "intermittent failure on build server, hard to repro on local system"
@users.each do |user|
name = "#{user.name}'s recording"
desc = "#{user.name}'s description"
@@ -177,6 +178,7 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
end
it "a 'Description' is optional" do
+ pending "intermittent failure on build server, hard to repro on local system"
@users.each do |user|
in_client(user) do
claim_recording("my recording", '')
diff --git a/websocket-gateway/Gemfile b/websocket-gateway/Gemfile
index defa2169a..d2c796ec3 100644
--- a/websocket-gateway/Gemfile
+++ b/websocket-gateway/Gemfile
@@ -24,6 +24,7 @@ gem 'ruby-protocol-buffers', '1.2.2'
gem 'em-websocket', '>=0.4.0' #, :path=> "#{workspace}/em-websocket-jam"
gem 'amqp'
gem 'activerecord', '3.2.13'
+gem 'actionpack', '3.2.13'
gem 'logging'
gem 'will_paginate'
gem 'actionmailer'
diff --git a/websocket-gateway/lib/jam_websockets/version.rb b/websocket-gateway/lib/jam_websockets/version.rb
index 67a2193ef..1a8dee8f5 100644
--- a/websocket-gateway/lib/jam_websockets/version.rb
+++ b/websocket-gateway/lib/jam_websockets/version.rb
@@ -1,3 +1,3 @@
module JamWebsockets
- VERSION = "0.0.1"
+ VERSION = "0.1.1"
end