Merge branch 'develop' into vrfs988
This commit is contained in:
commit
e539157d76
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -6,6 +6,14 @@ ActiveAdmin.register JamRuby::Mix, :as => 'Mixes' do
|
|||
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
|
||||
|
|
@ -25,7 +33,11 @@ ActiveAdmin.register JamRuby::Mix, :as => 'Mixes' do
|
|||
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 :what do |mix| link_to "Your Mom", '/' 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
|
||||
|
|
|
|||
|
|
@ -1,2 +1,11 @@
|
|||
//= require active_admin/base
|
||||
//= require autocomplete-rails
|
||||
// //= 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 .
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -12,4 +12,3 @@
|
|||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require_tree .
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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('<div>Mix enqueued</div><a href="' + gon.global.prefix + 'resque">Resque Web</a>').dialog();
|
||||
})
|
||||
.error(function(jqXHR) {
|
||||
$link.closest('div.mix-again').find('div.mix-again-dialog').html('Mix failed: ' + jqXHR.responseText).dialog();
|
||||
})
|
||||
|
||||
return false;
|
||||
})
|
||||
|
||||
});
|
||||
})(window, jQuery);
|
||||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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 .
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
.version-info {
|
||||
font-size:small;
|
||||
color:lightgray;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ cp ../pb/target/ruby/jampb/jampb-${GEM_VERSION}.gem vendor/cache/ || { echo "una
|
|||
cp ../ruby/jam_ruby-${GEM_VERSION}.gem vendor/cache/ || { echo "unable to copy jam-ruby gem"; exit 1; }
|
||||
|
||||
# put all dependencies into vendor/bundle
|
||||
rm -rf vendor/bundle
|
||||
#rm -rf vendor/bundle -- let jenkins config 'wipe workspace' decide this
|
||||
rm Gemfile.lock # if we don't want versions to float, pin it in the Gemfile, not count on Gemfile.lock
|
||||
bundle install --path vendor/bundle
|
||||
bundle update
|
||||
|
|
|
|||
|
|
@ -80,14 +80,26 @@ 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"
|
||||
|
||||
config.email_alerts_alias = 'alerts@jamkazam.com' # should be used for 'oh no' server down/service down sorts of emails
|
||||
config.email_generic_from = 'nobody@jamkazam.com'
|
||||
config.email_smtp_address = 'smtp.sendgrid.net'
|
||||
config.email_smtp_port = 587
|
||||
config.email_smtp_domain = 'www.jamkazam.com'
|
||||
config.email_smtp_authentication = :plain
|
||||
config.email_smtp_user_name = 'jamkazam'
|
||||
config.email_smtp_password = 'jamjamblueberryjam'
|
||||
config.email_smtp_starttls_auto = true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
ActionMailer::Base.raise_delivery_errors = true
|
||||
ActionMailer::Base.delivery_method = Rails.env == "test" ? :test : :smtp
|
||||
ActionMailer::Base.smtp_settings = {
|
||||
:address => "smtp.sendgrid.net",
|
||||
:port => 587,
|
||||
:domain => "www.jamkazam.com",
|
||||
:authentication => :plain,
|
||||
:user_name => "jamkazam",
|
||||
:password => "jamjamblueberryjam",
|
||||
:enable_starttls_auto => true
|
||||
:address => Rails.application.config.email_smtp_address,
|
||||
:port => Rails.application.config.email_smtp_port,
|
||||
:domain => Rails.application.config.email_smtp_domain,
|
||||
:authentication => Rails.application.config.email_smtp_authentication,
|
||||
:user_name => Rails.application.config.email_smtp_user_name,
|
||||
:password => Rails.application.config.email_smtp_password ,
|
||||
:enable_starttls_auto => Rails.application.config.email_smtp_starttls_auto
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Gon.global.prefix = ENV['RAILS_RELATIVE_URL_ROOT'] || '/'
|
||||
|
|
@ -0,0 +1 @@
|
|||
Resque.redis = Rails.application.config.redis_host
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -87,4 +87,5 @@ discardable_recorded_tracks2.sql
|
|||
icecast.sql
|
||||
home_page_promos.sql
|
||||
mix_job_watch.sql
|
||||
music_session_constraints.sql
|
||||
music_session_constraints.sql
|
||||
mixes_drop_manifest_add_retry.sql
|
||||
|
|
@ -147,11 +147,11 @@ create table icecast_relays (
|
|||
-- mount at server. eg /example.ogg
|
||||
mount VARCHAR(128) not null,
|
||||
-- eg /different.ogg
|
||||
local_mount VARCHAR(128) not null,
|
||||
local_mount VARCHAR(128) not null default '/relaymout.ogg',
|
||||
-- eg joe. could be null
|
||||
username VARCHAR(64) default NULL ,
|
||||
username VARCHAR(64) not null default 'jkicerelayusr' ,
|
||||
-- user password
|
||||
password VARCHAR(64) default null ,
|
||||
password VARCHAR(64) not null default 'jkicerelaypwd' ,
|
||||
relay_shoutcast_metadata INTEGER default 0,
|
||||
--- relay only if we have someone wanting to listen
|
||||
on_demand INTEGER default 0,
|
||||
|
|
@ -164,28 +164,28 @@ create TABLE icecast_user_authentications(
|
|||
id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
|
||||
--"htpasswd or url"
|
||||
-- real name is type
|
||||
stype VARCHAR(16) DEFAULT NULL ,
|
||||
stype VARCHAR(16) DEFAULT 'url' ,
|
||||
-- these are for httpasswd
|
||||
filename VARCHAR(256) default NULL,
|
||||
allow_duplicate_users INTEGER DEFAULT 0,
|
||||
allow_duplicate_users INTEGER DEFAULT 1,
|
||||
|
||||
-- these options are for url
|
||||
-- eg value="http://myauthserver.com/stream_start.php"
|
||||
mount_add VARCHAR(256) default NULL,
|
||||
mount_add VARCHAR(256) DEFAULT 'http://icecastauth.jamkazam.com/stream_start.php',
|
||||
--value="http://myauthserver.com/stream_end.php"
|
||||
mount_remove VARCHAR(256) default NULL,
|
||||
mount_remove VARCHAR(256) default 'http://icecastauth.jamkazam.com/stream_end.php',
|
||||
--value="http://myauthserver.com/listener_joined.php"
|
||||
listener_add VARCHAR(256) default NULL,
|
||||
listener_add VARCHAR(256) default 'http://icecastauth.jamkazam.com/listener_joined.php',
|
||||
--value="http://myauthserver.com/listener_left.php"
|
||||
listener_remove VARCHAR(256) default NULL,
|
||||
listener_remove VARCHAR(256) default 'http://icecastauth.jamkazam.com/listener_left.php',
|
||||
-- value="user"
|
||||
username VARCHAR(64) default NULL,
|
||||
username VARCHAR(64) default 'jkuser',
|
||||
-- value="pass"
|
||||
password VARCHAR(64) default NULL,
|
||||
password VARCHAR(64) DEFAULT 'jkhackpass',
|
||||
-- value="icecast-auth-user: 1"
|
||||
auth_header VARCHAR(64) default NULL,
|
||||
auth_header VARCHAR(64) default 'icecast-auth-user: 1',
|
||||
-- value="icecast-auth-timelimit:"
|
||||
timelimit_header VARCHAR(64) default NULL,
|
||||
timelimit_header VARCHAR(64) default 'icecast-auth-timelimit:',
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
|
|
@ -197,7 +197,7 @@ create table icecast_mounts (
|
|||
-- eg/example-complex.ogg
|
||||
mount_name VARCHAR(128) UNIQUE NOT NULL,
|
||||
username VARCHAR(64) NOT NULL DEFAULT 'jamsource',
|
||||
password VARCHAR(64) NOT NULL DEFAULT 'jamksource',
|
||||
password VARCHAR(64) NOT NULL DEFAULT 'jamhackmesourcepwd',
|
||||
max_listeners INTEGER NOT NULL DEFAULT 4,
|
||||
max_listener_duration INTEGER NOT NULL DEFAULT 3600,
|
||||
-- dump of the stream coming through on this mountpoint.
|
||||
|
|
@ -248,6 +248,8 @@ create table icecast_mounts (
|
|||
on_connect VARCHAR(256) DEFAULT '/home/icecast/bin/source-start',
|
||||
on_disconnect VARCHAR(256) DEFAULT '/home/icecast/bin/source-end',
|
||||
|
||||
user_authentication_id varchar(64) DEFAULT NULL references icecast_user_authentications(id),
|
||||
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
@ -294,15 +296,60 @@ create table icecast_securities (
|
|||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
create TABLE icecast_servers(
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
icecast_limit_id VARCHAR(64) REFERENCES icecast_limits(id)
|
||||
--use this to mark the server configuration as needing to be regenerated
|
||||
config_changed INTEGER DEFAULT 0,
|
||||
|
||||
limit_id VARCHAR(64) REFERENCES icecast_limits(id),
|
||||
adminauth_id VARCHAR(64) REFERENCES icecast_admin_authentications(id),
|
||||
directory_id VARCHAR(64) REFERENCES icecast_directories(id),
|
||||
misc_id VARCHAR(64) REFERENCES icecast_servermiscs(id),
|
||||
master_relay_id VARCHAR(64) REFERENCES icecast_mastersvr_relays(id),
|
||||
|
||||
/* relay_ids VARCHAR(64) REFERENCES icecast_serverrelays(id),
|
||||
mount_ids VARCHAR(64) REFERENCES icecast_servermounts(id),
|
||||
socket_ids VARCHAR(64) REFERENCES icecast_serversockets(id) ,
|
||||
*/
|
||||
|
||||
-- configs
|
||||
-- mounts
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE icecast_servermounts (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
mount_id VARCHAR(64) REFERENCES icecast_mounts(id) ON DELETE CASCADE,
|
||||
server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE icecast_servermounts ADD CONSTRAINT server_mount_uniqkey UNIQUE (server_id, mount_id);
|
||||
|
||||
CREATE TABLE icecast_serverrelays (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
relay_id VARCHAR(64) REFERENCES icecast_relays(id) ON DELETE CASCADE,
|
||||
server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE icecast_serverrelays ADD CONSTRAINT server_relay_uniqkey UNIQUE (server_id, relay_id);
|
||||
|
||||
CREATE TABLE icecast_serversockets (
|
||||
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
socket_id VARCHAR(64) REFERENCES icecast_listen_sockets(id) ON DELETE CASCADE,
|
||||
server_id VARCHAR(64) REFERENCES icecast_servers(id) ON DELETE CASCADE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
ALTER TABLE icecast_serversockets ADD CONSTRAINT server_socket_uniqkey UNIQUE (server_id, socket_id);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE mixes DROP COLUMN manifest;
|
||||
ALTER TABLE mixes ADD COLUMN should_retry BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,26 +1,19 @@
|
|||
|
||||
module JSONable
|
||||
def jdumpXml (ovb, nm, ident=1, output=$stdout)
|
||||
|
||||
serialized = Hash.new
|
||||
ovb.myattr_accessor.each do |attribute|
|
||||
#serialized[attribute] = ovb[attribute]
|
||||
puts "attribute = #{attribute}"
|
||||
#serialized[attribute] = self.public_send attribute
|
||||
end
|
||||
|
||||
hash = serialized
|
||||
module JAmXml
|
||||
def jdumpXml (hash, nm, ident=1, output=$stdout, child=nil)
|
||||
|
||||
tb = "\t"
|
||||
tbs = tb * ident
|
||||
tbse = tb * (ident-1)
|
||||
|
||||
output.puts "#{tbse}<#{nm}>"
|
||||
unless ident <= 0
|
||||
tbse = tb * (ident-1)
|
||||
output.puts "#{tbse}<#{nm}>"
|
||||
end
|
||||
|
||||
hash.each do |key, val|
|
||||
#puts "attrib: key=#{key} val=#{val}"
|
||||
|
||||
el = key
|
||||
if key.present?
|
||||
if !key.nil? && !key.empty?
|
||||
el = key.gsub(/_/, '-')
|
||||
end
|
||||
|
||||
|
|
@ -28,15 +21,45 @@ module JSONable
|
|||
sv = val
|
||||
if val.to_s.empty?
|
||||
#skip ???
|
||||
next if val.to_s.empty?
|
||||
else
|
||||
if val.instance_of? String
|
||||
#encode the string to be xml safe
|
||||
sv = CGI.escapeHTML(val)
|
||||
end
|
||||
end
|
||||
output.puts "#{tbs}<#{el}>#{sv}</#{el}>"
|
||||
|
||||
if key.empty?
|
||||
output.puts "#{tbs}<#{sv}/>"
|
||||
else
|
||||
output.puts "#{tbs}<#{el}>#{sv}</#{el}>"
|
||||
end
|
||||
end
|
||||
puts "#{tbse}</#{nm}>"
|
||||
|
||||
if !child.nil?
|
||||
if child.kind_of? Array
|
||||
child.each { |x| x.dumpXml(ident+1,output)}
|
||||
else
|
||||
child.dumpXml(ident+1,output)
|
||||
end
|
||||
end
|
||||
unless ident <= 0
|
||||
puts "#{tbse}</#{nm}>"
|
||||
end
|
||||
end
|
||||
|
||||
def jMakeStrXmlSafe(val)
|
||||
sv = val
|
||||
if val.to_s.empty?
|
||||
#skip ???
|
||||
sv =""
|
||||
else
|
||||
if val.instance_of? String
|
||||
#encode the string to be xml safe
|
||||
sv = CGI.escapeHTML(val)
|
||||
end
|
||||
end
|
||||
return sv
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -44,7 +67,7 @@ end
|
|||
|
||||
module JamRuby
|
||||
class IcecastAdminAuthentication < ActiveRecord::Base
|
||||
include JSONable
|
||||
include JAmXml
|
||||
|
||||
attr_accessible :source_password, :relay_user, :relay_password, :admin_user, :admin_password
|
||||
#myattr_accessor = [:source_password, :relay_user, :relay_password, :admin_user, :admin_password ]
|
||||
|
|
@ -65,7 +88,13 @@ module JamRuby
|
|||
validates :admin_password, presence: true, length: {minimum: 5}
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
self.jdumpXml(self,"authentication", ident,output)
|
||||
hash = Hash["source_password" => self.source_password,
|
||||
"relay_user" => self.relay_user,
|
||||
"relay_password" => self.relay_password,
|
||||
"admin_user" => self.admin_user,
|
||||
"admin_password" => self.admin_password]
|
||||
|
||||
self.jdumpXml(hash,"authentication", ident,output)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
module JamRuby
|
||||
class IcecastDirectory < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
|
||||
attr_accessible :yp_url_timeout, :yp_url
|
||||
attr_accessor :yp_url_timeout, :yp_url
|
||||
validates :yp_url_timeout, numericality: {only_integer: true}, length: {in: 1..30}
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
hash = Hash["yp_url_timeout" => self.yp_url_timeout,
|
||||
"yp_url" => self.yp_url]
|
||||
self.jdumpXml(hash, "directory", ident, output)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
module JamRuby
|
||||
class IcecastLimit < ActiveRecord::Base
|
||||
include JSONable
|
||||
include JAmXml
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :clients, :sources, :queue_size, :client_timeout, :header_timeout, :source_timeout, :burst_size
|
||||
#attr_accessor :clients, :sources, :queue_size, :client_timeout, :header_timeout, :source_timeout, :burst_size
|
||||
|
||||
#validates :clients, numericality: {only_integer: true}, length: {in: 1..15000}
|
||||
validates :clients, numericality: {only_integer: true}
|
||||
validates :clients, numericality: {only_integer: true}, length: {in: 1..15000}
|
||||
|
||||
|
||||
after_initialize :init
|
||||
|
||||
|
|
@ -23,12 +22,17 @@ module JamRuby
|
|||
self.burst_size ||= 65536
|
||||
end
|
||||
|
||||
def setclients(val)
|
||||
@clients = val
|
||||
end
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
self.jdumpXml(self, "limits", ident, output)
|
||||
hash = Hash["clients" => self.clients,
|
||||
"sources" => self.sources,
|
||||
"queue_size" => self.queue_size,
|
||||
"client_timeout" => self.client_timeout,
|
||||
"header_timeout" => self.header_timeout]
|
||||
hash.merge! "source_timeout" => self.source_timeout,
|
||||
"burst_size" => self.burst_size
|
||||
self.jdumpXml(hash, "limits", ident, output)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
module JamRuby
|
||||
class IcecastListenSocket < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :port, :bind_address, :shoutcast_mount, :shoutcast_compat
|
||||
attr_accessor :port, :bind_address, :shoutcast_mount, :shoutcast_compat
|
||||
|
||||
def dumpXml()
|
||||
belongs_to :server, :class_name => "JamRuby::IcecastServer" , :inverse_of => :sockets
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
hash = Hash["port" => self.port,
|
||||
"bind_address" => self.bind_address,
|
||||
"shoutcast_mount" => self.shoutcast_mount,
|
||||
"shoutcast_compat" => self.shoutcast_compat]
|
||||
|
||||
self.jdumpXml(hash, "listen-socket", ident, output)
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
module JamRuby
|
||||
class IcecastLogging < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :accesslog, :errorlog, :playlistlog, :loglevel
|
||||
attr_accessor :accesslog, :errorlog, :playlistlog, :loglevel
|
||||
|
||||
def dumpXml()
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
|
||||
hash = Hash["accesslog" => self.accesslog,
|
||||
"errorlog" => self.errorlog,
|
||||
"loglevel" => self.loglevel,
|
||||
"playlistlog" => self.playlistlog]
|
||||
|
||||
self.jdumpXml(hash, "logging", ident, output)
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
module JamRuby
|
||||
class IcecastMastersvrRelay < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
attr_accessible :master_server, :master_server_port, :master_username, :master_password, :relays_on_demand
|
||||
attr_accessible :master_server, :master_server_port, :master_username, :master_password, :relays_on_demand
|
||||
validates :master_password, :master_username, presence: true
|
||||
|
||||
def dumpXml()
|
||||
def dumpXml (ident=0, output=$stdout)
|
||||
hash = Hash["master_server" => self.master_server,
|
||||
"master_server_port" => self.master_server_port,
|
||||
"master_username" => self.master_username,
|
||||
"master_password" => self.master_password,
|
||||
"relays_on_demand" => self.relays_on_demand]
|
||||
|
||||
self.jdumpXml(hash, "masterrelay", ident, output)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,24 +1,64 @@
|
|||
module JamRuby
|
||||
class IcecastMount < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :mount_name, :username, :password, :max_listeners, :max_listener_duration, :dump_file
|
||||
attr_accessor :mount_name, :username, :password, :max_listeners, :max_listener_duration, :dump_file
|
||||
|
||||
attr_accessible :intro, :fallback_mount, :fallback_override, :fallback_when_full, :charset
|
||||
attr_accessor :intro, :fallback_mount, :fallback_override, :fallback_when_full, :charset
|
||||
|
||||
attr_accessible :publicc, :stream_name, :stream_description, :stream_url, :genre, :bitrate
|
||||
attr_accessor :publicc, :stream_name, :stream_description, :stream_url, :genre, :bitrate
|
||||
|
||||
attr_accessible :mtype, :subtype, :hidden, :burst_size, :mp3_metadata_interval, :on_connect, :on_disconnect
|
||||
attr_accessor :mtype, :subtype, :hidden, :burst_size, :mp3_metadata_interval, :on_connect, :on_disconnect
|
||||
|
||||
validates :mount_name, presence: true
|
||||
validates :username, presence: true
|
||||
validates :password, presence: true
|
||||
|
||||
#has_one :authentication, :class_name => "IcecastUserAuthentication"
|
||||
has_one :authentication, :class_name => "IcecastUserAuthentication"
|
||||
belongs_to :servermount, :class_name => "JamRuby::IcecastServermount" , :inverse_of => :mount
|
||||
|
||||
def dumpXml()
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
hash = Hash["mount_name" => self.mount_name,
|
||||
"username" => self.username,
|
||||
"password" => self.password,
|
||||
"max_listeners" => self.max_listeners,
|
||||
"max_listener_duration" => self.max_listener_duration,
|
||||
"dump_file" => self.dump_file,
|
||||
|
||||
"intro" => self.intro,
|
||||
"fallback_mount" => self.fallback_mount,
|
||||
"fallback_override" => self.fallback_override,
|
||||
"fallback_when_full" => self.fallback_when_full,
|
||||
"charset" => self.charset,
|
||||
|
||||
"public" => self.publicc,
|
||||
"stream_name" => self.stream_name,
|
||||
"stream_description" => self.stream_description,
|
||||
"stream_url" => self.stream_url,
|
||||
"genre" => self.genre,
|
||||
"bitrate" => self.bitrate,
|
||||
|
||||
"type" => self.mtype,
|
||||
"subtype" => self.subtype,
|
||||
"hidden" => self.hidden,
|
||||
"burst_size" => self.burst_size,
|
||||
"mp3_metadata_interval" => self.mp3_metadata_interval,
|
||||
"on_connect" => self.on_connect,
|
||||
"on_disconnect" => self.on_disconnect
|
||||
]
|
||||
|
||||
self.jdumpXml(hash, "mount", ident, output, self.authentication)
|
||||
end
|
||||
|
||||
def getMediaUrl
|
||||
if !self.servermount.nil?
|
||||
@server = self.servermount.server
|
||||
@misc = @server.misc
|
||||
url = "http://" + @misc.hostname + self.mount_name
|
||||
return url;
|
||||
else
|
||||
raise ("Undefined severid")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,13 +1,24 @@
|
|||
module JamRuby
|
||||
class IcecastPath < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :basedir, :logdir, :pidfile, :webroot, :adminroot, :allow_ip, :deny_ip, :aliass
|
||||
attr_accessor :basedir, :logdir, :pidfile, :webroot, :adminroot, :allow_ip, :deny_ip, :aliass
|
||||
|
||||
def dumpXml()
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
|
||||
a = "alias #{self.aliass}"
|
||||
hash = Hash["basedir" => self.basedir,
|
||||
"logdir" => self.logdir,
|
||||
"pidfile" => self.pidfile,
|
||||
"webroot" => self.webroot,
|
||||
"adminroot" => self.adminroot,
|
||||
|
||||
"allow_ip" => self.allow_ip,
|
||||
"deny_ip" => self.deny_ip,
|
||||
"" => a,
|
||||
]
|
||||
self.jdumpXml(hash, "paths", ident, output)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,14 +1,35 @@
|
|||
module JamRuby
|
||||
class IcecastRelay < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :server, :port, :mount, :local_mount, :username, :password, :relay_shoutcast_metadata, :on_demand
|
||||
attr_accessor :server, :port, :mount, :local_mount, :username, :password, :relay_shoutcast_metadata, :on_demand
|
||||
|
||||
def dumpXml()
|
||||
validates :port, numericality: {only_integer: true}, length: {in: 1..65000}
|
||||
validates :mount, presence: true
|
||||
validates :server, presence: true
|
||||
validates :local_mount, presence: true
|
||||
validates :username, presence: true
|
||||
validates :password, presence: true
|
||||
|
||||
belongs_to :sserver, :class_name => "JamRuby::IcecastServerrelay"
|
||||
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
|
||||
hash = Hash["server" => self.server,
|
||||
"port" => self.port,
|
||||
"mount" => self.mount,
|
||||
"local_mount" => self.local_mount,
|
||||
"username" => self.username,
|
||||
|
||||
"password" => self.password,
|
||||
"relay_shoutcast_metadata" => self.relay_shoutcast_metadata,
|
||||
"on_demand" => self.on_demand
|
||||
]
|
||||
self.jdumpXml(hash, "relay", ident, output)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,12 +1,39 @@
|
|||
module JamRuby
|
||||
class IcecastSecurity < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :chroot, :changeowner_user, :changeowner_group
|
||||
attr_accessor :chroot, :changeowner_user, :changeowner_group
|
||||
|
||||
def dumpXml()
|
||||
validates :chroot, numericality: {only_integer: true}, length: {in: 0..1}
|
||||
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
|
||||
tb = "\t"
|
||||
tbs = tb * (ident)
|
||||
tbs2 = tb * (ident+1)
|
||||
tbse = tb * (ident-1)
|
||||
if tbse.empty? || tbse.nil?
|
||||
tbse=""
|
||||
end
|
||||
|
||||
|
||||
nm = "security"
|
||||
output.puts "#{tbse}<#{nm}>"
|
||||
|
||||
output.puts "#{tbs}<chroot>#{self.chroot}</chroot>"
|
||||
output.puts "#{tbs}<changeowner>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.changeowner_user)
|
||||
output.puts "#{tbs2}<user>#{v}</user>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.changeowner_group)
|
||||
output.puts "#{tbs2}<group>#{v}</group>"
|
||||
|
||||
output.puts "#{tbs}<changeowner>"
|
||||
|
||||
output.puts "#{tbse}</#{nm}>"
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,75 @@
|
|||
module JamRuby
|
||||
class IcecastServer < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
has_one :limit, :class_name => "JamRuby::IcecastLimit"
|
||||
has_one :adminauth, :class_name => "JamRuby::IcecastAdminAuthentication"
|
||||
has_one :directory, :class_name => "JamRuby::IcecastDirectory"
|
||||
has_one :misc, :class_name => "JamRuby::IcecastServermisc"
|
||||
has_many :listen_sockets, :class_name => "JamRuby::IcecastListenSocket"
|
||||
has_one :master_relay, :class_name => "JamRuby::IcecastMastersvrRelay"
|
||||
has_one :relay, :class_name => "JamRuby::IcecastRelay"
|
||||
has_many :mounts, :class_name => "JamRuby::IcecastMount"
|
||||
has_one :path, :class_name => "JamRuby::IcecastPath"
|
||||
has_one :logging, :class_name => "JamRuby::IcecastLogging"
|
||||
has_one :security, :class_name => "JamRuby::IceCastSecurity"
|
||||
has_one :limit, :class_name => "JamRuby::IcecastLimit" , foreign_key: "id"
|
||||
has_one :adminauth, :class_name => "JamRuby::IcecastAdminAuthentication" , foreign_key: "id"
|
||||
has_one :directory, :class_name => "JamRuby::IcecastDirectory" , foreign_key: "id"
|
||||
has_one :misc, :class_name => "JamRuby::IcecastServermisc" , foreign_key: "id"
|
||||
|
||||
def dumpXml()
|
||||
has_one :master_relay, :class_name => "JamRuby::IcecastMastersvrRelay" , foreign_key: "id"
|
||||
|
||||
has_many :smounts, :class_name => "JamRuby::IcecastServermount"
|
||||
has_many :mounts, :class_name => "JamRuby::IcecastMount", :through => :smounts
|
||||
|
||||
has_many :ssockets, :class_name => "JamRuby::IcecastServersocket"
|
||||
has_many :sockets, :class_name => "JamRuby::IcecastListenSocket" ,:through => :ssockets
|
||||
|
||||
has_many :srelays, :class_name => "JamRuby::IcecastServerrelay" , :inverse_of => :server
|
||||
has_many :relays, :class_name => "JamRuby::IcecastRelay" , :through => :srelays
|
||||
|
||||
|
||||
has_one :path, :class_name => "JamRuby::IcecastPath" , foreign_key: "id"
|
||||
has_one :logging, :class_name => "JamRuby::IcecastLogging" , foreign_key: "id"
|
||||
has_one :security, :class_name => "JamRuby::IcecastSecurity" , foreign_key: "id"
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
ident += 1
|
||||
unless self.limit.nil?
|
||||
self.limit.dumpXml(ident,output)
|
||||
end
|
||||
unless self.adminauth.nil?
|
||||
self.adminauth.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
unless self.directory.nil?
|
||||
self.directory.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
unless self.misc.nil?
|
||||
self.misc.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
unless self.master_relay.nil?
|
||||
self.master_relay.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
|
||||
unless self.path.nil?
|
||||
self.path.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
unless self.logging.nil?
|
||||
self.logging.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
unless self.security.nil?
|
||||
self.security.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
|
||||
self.relays.each do |rl|
|
||||
sock.rl(ident,output)
|
||||
end
|
||||
|
||||
self.sockets.each do |sock|
|
||||
sock.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
self.mounts.each do |mount|
|
||||
mount.dumpXml(ident,output)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
module JamRuby
|
||||
class IcecastServermisc < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :hostname, :location, :admin, :fileserve, :server_id
|
||||
attr_accessor :hostname, :location, :admin, :fileserve, :server_id
|
||||
|
||||
def dumpXml()
|
||||
|
||||
def dumpXml (ident=0, output=$stdout)
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
module JamRuby
|
||||
class IcecastServermount < ActiveRecord::Base
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :mount, :class_name => "JamRuby::IcecastMount" , :inverse_of => :servermount
|
||||
belongs_to :server, :class_name => "JamRuby::IcecastServer"
|
||||
|
||||
validates :server_id, :presence => true
|
||||
validates :mount_id, :presence => true
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
module JamRuby
|
||||
class IcecastServerrelay < ActiveRecord::Base
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :relay, :class_name => "JamRuby::IcecastRelay"
|
||||
belongs_to :server, :class_name => "JamRuby::IcecastServer"
|
||||
|
||||
validates :server_id, :presence => true
|
||||
validates :relay_id, :presence => true
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
module JamRuby
|
||||
class IcecastServersocket < ActiveRecord::Base
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :socket, :class_name => "JamRuby::IcecastListenSocket" , foreign_key: "id"
|
||||
belongs_to :server, :class_name => "JamRuby::IcecastServer" , foreign_key: "id"
|
||||
|
||||
validates :socket_id, :presence => true
|
||||
validates :server_id, :presence => true
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -1,16 +1,76 @@
|
|||
module JamRuby
|
||||
class IcecastUserAuthentication < ActiveRecord::Base
|
||||
|
||||
include JAmXml
|
||||
self.primary_key = 'id'
|
||||
|
||||
attr_accessible :stype, :filename, :allow_duplicate_users, :mount_add, :mount_remove,
|
||||
:listener_add, :listener_remove, :username, :password, :auth_header, :timelimit_header
|
||||
|
||||
attr_accessor :stype, :filename, :allow_duplicate_users, :mount_add, :mount_remove,
|
||||
:listener_add, :listener_remove, :username, :password, :auth_header, :timelimit_header
|
||||
|
||||
|
||||
def dumpXml()
|
||||
validates :stype, presence: true
|
||||
|
||||
def dumpXml (ident=1, output=$stdout)
|
||||
|
||||
tb = "\t"
|
||||
tbs = tb * (ident)
|
||||
tbse = tb * (ident-1)
|
||||
if tbse.empty? || tbse.nil?
|
||||
tbse=""
|
||||
end
|
||||
|
||||
if self.stype.nil?
|
||||
return
|
||||
elsif self.stype.empty?
|
||||
return
|
||||
elsif self.stype == "htpasswd"
|
||||
nm = "<authentication type=\"htpasswd\">"
|
||||
|
||||
output.puts "#{tbse}#{nm}"
|
||||
fname = jMakeStrXmlSafe(self.filename)
|
||||
|
||||
output.puts "#{tbs}<option name=\"filename\" value=\"#{fname}\"/>"
|
||||
output.puts "#{tbs}<option name=\"allow_duplicate_users\" value=\"#{self.allow_duplicate_users}\"/>"
|
||||
nm = "authentication"
|
||||
output.puts "#{tbse}</#{nm}>"
|
||||
|
||||
elsif self.stype == 'url'
|
||||
|
||||
nm = "<authentication type=\"url\">"
|
||||
output.puts "#{tbse}#{nm}"
|
||||
v = jMakeStrXmlSafe(self.mount_add)
|
||||
output.puts "#{tbs}<option name=\"mount_add\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.mount_remove)
|
||||
output.puts "#{tbs}<option name=\"mount_remove\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.listener_add)
|
||||
output.puts "#{tbs}<option name=\"listener_add\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.listener_remove)
|
||||
output.puts "#{tbs}<option name=\"listener_remove\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.listener_remove)
|
||||
output.puts "#{tbs}<option name=\"listener_remove\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.username)
|
||||
output.puts "#{tbs}<option name=\"username\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.password)
|
||||
output.puts "#{tbs}<option name=\"password\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.auth_header)
|
||||
output.puts "#{tbs}<option name=\"auth_header\" value=\"#{v}\"/>"
|
||||
|
||||
v = jMakeStrXmlSafe(self.timelimit_header)
|
||||
output.puts "#{tbs}<option name=\"timelimit_header\" value=\"#{v}\"/>"
|
||||
|
||||
|
||||
nm = "authentication"
|
||||
output.puts "#{tbse}</#{nm}>"
|
||||
else
|
||||
raise 'Unsupported authentication format #{self.stype}'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ 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(mix.created_at, recording.id, mix.id)
|
||||
if mix.save
|
||||
|
|
@ -26,7 +26,16 @@ module JamRuby
|
|||
end
|
||||
|
||||
def enqueue
|
||||
Resque.enqueue(AudioMixer, self.id, self.sign_put)
|
||||
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)
|
||||
|
|
@ -53,6 +62,23 @@ 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(url)
|
||||
end
|
||||
|
|
@ -70,6 +96,12 @@ module JamRuby
|
|||
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
|
||||
|
||||
def delete_s3_files
|
||||
|
|
|
|||
|
|
@ -285,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
|
||||
|
|
@ -310,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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -210,7 +209,7 @@ module JamRuby
|
|||
return
|
||||
end
|
||||
|
||||
@manifest = symbolize_keys(JSON.parse(mix.manifest))
|
||||
@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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -8,8 +8,10 @@ describe IcecastDirectory do
|
|||
|
||||
end
|
||||
|
||||
|
||||
it "save" do
|
||||
idir.save.should be_true
|
||||
idir.dumpXml
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ describe IcecastLimit do
|
|||
v = IcecastLimit.find(limit.id)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
it "non-integer clients should be checked" do
|
||||
limit.setclients 'a'
|
||||
puts limit.clients
|
||||
puts limit.inspect
|
||||
limit.clients = 'a'
|
||||
#puts limit.clients
|
||||
#puts limit.inspect
|
||||
limit.save.should be_false
|
||||
limit.errors[:clients].should == ['is not a number']
|
||||
limit.errors[:clients].should === ['is not a number']
|
||||
end
|
||||
=end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ describe IcecastListenSocket do
|
|||
|
||||
it "save" do
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ describe IcecastLogging do
|
|||
|
||||
it "save" do
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -9,12 +9,13 @@ describe IcecastMastersvrRelay do
|
|||
end
|
||||
|
||||
|
||||
=begin
|
||||
|
||||
it "should not save" do
|
||||
iobj.save.should be_false
|
||||
iobj.errors[:master_server].should_equal "is required"
|
||||
#puts iobj.errors.inspect
|
||||
iobj.errors[:master_password].should === ["can't be blank"]
|
||||
end
|
||||
=end
|
||||
|
||||
|
||||
it "should save" do
|
||||
iobj.master_server = "test.www.com"
|
||||
|
|
@ -22,6 +23,7 @@ describe IcecastMastersvrRelay do
|
|||
iobj.master_username = "hack"
|
||||
iobj.master_password = "hackme"
|
||||
iobj.save.should be_true
|
||||
#iobj.dumpXml
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -9,9 +9,36 @@ describe IcecastMount do
|
|||
end
|
||||
|
||||
=begin
|
||||
|
||||
it "save" do
|
||||
iobj.save.should be_true
|
||||
iobj.build_authentication
|
||||
@ua = iobj.authentication
|
||||
@ua.username ="testcase"
|
||||
iobj.mount_name = "Dhdhjd<>&%&&s@#$% gg8io9 fdfdj"
|
||||
iobj.save
|
||||
#puts iobj.inspect
|
||||
iobj.dumpXml
|
||||
iobj.errors.any?.should be_false
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
it "save 2" do
|
||||
iobj.build_authentication
|
||||
@ua = iobj.authentication
|
||||
@ua.stype =""
|
||||
|
||||
iobj.mount_name = "No auth 473873434"
|
||||
iobj.save
|
||||
#puts iobj.inspect
|
||||
#puts iobj.errors.inspect
|
||||
iobj.dumpXml
|
||||
iobj.errors.any?.should be_false
|
||||
end
|
||||
=end
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -10,6 +10,7 @@ describe IcecastPath do
|
|||
|
||||
it "save" do
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -8,10 +8,15 @@ describe IcecastRelay do
|
|||
|
||||
end
|
||||
|
||||
|
||||
=begin
|
||||
it "save" do
|
||||
:iobj.save.should be_true
|
||||
iobj.server ="10.7.0.99"
|
||||
iobj.mount ="/lcrock.ogg"
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
end
|
||||
=end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe IcecastSecurity do
|
||||
|
||||
let(:iobj) { IcecastSecurity.new }
|
||||
|
||||
before(:all) do
|
||||
|
||||
end
|
||||
|
||||
|
||||
it "save" do
|
||||
iobj.changeowner_user ="hotdog"
|
||||
iobj.changeowner_group ="mongrel"
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe IcecastServer do
|
||||
|
||||
let(:iobj) { IcecastServer.new }
|
||||
|
||||
before(:all) do
|
||||
|
||||
end
|
||||
|
||||
=begin
|
||||
it "save master" do
|
||||
iobj.build_limit
|
||||
iobj.build_adminauth
|
||||
iobj.build_directory
|
||||
iobj.build_logging
|
||||
iobj.build_path
|
||||
iobj.build_master_relay
|
||||
iobj.build_misc
|
||||
|
||||
m1 = IcecastMount.new
|
||||
m1.mount_name = "/m1hottstuff.og"
|
||||
m2 = IcecastMount.new
|
||||
m1.mount_name = "/m2.ogg"
|
||||
|
||||
sm = IcecastServermount.new
|
||||
sm.build_mount= iobj,m1
|
||||
sm.build_mount= iobj,m2
|
||||
|
||||
|
||||
# iobj.mounts=m1,m2
|
||||
|
||||
iobj.save
|
||||
puts iobj.errors.inspect
|
||||
iobj.dumpXml
|
||||
iobj.errors.any?.should be_false
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
it "save relay" do
|
||||
iobj.build_limit
|
||||
iobj.build_adminauth
|
||||
iobj.build_directory
|
||||
|
||||
iobj.build_path
|
||||
iobj.build_relay
|
||||
iobj.build_misc
|
||||
|
||||
iobj.build_logging
|
||||
iobj.build_security
|
||||
|
||||
m1 = IcecastMount.new
|
||||
m1.mount_name = "/relaymout.ogg"
|
||||
m2 = IcecastMount.new
|
||||
m1.mount_name = "/local.ogg"
|
||||
iobj.mounts=m1,m2
|
||||
|
||||
|
||||
iobj.save
|
||||
#puts iobj.inspect
|
||||
iobj.dumpXml
|
||||
iobj.errors.any?.should be_false
|
||||
|
||||
end
|
||||
=end
|
||||
end
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe IcecastUserAuthentication do
|
||||
|
||||
let(:iobj) { IcecastUserAuthentication.new }
|
||||
|
||||
before(:all) do
|
||||
|
||||
end
|
||||
|
||||
it "save" do
|
||||
iobj.save
|
||||
#puts iobj.inspect
|
||||
iobj.dumpXml
|
||||
iobj.errors.any?.should be_false
|
||||
end
|
||||
|
||||
|
||||
|
||||
it "http autthenication" do
|
||||
iobj.stype = 'htpasswd'
|
||||
#puts limit.clients
|
||||
#puts limit.inspect
|
||||
iobj.filename ="/dfdfd</$%%%6566.auth"
|
||||
iobj.save.should be_true
|
||||
iobj.dumpXml
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -225,7 +230,8 @@ describe AudioMixer do
|
|||
|
||||
it "bails out with no error if already completed" 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
|
||||
|
|
@ -274,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
|
||||
|
|
@ -286,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()
|
||||
|
|
|
|||
11
web/Gemfile
11
web/Gemfile
|
|
@ -61,6 +61,7 @@ gem 'haml-rails'
|
|||
gem 'resque'
|
||||
gem 'resque-retry'
|
||||
gem 'resque-failed-job-mailer'
|
||||
gem 'resque-dynamic-queues'
|
||||
|
||||
gem 'quiet_assets', :group => :development
|
||||
|
||||
|
|
@ -90,12 +91,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'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ rm -rf $DIR/target
|
|||
mkdir $DIR/target
|
||||
mkdir $DIR/target/deb
|
||||
|
||||
rm -rf vendor/bundle
|
||||
#rm -rf vendor/bundle -- let jenkins config wipe workspace, or not
|
||||
|
||||
rm -rf tmp/capybara
|
||||
rm -f Gemfile.lock # if we don't want versions to float, pin it in the Gemfile, not count on Gemfile.lock
|
||||
# put all dependencies into vendor/bundle
|
||||
|
|
|
|||
|
|
@ -167,5 +167,15 @@ include JamRuby
|
|||
config.redis_host = "localhost:6379"
|
||||
|
||||
config.audiomixer_path = "/var/lib/audiomixer/audiomixer/audiomixerapp"
|
||||
|
||||
config.email_alerts_alias = 'alerts@jamkazam.com' # should be used for 'oh no' server down/service down sorts of emails
|
||||
config.email_generic_from = 'nobody@jamkazam.com'
|
||||
config.email_smtp_address = 'smtp.sendgrid.net'
|
||||
config.email_smtp_port = 587
|
||||
config.email_smtp_domain = 'www.jamkazam.com'
|
||||
config.email_smtp_authentication = :plain
|
||||
config.email_smtp_user_name = 'jamkazam'
|
||||
config.email_smtp_password = 'jamjamblueberryjam'
|
||||
config.email_smtp_starttls_auto = true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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|
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
ActionMailer::Base.raise_delivery_errors = true
|
||||
ActionMailer::Base.delivery_method = Rails.env == "test" ? :test : :smtp
|
||||
ActionMailer::Base.smtp_settings = {
|
||||
:address => "smtp.sendgrid.net",
|
||||
:port => 587,
|
||||
:domain => "www.jamkazam.com",
|
||||
:authentication => :plain,
|
||||
:user_name => "jamkazam",
|
||||
:password => "jamjamblueberryjam",
|
||||
:enable_starttls_auto => true
|
||||
:address => Rails.application.config.email_smtp_address,
|
||||
:port => Rails.application.config.email_smtp_port,
|
||||
:domain => Rails.application.config.email_smtp_domain,
|
||||
:authentication => Rails.application.config.email_smtp_authentication,
|
||||
:user_name => Rails.application.config.email_smtp_user_name,
|
||||
:password => Rails.application.config.email_smtp_password ,
|
||||
:enable_starttls_auto => Rails.application.config.email_smtp_starttls_auto
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
require 'resque_failed_job_mailer'
|
||||
|
||||
Resque::Failure::Notifier.configure do |config|
|
||||
config.from = 'seth@jamkazam.com'
|
||||
config.to = 'seth@jamkazam.com'
|
||||
config.from = Rails.application.config.email_alerts_alias
|
||||
config.to = Rails.application.config.email_generic_from
|
||||
end
|
||||
|
|
@ -296,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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -1,14 +1,34 @@
|
|||
# this rake file is meant to hold shortcuts/helpers for starting onerous command line executions
|
||||
|
||||
# bunde exec rake all_jobs
|
||||
task :all_jobs do
|
||||
Rake::Task['environment'].invoke
|
||||
|
||||
ENV['QUEUE'] = '*'
|
||||
Rake::Task['resque:work'].invoke
|
||||
end
|
||||
|
||||
# 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'
|
||||
Rake::Task['resque:work'].invoke
|
||||
end
|
||||
|
||||
# bundle exec rake icecast
|
||||
task :icecast do
|
||||
Rake::Task['environment'].invoke
|
||||
|
||||
ENV['QUEUE'] = 'icecast'
|
||||
Rake::Task['resque:work'].invoke
|
||||
end
|
||||
|
||||
# bundle exec rake odd_jobs
|
||||
# this command is the same as used in production
|
||||
task :odd_jobs do
|
||||
Rake::Task['environment'].invoke
|
||||
|
||||
ENV['QUEUE'] = '*,!icecast,!audiomixer'
|
||||
Rake::Task['resque:work'].invoke
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -19,21 +19,13 @@ chown -R $USER:$GROUP /var/lib/$NAME
|
|||
chown -R $USER:$GROUP /etc/$NAME
|
||||
chown -R $USER:$GROUP /var/log/$NAME
|
||||
|
||||
# make log folders for jobs
|
||||
mkdir -p /var/log/audiomixer-worker
|
||||
mkdir -p /var/log/icecast-worker
|
||||
mkdir -p /var/log/any-job-worker
|
||||
mkdir -p /var/log/scheduler-worker
|
||||
|
||||
# do the same for audiomixer-worker
|
||||
NAME="audiomixer-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/audiomixer-worker
|
||||
chown -R $USER:$GROUP /var/log/icecast-worker
|
||||
chown -R $USER:$GROUP /var/log/any-job-worker
|
||||
chown -R $USER:$GROUP /var/log/scheduler-worker
|
||||
|
|
|
|||
|
|
@ -24,30 +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
|
||||
fi
|
||||
|
|
@ -34,42 +34,4 @@ then
|
|||
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
|
||||
set -e
|
||||
|
|
@ -39,7 +39,7 @@ describe "Music Session", :js => true, :type => :feature, :capybara_feature => t
|
|||
|
||||
describe "abruptly leaves music session" do
|
||||
it "should delete connection and update music session user session history" do
|
||||
#pending
|
||||
pending "still intermittently fails on build server"
|
||||
should have_link('session-leave')
|
||||
page.evaluate_script("JK.JamServer.close(true)")
|
||||
leave_music_session_sleep_delay
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ describe "Session Recordings", :js => true, :type => :feature, :capybara_feature
|
|||
end
|
||||
|
||||
it "discard the recording" do
|
||||
pending "fails intermittently on the build server"
|
||||
in_client(creator) do
|
||||
find('#recording-finished-dialog h1')
|
||||
find('#discard-session-recording').trigger(:click)
|
||||
|
|
@ -145,6 +146,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 +179,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", '')
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ cp ../pb/target/ruby/jampb/jampb-${GEM_VERSION}.gem vendor/cache/ || { echo "una
|
|||
cp ../ruby/jam_ruby-${GEM_VERSION}.gem vendor/cache/ || { echo "unable to copy jam-ruby gem"; exit 1; }
|
||||
|
||||
# put all dependencies into vendor/bundle
|
||||
rm -rf vendor/bundle
|
||||
#rm -rf vendor/bundle -- let checkins config 'wipe workspace' decide this
|
||||
echo "updating dependencies"
|
||||
|
||||
bundle install --path vendor/bundle
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
module JamWebsockets
|
||||
VERSION = "0.0.1"
|
||||
VERSION = "0.1.1"
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue