diff --git a/.gitignore b/.gitignore index 5e26ec47d..134a86d93 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .idea *~ *.swp -web/screenshot*.html -web/screenshot*.png +*/vendor/bundle +*/vendor/cache +HTML +.DS_Store +coverage diff --git a/admin/.simplecov b/admin/.simplecov new file mode 100644 index 000000000..dfe6c4166 --- /dev/null +++ b/admin/.simplecov @@ -0,0 +1,46 @@ +if ENV['COVERAGE'] == "1" + + require 'simplecov-rcov' + class SimpleCov::Formatter::MergedFormatter + def format(result) + SimpleCov::Formatter::HTMLFormatter.new.format(result) + SimpleCov::Formatter::RcovFormatter.new.format(result) + end + end + + SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter + + SimpleCov.start do + add_filter "/test/" + add_filter "/bin/" + add_filter "/scripts/" + add_filter "/tmp/" + add_filter "/vendor/" + add_filter "/spec/" + end + + all_files = Dir['**/*.rb'] + base_result = {} + all_files.each do |file| + absolute = File::expand_path(file) + lines = File.readlines(absolute, :encoding => 'UTF-8') + base_result[absolute] = lines.map do |l| + l.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '') + l.encode!('UTF-8', 'UTF-16') + l.strip! + l.empty? || l =~ /^end$/ || l[0] == '#' ? nil : 0 + end + end + + SimpleCov.at_exit do + coverage_result = Coverage.result + covered_files = coverage_result.keys + covered_files.each do |covered_file| + base_result.delete(covered_file) + end + merged = SimpleCov::Result.new(coverage_result).original_result.merge_resultset(base_result) + result = SimpleCov::Result.new(merged) + result.format! + end + +end diff --git a/admin/Gemfile b/admin/Gemfile index 6a249b8fc..b3b899433 100644 --- a/admin/Gemfile +++ b/admin/Gemfile @@ -1,4 +1,4 @@ -source 'https://rubygems.org' +source 'http://rubygems.org' source 'https://jamjam:blueberryjam@int.jamkazam.com/gems/' devenv = ENV["BUILD_NUMBER"].nil? # Jenkins sets a build number environment variable @@ -11,9 +11,10 @@ else gem 'jam_db', "0.1.#{ENV["BUILD_NUMBER"]}" gem 'jampb', "0.1.#{ENV["BUILD_NUMBER"]}" gem 'jam_ruby', "0.1.#{ENV["BUILD_NUMBER"]}" + ENV['NOKOGIRI_USE_SYSTEM_LIBRARIES'] ||= "true" end -gem 'rails' +gem 'rails', '~> 3.2.11' gem 'bootstrap-sass', '2.0.4' gem 'bcrypt-ruby', '3.0.1' @@ -34,9 +35,10 @@ end gem 'will_paginate', '3.0.3' gem 'bootstrap-will_paginate', '0.0.6' 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' @@ -46,9 +48,15 @@ gem 'unf', '0.1.3' #optional fog dependency gem 'country-select' gem 'aasm', '3.0.16' gem 'postgres-copy', '0.6.0' -gem 'aws-sdk' -gem 'bugsnag' - +gem 'aws-sdk' #, '1.29.1' +gem 'bugsnag' +gem 'gon' +gem 'cocoon' +gem 'haml-rails' +gem 'resque' +gem 'resque-retry' +gem 'resque-failed-job-mailer' +gem 'resque-lonely_job', '~> 1.0.0' gem 'eventmachine', '1.0.3' gem 'amqp', '0.9.8' @@ -57,7 +65,12 @@ gem 'logging-rails', :require => 'logging/rails' gem 'pg_migrate' gem 'ruby-protocol-buffers', '1.2.2' -gem 'sendgrid', '1.1.0' +gem 'sendgrid', '1.2.0' + +gem 'geokit-rails' +gem 'postgres_ext', '1.0.0' +gem 'resque_mailer' +gem 'rest-client' gem 'geokit-rails' gem 'postgres_ext', '1.0.0' @@ -98,4 +111,11 @@ group :development, :test do gem 'factory_girl_rails', '4.1.0' gem 'database_cleaner', '0.7.0' gem 'launchy' + gem 'faker' end + +group :test do + gem 'simplecov', '~> 0.7.1' + gem 'simplecov-rcov' +end + diff --git a/admin/app/admin/bands.rb b/admin/app/admin/bands.rb index 5e7dd2f80..17bcfee13 100644 --- a/admin/app/admin/bands.rb +++ b/admin/app/admin/bands.rb @@ -1,3 +1,7 @@ -ActiveAdmin.register JamRuby::Band, :as => 'Band' do +ActiveAdmin.register JamRuby::Band, :as => 'Band' do + collection_action :autocomplete_band_name, :method => :get + controller do + autocomplete :band, :name, :full => true + end end 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/dashboard.rb b/admin/app/admin/dashboard.rb index 45d0e5054..3a70134aa 100644 --- a/admin/app/admin/dashboard.rb +++ b/admin/app/admin/dashboard.rb @@ -8,7 +8,7 @@ ActiveAdmin.register_page "Dashboard" do span "JamKazam Data Administration Portal" small ul do li "Admin users are users with the admin boolean set to true" - li "Create/Edit JamKazam users using the 'Jam User' menu in header" + li "Invite JamKazam users using the 'Users > Invite' menu in header" li "Admin users are created/deleted when toggling the 'admin' flag for JamKazam users" end end diff --git a/admin/app/admin/email_batch.rb b/admin/app/admin/email_batch.rb new file mode 100644 index 000000000..e5743eeb8 --- /dev/null +++ b/admin/app/admin/email_batch.rb @@ -0,0 +1,127 @@ +ActiveAdmin.register JamRuby::EmailBatch, :as => 'Batch Emails' do + + menu :label => 'Batch Emails', :parent => 'Email' + + config.sort_order = 'updated_at DESC' + config.batch_actions = false + config.clear_action_items! + config.filters = false + + form :partial => 'form' + + action_item :only => [:show] do + link_to('Edit Batch Email', edit_admin_batch_email_path(resource.id)) if resource.can_run_batch? + end + + action_item :only => [:show] do + link_to("Test Batch (#{resource.test_count})", + batch_test_admin_batch_email_path(resource.id), + :confirm => "Run test batch with #{resource.test_count} emails?") if resource.can_run_test? + end + + action_item :only => [:show] do + link_to("Deliver Batch (#{User.email_opt_in.count})", + batch_send_admin_batch_email_path(resource.id), + :confirm => "Run LIVE batch with #{User.email_opt_in.count} emails?") if resource.can_run_batch? + end + + action_item :only => [:show, :edit] do + link_to('Clone Batch Email', batch_clone_admin_batch_email_path(resource.id)) + end + + action_item do + link_to('New Batch Email', new_admin_batch_email_path) + end + + index do + column 'Subject' do |bb| bb.subject end + column 'Created' do |bb| bb.created_at end + column 'From' do |bb| bb.from_email end + column 'Status' do |bb| bb.aasm_state end + column 'Test Emails' do |bb| bb.test_emails end + column 'Email Count' do |bb| bb.opt_in_count end + column 'Sent Count' do |bb| bb.sent_count end + column 'Started' do |bb| bb.started_at end + column 'Completed' do |bb| bb.completed_at end + column 'Send Test' do |bb| + bb.can_run_test? ? link_to("Test Batch (#{bb.test_count})", + batch_test_admin_batch_email_path(bb.id), + :confirm => "Run test batch with #{bb.test_count} emails?") : '' + end + column 'Deliver Live' do |bb| + bb.can_run_batch? ? link_to("Deliver Batch (#{User.email_opt_in.count})", + batch_send_admin_batch_email_path(bb.id), + :confirm => "Run LIVE batch with #{User.email_opt_in.count} emails?") : '' + end + column 'Clone' do |bb| + link_to("Clone", batch_clone_admin_batch_email_path(bb.id)) + end + + default_actions + end + + show :title => 'Batch Email' do |obj| + panel 'Email Contents' do + attributes_table_for obj do + row 'From' do |obj| obj.from_email end + row 'Test Emails' do |obj| obj.test_emails end + row 'Subject' do |obj| obj.subject end + row 'Body' do |obj| obj.body end + end + end + columns do + column do + panel 'Sending Parameters' do + attributes_table_for obj do + row 'State' do |obj| obj.aasm_state end + row 'Opt-in Count' do |obj| obj.opting_in_count end + row 'Sent Count' do |obj| obj.sent_count end + row 'Started' do |obj| obj.started_at end + row 'Completed' do |obj| obj.completed_at end + row 'Updated' do |obj| obj.updated_at end + end + end + end + column do + panel 'Send Chunks' do + table_for(sets = obj.email_batch_sets) do + column :started_at do |sets| sets.started_at.strftime('%b %d %Y, %H:%M') end + column :batch_count do |sets| sets.batch_count end + end + end + end + end + end + + controller do + + def create + batch = EmailBatch.create_with_params(params[:jam_ruby_email_batch]) + set_resource_ivar(batch) + render active_admin_template('show') + end + + def update + resource.update_with_conflict_validation(params[:jam_ruby_email_batch]) + set_resource_ivar(resource) + render active_admin_template('show') + end + + end + + member_action :batch_test, :method => :get do + resource.send_test_batch + redirect_to admin_batch_email_path(resource.id) + end + + member_action :batch_send, :method => :get do + resource.deliver_batch + redirect_to admin_batch_email_path(resource.id) + end + + member_action :batch_clone, :method => :get do + bb = resource.clone + redirect_to edit_admin_batch_email_path(bb.id) + end + +end diff --git a/admin/app/admin/email_error_batch.rb b/admin/app/admin/email_error_batch.rb new file mode 100644 index 000000000..9c4ce9280 --- /dev/null +++ b/admin/app/admin/email_error_batch.rb @@ -0,0 +1,29 @@ +ActiveAdmin.register JamRuby::EmailError, :as => 'Email Errors' do + + menu :label => 'Email Errors', :parent => 'Email' + + config.batch_actions = false + config.filters = false + config.clear_action_items! + + index do + column 'User' do |eerr| + eerr.user ? link_to(eerr.user.name, admin_user_path(eerr.user_id)) : 'N/A' + end + column 'Error Type' do |eerr| eerr.error_type end + column 'Email Address' do |eerr| eerr.email_address end + column 'Status' do |eerr| eerr.status end + column 'Reason' do |eerr| eerr.reason end + column 'Email Date' do |eerr| eerr.email_date end + end + + controller do + + def scoped_collection + @eerrors ||= end_of_association_chain + .includes([:user]) + .order('email_date DESC') + end + end + +end 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/event.rb b/admin/app/admin/event.rb new file mode 100644 index 000000000..186592d30 --- /dev/null +++ b/admin/app/admin/event.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::Event, :as => 'Event' do + menu :parent => 'Events' +end diff --git a/admin/app/admin/event_session.rb b/admin/app/admin/event_session.rb new file mode 100644 index 000000000..df540716d --- /dev/null +++ b/admin/app/admin/event_session.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::EventSession, :as => 'Event Session' do + menu :parent => 'Events' +end diff --git a/admin/app/admin/icecast_admin_authentication.rb b/admin/app/admin/icecast_admin_authentication.rb new file mode 100644 index 000000000..1298409cb --- /dev/null +++ b/admin/app/admin/icecast_admin_authentication.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastAdminAuthentication, :as => 'Admin Authentication' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_bootstrap.rb b/admin/app/admin/icecast_bootstrap.rb new file mode 100644 index 000000000..e07af5f20 --- /dev/null +++ b/admin/app/admin/icecast_bootstrap.rb @@ -0,0 +1,242 @@ +ActiveAdmin.register_page "Bootstrap" do + menu :parent => 'Icecast' + + page_action :create_server, :method => :post do + + template = IcecastTemplate.find_by_id(params[:jam_ruby_icecast_server][:template_id]) + mount_template = IcecastMountTemplate.find_by_id(params[:jam_ruby_icecast_server][:mount_template_id]) + hostname = params[:jam_ruby_icecast_server][:hostname] + + server = IcecastServer.new + server.template = template + server.mount_template = mount_template + server.hostname = hostname + server.server_id = hostname + server.save! + + redirect_to admin_bootstrap_path, :notice => "Server created. If you start a job worker (bundle exec rake all_jobs in /web), it should update your icecast config." + end + + page_action :brew_template, :method => :post do + # to make this template, I just did 'brew install icecast', and then based the rest of this code on what I saw in /usr/local/etc/icecast.xml + + + IcecastServer.transaction do + + + limit = IcecastLimit.new + limit.clients = 100 + limit.sources = 2 + limit.queue_size = 524288 + limit.client_timeout = 30 + limit.header_timeout = 15 + limit.source_timeout = 10 + limit.burst_size = 65535 + limit.save! + + admin_auth = IcecastAdminAuthentication.new + admin_auth.source_pass = 'blueberryjam' + admin_auth.relay_user = 'jamjam' + admin_auth.relay_pass = 'blueberryjam' + admin_auth.admin_user = 'jamjam' + admin_auth.admin_pass = 'blueberryjam' + admin_auth.save! + + path = IcecastPath.new + path.base_dir = '/usr/local/Cellar/icecast/2.3.3/share/icecast' + path.log_dir = '/usr/local/Cellar/icecast/2.3.3/var/log/icecast' + path.web_root = '/usr/local/Cellar/icecast/2.3.3/share/icecast/web' + path.admin_root = '/usr/local/Cellar/icecast/2.3.3/share/icecast/admin' + path.pid_file = nil + path.save! + + security = IcecastSecurity.new + security.chroot = false + security.save! + + logging = IcecastLogging.new + logging.access_log = 'access.log' + logging.error_log = 'error.log' + logging.log_level = 3 # you might want to change this after creating the template + logging.log_size = 10000 + logging.save! + + listen_socket1 = IcecastListenSocket.new + listen_socket1.port = 10000 + listen_socket1.save! + + listen_socket2 = IcecastListenSocket.new + listen_socket2.port = 10001 + listen_socket2.save! + + template = IcecastTemplate.new + template.name = "Brew-#{IcecastTemplate.count + 1}" + template.location = '@work' + template.admin_email = 'nobody@jamkazam.com' + template.fileserve = true + template.limit = limit + template.admin_auth = admin_auth + template.path = path + template.security = security + template.logging = logging + template.listen_sockets = [listen_socket1, listen_socket2] + template.save! + end + + redirect_to admin_bootstrap_path, :notice => "Brew template created. Now, create a mount template." + end + + page_action :ubuntu_template, :method => :post do + # to make this template, I installed icecast233 from jenkins (or our chef'ed apt-repo, same difference), and then based the rest of this code on what I saw in /etc/icecast2/icecast.xml + + IcecastServer.transaction do + + limit = IcecastLimit.new + limit.clients = 100 + limit.sources = 2 + limit.queue_size = 524288 + limit.client_timeout = 30 + limit.header_timeout = 15 + limit.source_timeout = 10 + limit.burst_size = 65535 + limit.save! + + admin_auth = IcecastAdminAuthentication.new + admin_auth.source_pass = 'blueberryjam' + admin_auth.relay_user = 'jamjam' + admin_auth.relay_pass = 'blueberryjam' + admin_auth.admin_user = 'jamjam' + admin_auth.admin_pass = 'blueberryjam' + admin_auth.save! + path = IcecastPath.new + path.base_dir = '/usr/share/icecast2' + path.log_dir = '/var/log/icecast2' + path.web_root = '/usr/share/icecast2/web' + path.admin_root = '/usr/share/icecast2/admin' + path.pid_file = nil + path.save! + + security = IcecastSecurity.new + security.chroot = false + security.save! + + logging = IcecastLogging.new + logging.access_log = 'access.log' + logging.error_log = 'error.log' + logging.log_level = 3 # you might want to change this after creating the template + logging.log_size = 10000 + logging.save! + + listen_socket1 = IcecastListenSocket.new + listen_socket1.port = 10000 + listen_socket1.save! + + listen_socket2 = IcecastListenSocket.new + listen_socket2.port = 10001 + listen_socket2.save! + + template = IcecastTemplate.new + template.name = "Ubuntu-#{IcecastTemplate.count + 1}" + template.location = '@work' + template.admin_email = 'nobody@jamkazam.com' + template.fileserve = true + template.limit = limit + template.admin_auth = admin_auth + template.path = path + template.security = security + template.logging = logging + template.listen_sockets = [listen_socket1, listen_socket2] + template.save! + end + + redirect_to admin_bootstrap_path, :notice => "Ubuntu 12.04 template created. You should also install the icecast233 package: https://int.jamkazam.com/jenkins/job/icecast-debian/" + end + + page_action :create_mount_template, :method => :post do + IcecastServer.transaction do + hostname = params[:jam_ruby_icecast_mount_template][:hostname] + type = params[:jam_ruby_icecast_mount_template][:default_mime_type] + + auth = IcecastUserAuthentication.new + auth.authentication_type = 'url' + auth.mount_add = 'http://' + hostname + '/api/icecast/mount_add' + auth.mount_remove = 'http://' + hostname + '/api/icecast/mount_remove' + auth.listener_add = 'http://' + hostname + '/api/icecast/listener_add' + auth.listener_remove = 'http://' + hostname + '/api/icecast/listener_remove' + auth.auth_header = 'HTTP/1.1 200 OK' + auth.timelimit_header = 'icecast-auth-timelimit:' + auth.save! + + mount_template = IcecastMountTemplate.new + mount_template.name = "#{type}-#{IcecastMountTemplate.count + 1}" + mount_template.source_username = nil # mount will override + mount_template.source_pass = nil # mount will override + mount_template.max_listeners = 20000 # huge + mount_template.max_listener_duration = 3600 * 24 # one day + mount_template.fallback_override = 1 + mount_template.fallback_when_full = 1 + mount_template.is_public = 0 + mount_template.stream_name = nil # mount will override + mount_template.stream_description = nil # mount will override + mount_template.stream_url = nil # mount will override + mount_template.genre = nil # mount will override + mount_template.bitrate = 128 + mount_template.burst_size = 65536 + mount_template.hidden = 1 + mount_template.on_connect = nil + mount_template.on_disconnect = nil + mount_template.authentication = auth + + if type == 'ogg' + mount_template.mp3_metadata_interval = nil + mount_template.mime_type ='audio/ogg' + mount_template.subtype = 'vorbis' + #mount_template.fallback_mount = "/fallback-#{mount_template.bitrate}.ogg" + else + mount_template.mp3_metadata_interval = 4096 + mount_template.mime_type ='audio/mpeg' + mount_template.subtype = nil + #mount_template.fallback_mount = "/fallback-#{mount_template.bitrate}.mp3" + end + mount_template.save! + end + + redirect_to admin_bootstrap_path, :notice => "Mount template created. Create a server now with your new templates specified." + end + + + action_item do + link_to "Create MacOSX (Brew) Template", admin_bootstrap_brew_template_path, :method => :post + end + + action_item do + link_to "Create Ubuntu 12.04 Template", admin_bootstrap_ubuntu_template_path, :method => :post + end + + + content do + + if IcecastTemplate.count == 0 + para "You need to create at least one server template, and one mount template. Click one of the top-left buttons based on your platform" + + elsif IcecastMountTemplate.count == 0 + semantic_form_for IcecastMountTemplate.new, :url => admin_bootstrap_create_mount_template_path, :builder => ActiveAdmin::FormBuilder do |f| + f.inputs "New Mount Template" do + f.input :hostname, :label => "jam-web public hostname:port (such that icecast can reach it)" + f.input :default_mime_type, :as => :select, :collection => ["ogg", "mp3"] + end + f.actions + end + else + semantic_form_for IcecastServer.new, :url => admin_bootstrap_create_server_path, :builder => ActiveAdmin::FormBuilder do |f| + f.inputs "New Icecast Server" do + f.input :hostname, :hint => "Just the icecast hostname; no port" + f.input :template, :hint => "This is the template associated with the server. Not as useful for the 1st server, but subsequent servers can use this same template, and share config" + f.input :mount_template, :hint => "The mount template. When mounts are made as music sessions are created, this template will satisfy templatable values" + end + f.actions + end + end + + end +end diff --git a/admin/app/admin/icecast_directory.rb b/admin/app/admin/icecast_directory.rb new file mode 100644 index 000000000..cb0f959ee --- /dev/null +++ b/admin/app/admin/icecast_directory.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastDirectory, :as => 'Directory' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_limit.rb b/admin/app/admin/icecast_limit.rb new file mode 100644 index 000000000..bbd0f9283 --- /dev/null +++ b/admin/app/admin/icecast_limit.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastLimit, :as => 'Limit' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_listen_socket.rb b/admin/app/admin/icecast_listen_socket.rb new file mode 100644 index 000000000..57fb80d6e --- /dev/null +++ b/admin/app/admin/icecast_listen_socket.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastListenSocket, :as => 'Listener' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_logging.rb b/admin/app/admin/icecast_logging.rb new file mode 100644 index 000000000..2465aa0ec --- /dev/null +++ b/admin/app/admin/icecast_logging.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastLogging, :as => 'Logging' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_master_server_relay.rb b/admin/app/admin/icecast_master_server_relay.rb new file mode 100644 index 000000000..c458d2dbd --- /dev/null +++ b/admin/app/admin/icecast_master_server_relay.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastMasterServerRelay, :as => 'Master Server Relay' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_mount.rb b/admin/app/admin/icecast_mount.rb new file mode 100644 index 000000000..f8de558d2 --- /dev/null +++ b/admin/app/admin/icecast_mount.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastMount, :as => 'Mount' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_mount_template.rb b/admin/app/admin/icecast_mount_template.rb new file mode 100644 index 000000000..3a369da11 --- /dev/null +++ b/admin/app/admin/icecast_mount_template.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastMountTemplate, :as => 'IcecastMountTemplate' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_path.rb b/admin/app/admin/icecast_path.rb new file mode 100644 index 000000000..c44eaadb5 --- /dev/null +++ b/admin/app/admin/icecast_path.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastPath, :as => 'Path' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_relay.rb b/admin/app/admin/icecast_relay.rb new file mode 100644 index 000000000..96b1946a2 --- /dev/null +++ b/admin/app/admin/icecast_relay.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastRelay, :as => 'Relay' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_security.rb b/admin/app/admin/icecast_security.rb new file mode 100644 index 000000000..a074cae6d --- /dev/null +++ b/admin/app/admin/icecast_security.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastSecurity, :as => 'Security' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_server.rb b/admin/app/admin/icecast_server.rb new file mode 100644 index 000000000..08b8e4f7e --- /dev/null +++ b/admin/app/admin/icecast_server.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastServer, :as => 'Server' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_server_group.rb b/admin/app/admin/icecast_server_group.rb new file mode 100644 index 000000000..2c560996d --- /dev/null +++ b/admin/app/admin/icecast_server_group.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastServerGroup, :as => 'IcecastServerGroup' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_server_mount.rb b/admin/app/admin/icecast_server_mount.rb new file mode 100644 index 000000000..2b6badd9b --- /dev/null +++ b/admin/app/admin/icecast_server_mount.rb @@ -0,0 +1,4 @@ +ActiveAdmin.register JamRuby::IcecastServerMount, :as => 'ServerMounts' do + menu :parent => 'Icecast' + +end diff --git a/admin/app/admin/icecast_server_relay.rb b/admin/app/admin/icecast_server_relay.rb new file mode 100644 index 000000000..d3f0e8b5b --- /dev/null +++ b/admin/app/admin/icecast_server_relay.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastServerRelay, :as => 'ServerRelays' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_server_socket.rb b/admin/app/admin/icecast_server_socket.rb new file mode 100644 index 000000000..70479b991 --- /dev/null +++ b/admin/app/admin/icecast_server_socket.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastServerSocket, :as => 'ServerListenSockets' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_template.rb b/admin/app/admin/icecast_template.rb new file mode 100644 index 000000000..30ea716d0 --- /dev/null +++ b/admin/app/admin/icecast_template.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastTemplate, :as => 'Template' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_template_socket.rb b/admin/app/admin/icecast_template_socket.rb new file mode 100644 index 000000000..beb5c96a5 --- /dev/null +++ b/admin/app/admin/icecast_template_socket.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastTemplateSocket, :as => 'TemplateListenSockets' do + menu :parent => 'Icecast' +end diff --git a/admin/app/admin/icecast_user_authentication.rb b/admin/app/admin/icecast_user_authentication.rb new file mode 100644 index 000000000..945748700 --- /dev/null +++ b/admin/app/admin/icecast_user_authentication.rb @@ -0,0 +1,3 @@ +ActiveAdmin.register JamRuby::IcecastUserAuthentication, :as => 'User Authentication' do + menu :parent => 'Icecast' +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..fa2ae8051 100644 --- a/admin/app/admin/jam_ruby_users.rb +++ b/admin/app/admin/jam_ruby_users.rb @@ -1,6 +1,9 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do - menu :label => 'Jam User' + + collection_action :autocomplete_user_email, :method => :get + + menu :label => 'Users', :parent => 'Users' config.sort_order = 'created_at DESC' @@ -11,7 +14,8 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do filter :created_at filter :updated_at - form do |ff| + + form do |ff| ff.inputs "Details" do ff.input :email ff.input :admin @@ -69,7 +73,7 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do column :admin column :updated_at column :created_at - column :musician + column :musician do |user| user.musician? ? true : false end column :city column :state column :country @@ -95,6 +99,13 @@ ActiveAdmin.register JamRuby::User, :as => 'Users' do controller do + # this actually searches on first name, last name, and email, because of get_autocomplete_items defined below + autocomplete :user, :email, :full => true, :display_value => :autocomplete_display_name + + def get_autocomplete_items(parameters) + items = User.select("DISTINCT email, first_name, last_name, id").where(["email ILIKE ? OR first_name ILIKE ? OR last_name ILIKE ?", "%#{parameters[:term]}%", "%#{parameters[:term]}%", "%#{parameters[:term]}%"]) + end + def create @jam_ruby_user = JamRuby::User.new(params[:jam_ruby_user]) @jam_ruby_user.administratively_created = true 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..d4fb59a1b 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 @@ -23,7 +25,7 @@ ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History index :as => :block do |msh| div :for => msh do h3 "Session ##{msh.music_session_id}: #{msh.created_at.strftime('%b %d %Y, %H:%M')}" - h4 "(append URL with ?admin=0 to hide admin sessions)" + h4 "(append URL with ?admin=1 to show admin sessions)" columns do column do panel 'Session Details' do diff --git a/admin/app/admin/promo_buzz.rb b/admin/app/admin/promo_buzz.rb new file mode 100644 index 000000000..b3fc90514 --- /dev/null +++ b/admin/app/admin/promo_buzz.rb @@ -0,0 +1,68 @@ +ActiveAdmin.register JamRuby::PromoBuzz, :as => 'Buzz' do + + menu :label => 'Buzz', :parent => 'Home Page' + + config.sort_order = 'position ASC aasm_state DESC updated_at DESC' + config.batch_actions = false + # config.clear_action_items! + config.filters = false + + form :partial => 'form' + + index do + column 'Who?' do |pp| pp.text_short end + column 'Image' do |pp| + image_tag(pp.image_url, :size => '50x50') + end + column 'Quote' do |pp| pp.text_long[0..256] end + column 'State' do |pp| pp.aasm_state end + column 'Position' do |pp| pp.position end + column 'Updated' do |pp| pp.updated_at end + default_actions + end + + show do + attributes_table do + row 'Who?' do |obj| obj.text_short end + row 'Quote' do |obj| obj.text_long end + row :image do |obj| + image_tag(obj.image_url, :size => '50x50') + end + row 'State' do |obj| obj.aasm_state end + row 'Position' do |obj| obj.position end + row 'Updated' do |obj| obj.updated_at end + end + end + + controller do + + def new + @promo = JamRuby::PromoBuzz.new + @promo.key = params[:key] if params[:key].present? + @promo.aasm_state = 'active' + @uploader = @promo.image + @uploader.success_action_redirect = new_admin_buzz_url + super + end + + def create + promo = PromoBuzz.create_with_params(params[:jam_ruby_promo_buzz]) + redirect_to admin_buzzs_path + end + + def edit + @promo = resource + @promo.key = params[:key] if params[:key].present? && params[:key] != @promo.key + @uploader = @promo.image + @uploader.success_action_redirect = edit_admin_buzz_url(@promo) + super + end + + def update + resource.update_with_params(params[:jam_ruby_promo_buzz]).save! + redirect_to admin_buzzs_path + end + + end + +end diff --git a/admin/app/admin/promo_latest.rb b/admin/app/admin/promo_latest.rb new file mode 100644 index 000000000..ec0c593ba --- /dev/null +++ b/admin/app/admin/promo_latest.rb @@ -0,0 +1,56 @@ +ActiveAdmin.register JamRuby::PromoLatest, :as => 'Latest' do + + menu :label => 'Latest', :parent => 'Home Page' + + config.batch_actions = false + config.sort_order = '' + # config.clear_action_items! + config.filters = false + + form :partial => 'form' + + index do + column 'Latest' do |pp| pp.latest_display_name end + column 'Latest ID' do |pp| pp.latest_id end + column 'State' do |pp| pp.aasm_state end + column 'Position' do |pp| pp.position end + column 'Updated' do |pp| pp.updated_at end + default_actions + end + + show do + attributes_table do + row 'Latest' do |pp| pp.latest_display_name end + row 'State' do |obj| obj.aasm_state end + row 'Position' do |obj| obj.position end + row 'Updated' do |obj| obj.updated_at end + end + end + + controller do + + def new + @promo = JamRuby::PromoLatest.new + @promo.aasm_state = 'active' + super + end + + def create + promo = PromoLatest.create_with_params(params[:jam_ruby_promo_latest]) + redirect_to admin_latests_path + end + + def edit + @promo = resource + super + end + + def update + resource.update_with_params(params[:jam_ruby_promo_latest]).save! + redirect_to admin_latests_path + end + + end + + +end diff --git a/admin/app/admin/recordings.rb b/admin/app/admin/recordings.rb new file mode 100644 index 000000000..eb0ac1fc1 --- /dev/null +++ b/admin/app/admin/recordings.rb @@ -0,0 +1,61 @@ +ActiveAdmin.register JamRuby::Recording, :as => 'Recording' do + + menu :label => 'Recording', :parent => 'Recordings' + + config.sort_order = 'DESC updated_at' + config.batch_actions = false + # config.clear_action_items! + config.filters = false + + form :partial => 'form' + + controller do + + def initialize_client_tokens(params) + + recording = params[:jam_ruby_recording] + return params unless recording + + recorded_tracks = recording[:recorded_tracks_attributes] + return params unless recorded_tracks + + recorded_tracks.each do |key, recorded_track| + recorded_track[:client_id] = nil if recorded_track[:client_id] == "" + recorded_track[:client_track_id] = nil if recorded_track[:client_track_id] == "" + recorded_track[:track_id] = nil if recorded_track[:track_id] == "" + + recorded_track[:client_id] ||= recorded_track[:user_id] if recorded_track[:user_id] + recorded_track[:client_track_id] ||= SecureRandom.uuid + recorded_track[:track_id] ||= SecureRandom.uuid + end + + params + end + + def new + @recording = JamRuby::Recording.new + + super + end + + def create + params.merge! initialize_client_tokens(params) + create! + end + + def edit + @recording = resource + super + end + + def update + params.merge! initialize_client_tokens(params) + + update! do |format| + format.html { redirect_to edit_admin_recording_url(params[:jam_ruby_recording]) } + end + end + end + + +end 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 new file mode 100644 index 000000000..6ea4bb285 --- /dev/null +++ b/admin/app/admin/user_progression.rb @@ -0,0 +1,89 @@ +ActiveAdmin.register JamRuby::User, :as => 'User Progression' do + PROGRESSION_DATE = '%Y-%m-%d %H:%M' unless defined?(PROGRESSION_DATE) + + menu :label => 'Progression', :parent => 'Users' + + config.sort_order = 'updated_at DESC' + config.batch_actions = false + config.clear_action_items! + config.filters = false + + index do + column :email do |user| link_to(truncate(user.email, {:length => 12}), resource_path(user), {:title => "#{user.first_name} #{user.last_name} (#{user.email})"}) end + column :updated_at do |uu| uu.updated_at.strftime(PROGRESSION_DATE) end + column :created_at do |uu| uu.created_at.strftime(PROGRESSION_DATE) end + column :city + column :musician + column 'Client DL' do |uu| + if dd = uu.first_downloaded_client_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Client Run' do |uu| + if dd = uu.first_ran_client_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Certified Gear' do |uu| + if dd = uu.first_certified_gear_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Any Session' do |uu| + if dd = uu.first_music_session_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Real Session' do |uu| + if dd = uu.first_real_music_session_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Good Session' do |uu| + if dd = uu.first_good_music_session_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Invited' do |uu| + if dd = uu.first_invited_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Friended' do |uu| + if dd = uu.first_friended_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Recorded' do |uu| + if dd = uu.first_recording_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + column 'Promoted' do |uu| + if dd = uu.first_social_promoted_at + dd.strftime(PROGRESSION_DATE) + else + '' + end + end + end + +end diff --git a/admin/app/assets/javascripts/active_admin.js b/admin/app/assets/javascripts/active_admin.js index 7498ec940..088012d98 100644 --- a/admin/app/assets/javascripts/active_admin.js +++ b/admin/app/assets/javascripts/active_admin.js @@ -1,2 +1,14 @@ -//= 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 +// require jquery.ui.core +// require jquery.ui.widget +// require jquery.ui.datepicker +// require jquery.ui.dialog +// require jquery.ui.autocomplete +//= require cocoon +//= 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('
<%= f.file_field :image %>
+<%= f.submit "Upload Image", :id => :submit_buzz_img %>
+ <% end %> +<% end %> +<%= semantic_form_for([:admin, @promo], :html => {:multipart => true}, :url => @promo.new_record? ? admin_buzzs_path : "/admin/buzzs/#{@promo.id}") do |f| %> + <%= f.inputs do %> + <%= f.input(:text_short, :label => "Who?", :input_html => {:maxlength => 512}) %> + <%= f.input(:text_long, :label => "Quote", :input_html => {:rows => 3, :maxlength => 4096}) %> + <%= f.input(:position, :label => "Position", :input_html => {:maxlength => 4}) %> + <%= f.input(:aasm_state, :as => :select, :collection => Promotional::STATES, :label => 'Status') %> + Image File: <%= @promo.image_name %> + <%= f.hidden_field :key %> + <% # = f.input(:photo, :as => :file, :hint => f.template.image_tag(@promo.image_url(:thumb), :size => '50x50')) if @promo.new_record? %> + <% end %> + <% if @promo.image_name.present? %> + <%= f.actions %> + <% end %> +<% end %> diff --git a/admin/app/views/admin/latests/_form.html.erb b/admin/app/views/admin/latests/_form.html.erb new file mode 100644 index 000000000..869c9e8d3 --- /dev/null +++ b/admin/app/views/admin/latests/_form.html.erb @@ -0,0 +1,11 @@ +<%= semantic_form_for([:admin, @promo], :html => {:multipart => true}, :url => @promo.new_record? ? admin_latests_path : "/admin/latests/#{@promo.id}") do |f| %> + <%= f.inputs :name => "Recording or Session", :for => :latest do |latest_form| %> + <%= f.input(:latest_id, :label => "Unique ID (Recording or Session)", :input_html => {:maxlength => 128}) %> + <% #= latest_form.input :id, :as => :select, :collection => @latests.collect { |ll| [ll[:name], ll[:id]] }, :label => "Latest", :required => true, :selected => @promo.latest.try(:id) %> + <% end %> + <%= f.inputs do %> + <%= f.input(:position, :label => "Position", :input_html => {:maxlength => 4}) %> + <%= f.input(:aasm_state, :as => :select, :collection => Promotional::STATES, :label => 'Status') %> + <% end %> + <%= f.actions %> +<% end %> diff --git a/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml b/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml new file mode 100644 index 000000000..6a68db880 --- /dev/null +++ b/admin/app/views/admin/recordings/_claimed_recording_fields.html.haml @@ -0,0 +1,15 @@ += f.inputs name: 'Claimed Recording' do + %ol.nested-fields + = f.input :name, :hint => 'This is entered in the post-recording dialog. It will be displayed in jam-web.' + = f.input :description, :hint => 'This is entered in the post-recording dialog. It will be displayed in jam-web.' + = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { id: "jam_ruby_claimed_recording_user_id", name: "", id_element: "#WILL_BE_OVERRIDDEN_BY_JS_IN_RECORDED_FORM" } + = f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_claimed_recording[user_id]" } + = f.input :genre, collection: Genre.all, :member_label => :description + = f.input :is_public + = link_to_remove_association "Delete Claimed Recording", f, class: 'button', style: 'margin-left:10px' + + %div{style: 'display:none'} + + + + diff --git a/admin/app/views/admin/recordings/_form.html.haml b/admin/app/views/admin/recordings/_form.html.haml new file mode 100644 index 000000000..2c1bb2ce0 --- /dev/null +++ b/admin/app/views/admin/recordings/_form.html.haml @@ -0,0 +1,65 @@ +%h2 Instructions +%h3 Overview +%p Make each recorded track first, then the mix, and then finally the claimed recordings. +%h3 Entering users and bands +%p Autocomplete is used to supply users and bands. Just starting typing and pick from the resulting options. +%h3 Adding Tracks and Mixes +%p To add a track or mix, you first click 'Add track' or 'Add mix', and fill out any values present. However, to upload an ogg file for a mix or track, you must first click 'Update Recording' after you initially click 'Add Track/Mix'. When the form re-displays after the update, you will then seen an upload file input. Finally, after you have uploaded an ogg file, you can then click the Download link to verify your ogg file, or mp3, in the case of mixes. +%h4 Specific to Mixes +%ul + %li When you first click 'Add Mix', there is nothing to fill out. So click 'Add Mix', then click 'Update Recording'. The page will prompt you, as well. + %li When you upload a mix ogg file, it will be converted to mp3 too. This makes the request take a little bit of time. Just wait it out. +%h3 Add Claimed Recordings +%p Once your recorded tracks are added, you then want to add one Claimed Recording for each user you want to have access to the recording. Making a claimed recording is basically making a recording 'visible' for a given user. The user must have a recorded track to have a claimed recording. +%h3 Validations +%p It should not be possible to create an invalid recording/track/mix/claim; there are a great deal of validations that will prevent you from doing something invalid. If you find otherwise, please fill out a JIRA . + += semantic_form_for([:admin, @recording], :html => {:multipart => true}, :url => @recording.new_record? ? admin_recordings_path : "#{ENV['RAILS_RELATIVE_URL_ROOT']}/admin/recordings/#{@recording.id}") do |f| + = f.semantic_errors *f.object.errors.keys + = f.inputs name: 'Recording Fields' do + + = f.input :name, :hint => 'something to remember this recording by. This is used solely for display in jam-admin; nowhere else.' + + = f.input :owner, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { :id => "jam_ruby_recording_owner", :name => "", :id_element => "#jam_ruby_recording_owner_id" } + = f.input :owner_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[owner_id]" } + + = f.input :band, :as => :autocomplete, :url => autocomplete_band_name_admin_bands_path, :input_html => { :id => "jam_ruby_recording_band", :name => "", :id_element => "#jam_ruby_recording_band_id" } + = f.input :band_id, :as => :hidden, :input_html => { :name => "jam_ruby_recording[band_id]" } + + = f.input :duration, :hint => 'how long the recording is (in seconds)' + + = f.semantic_fields_for :recorded_tracks do |recorded_track, index| + = render 'recorded_track_fields', f: recorded_track + .links + = link_to_add_association 'Add Track', f, :recorded_tracks, class: 'button', style: 'margin:20px;padding:10px 20px' + + = f.semantic_fields_for :mixes do |mix, index| + = render 'mix_fields', f: mix + .links + = link_to_add_association 'Add Mix', f, :mixes, class: 'button', style: 'margin:20px; padding:10px 20px' + + = f.semantic_fields_for :claimed_recordings do |claimed_recording, index| + = render 'claimed_recording_fields', f: claimed_recording + .links + = link_to_add_association 'Add Claimed Recording', f, :claimed_recordings, class: 'button', style: 'margin:20px; padding:10px 20px' + + = f.actions + + +:javascript + $(document).ready( function() { + $('body').on('cocoon:before-insert', function(e, insertedItem) { + + // handle recorded tracks + var idForHiddenUserId = $('input[class="jam_ruby_recorded_track[user_id]"]', insertedItem).attr('id'); + if(idForHiddenUserId) { + $('input[id="jam_ruby_recorded_track_user_id"]', insertedItem).attr('data-id-element', '#' + idForHiddenUserId) + } + + // handle claimed recordings + idForHiddenUserId = $('input[class="jam_ruby_claimed_recording[user_id]"]', insertedItem).attr('id'); + if(idForHiddenUserId) { + $('input[id="jam_ruby_claimed_recording_user_id"]', insertedItem).attr('data-id-element', '#' + idForHiddenUserId) + } + }); + }); diff --git a/admin/app/views/admin/recordings/_mix_fields.html.haml b/admin/app/views/admin/recordings/_mix_fields.html.haml new file mode 100644 index 000000000..6d8c96b8b --- /dev/null +++ b/admin/app/views/admin/recordings/_mix_fields.html.haml @@ -0,0 +1,22 @@ += f.inputs name: 'Mix' do + %ol.nested-fields + - if f.object.new_record? + %p{style: 'margin-left:10px'} + %i before you can upload, you must select 'Update Recording' + - else + = f.input :ogg_url, :as => :file + .current_file_holder{style: 'margin-bottom:10px'} + - unless f.object.nil? || f.object[:ogg_url].nil? + %a{href: f.object.sign_url(3600, 'ogg'), style: 'padding:0 0 0 20px'} Download OGG + - unless f.object.nil? || f.object[:mp3_url].nil? + %a{href: f.object.sign_url(3600, 'mp3'), style: 'padding:0 0 0 20px'} Download MP3 + + %div{style: 'display:none'} + = f.input :should_retry, :as => :hidden, :input_html => {:value => '0' } + + = link_to_remove_association "Delete Mix", f, class: 'button', style: 'margin-left:10px' + + + + + diff --git a/admin/app/views/admin/recordings/_recorded_track_fields.html.haml b/admin/app/views/admin/recordings/_recorded_track_fields.html.haml new file mode 100644 index 000000000..617f50dbe --- /dev/null +++ b/admin/app/views/admin/recordings/_recorded_track_fields.html.haml @@ -0,0 +1,25 @@ += f.inputs name: 'Track' do + + %ol.nested-fields + = f.input :user, :as => :autocomplete, :url => autocomplete_user_email_admin_users_path, :input_html => { id: "jam_ruby_recorded_track_user_id", name: "", id_element: "#WILL_BE_OVERRIDDEN_BY_JS_IN_RECORDED_FORM" } + = f.input :user_id, :as => :hidden, :input_html => { class: "jam_ruby_recorded_track[user_id]" } + = f.input :instrument, collection: Instrument.all + = f.input :sound, :as => :select, collection: options_for_select(RecordedTrack::SOUND, 'stereo') + + - if f.object.new_record? + %i before you can upload, you must select 'Update Recording' + - else + = f.input :url, :as => :file + - unless f.object.nil? || f.object[:url].nil? + .current_file_holder{style: 'margin-bottom:10px'} + %a{href: f.object.sign_url(3600), style: 'padding:0 0 0 20px'} Download + + %div{style: 'display:none'} + = f.input :client_id, as: :hidden + = f.input :track_id, as: :hidden + = f.input :client_track_id, as: :hidden + + = link_to_remove_association "Delete Track", f, class: 'button', style: 'margin-left:10px' + + + diff --git a/admin/build b/admin/build index 4064b6082..64c48f159 100755 --- a/admin/build +++ b/admin/build @@ -22,10 +22,10 @@ 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 +#bundle update if [ "$?" = "0" ]; then echo "success: updated dependencies" @@ -74,7 +74,7 @@ EOF set -e # cache all gems local, and tell bundle to use local gems only - bundle install --path vendor/bundle --local + #bundle install --path vendor/bundle --local # prepare production acssets rm -rf $DIR/public/assets bundle exec rake assets:precompile RAILS_ENV=production diff --git a/admin/config/application.rb b/admin/config/application.rb index 5b76766e9..36a91e1a5 100644 --- a/admin/config/application.rb +++ b/admin/config/application.rb @@ -16,6 +16,9 @@ end include JamRuby +User = JamRuby::User +Band = JamRuby::Band + module JamAdmin class Application < Rails::Application @@ -33,7 +36,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']}/assets" # 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. @@ -52,6 +55,9 @@ module JamAdmin # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true + # suppress locale complaint: http://stackoverflow.com/questions/20361428/rails-i18n-validation-deprecation-warning + config.i18n.enforce_available_locales = false + # Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types @@ -72,15 +78,48 @@ module JamAdmin # to make active_admin assets precompile config.assets.precompile += ['active_admin.css', 'active_admin.js', 'active_admin/print.css'] + ###### THESE ARE JAM-WEB VALUES + config.external_hostname = ENV['EXTERNAL_HOSTNAME'] || 'localhost' + config.external_port = ENV['EXTERNAL_PORT'] || 3000 + config.external_protocol = ENV['EXTERNAL_PROTOCOL'] || 'http://' + config.external_root_url = "#{config.external_protocol}#{config.external_hostname}#{(config.external_port == 80 || config.external_port == 443) ? '' : ':' + config.external_port.to_s}" + + # set to false to instead use amazon. You will also need to supply amazon secrets - config.store_artifacts_to_disk = true + config.store_artifacts_to_disk = false + #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 + + config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398' + config.facebook_app_secret = ENV['FACEBOOK_APP_SECRET'] || '546a5b253972f3e2e8b36d9a3dd5a06e' + + config.twitter_app_id = ENV['TWITTER_APP_ID'] || 'nQj2oEeoJZxECC33tiTuIg' + config.twitter_app_secret = ENV['TWITTER_APP_SECRET'] || 'Azcy3QqfzYzn2fsojFPYXcn72yfwa0vG6wWDrZ3KT8' + + config.ffmpeg_path = ENV['FFMPEG_PATH'] || (File.exist?('/usr/local/bin/ffmpeg') ? '/usr/local/bin/ffmpeg' : '/usr/bin/ffmpeg') + + config.max_audio_downloads = 100 end end diff --git a/admin/config/boot.rb b/admin/config/boot.rb index 2b59194e5..56e91c277 100644 --- a/admin/config/boot.rb +++ b/admin/config/boot.rb @@ -12,7 +12,9 @@ module Rails class Server alias :default_options_alias :default_options def default_options - default_options_alias.merge!(:Port => 3333) + default_options_alias.merge!( + :Port => 3333 + ENV['JAM_INSTANCE'].to_i, + :pid => File.expand_path("tmp/pids/server-#{ENV['JAM_INSTANCE'].to_i}.pid")) end end end \ No newline at end of file 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/environments/test.rb b/admin/config/environments/test.rb index 79a74c4ac..6a51a23eb 100644 --- a/admin/config/environments/test.rb +++ b/admin/config/environments/test.rb @@ -34,4 +34,10 @@ JamAdmin::Application.configure do # Print deprecation notices to the stderr config.active_support.deprecation = :stderr + + config.facebook_app_id = '1441492266082868' + config.facebook_app_secret = '233bd040a07e47dcec1cff3e490bfce7' + + config.twitter_app_id = 'e7hGc71gmcBgo6Wvdta6Sg' + config.twitter_app_secret = 'PfG1jAUMnyrimPcDooUVQaJrG1IuDjUyGg5KciOo' end diff --git a/admin/config/initializers/active_admin.rb b/admin/config/initializers/active_admin.rb index 1b7899669..7894eed15 100644 --- a/admin/config/initializers/active_admin.rb +++ b/admin/config/initializers/active_admin.rb @@ -2,9 +2,15 @@ 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 +module ActiveAdmin + class BaseController + with_role :admin + end +end ActiveAdmin.setup do |config| @@ -159,4 +165,11 @@ ActiveAdmin.setup do |config| # config.csv_options = {} config.view_factory.footer = Footer + + config.register_javascript 'autocomplete-rails.js' + config.register_stylesheet 'jquery.ui.theme.css' + + config.authorization_adapter = "AdminAuthorization" + end + diff --git a/admin/config/initializers/carrierwave.rb b/admin/config/initializers/carrierwave.rb index 8a3a54052..888373e84 100644 --- a/admin/config/initializers/carrierwave.rb +++ b/admin/config/initializers/carrierwave.rb @@ -4,20 +4,9 @@ CarrierWave.root = Rails.root.join(Rails.public_path).to_s CarrierWave.base_path = ENV['RAILS_RELATIVE_URL_ROOT'] CarrierWave.configure do |config| - if JamAdmin::Application.config.store_artifacts_to_disk - config.storage = :file - else - 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, - } - config.fog_directory = JamAdmin::Application.config.aws_artifact_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 {} - end + + config.storage = Rails.application.config.store_artifacts_to_disk ? :file : :fog + JamRuby::UploaderConfiguration.set_aws_private_configuration(config) end require 'carrierwave/orm/activerecord' diff --git a/admin/config/initializers/email.rb b/admin/config/initializers/email.rb index 8b6bb118f..41e1651d0 100644 --- a/admin/config/initializers/email.rb +++ b/admin/config/initializers/email.rb @@ -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 } \ No newline at end of file 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/jam_ruby/promotional.rb b/admin/config/initializers/jam_ruby/promotional.rb new file mode 100644 index 000000000..7d58bf09d --- /dev/null +++ b/admin/config/initializers/jam_ruby/promotional.rb @@ -0,0 +1,3 @@ +class JamRuby::PromoBuzz < JamRuby::Promotional + mount_uploader :image, ImageUploader +end diff --git a/admin/config/initializers/jam_ruby_user.rb b/admin/config/initializers/jam_ruby_user.rb index dfaebced6..75d18197d 100644 --- a/admin/config/initializers/jam_ruby_user.rb +++ b/admin/config/initializers/jam_ruby_user.rb @@ -25,14 +25,6 @@ end end - def country - @country = "United States" - end - - def musician - @musician = true - end - def confirm_url @signup_confirm_url ||= CONFIRM_URL end 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 ebc1b9790..05aed06bc 100644 --- a/admin/config/routes.rb +++ b/admin/config/routes.rb @@ -1,3 +1,7 @@ +require 'resque/server' +require 'resque-retry' +require 'resque-retry/server' + JamAdmin::Application.routes.draw do # ActiveAdmin::Devise.config, @@ -5,12 +9,32 @@ JamAdmin::Application.routes.draw do devise_for :users, :class_name => "JamRuby::User", :path_prefix => '/admin', :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'} + + scope ENV['RAILS_RELATIVE_URL_ROOT'] || '/' do root :to => "admin/dashboard#index" + namespace :admin do + resources :users do + get :autocomplete_user_email, :on => :collection + end + end + + namespace :admin do + resources :bands do + get :autocomplete_band_name, :on => :collection + end + end + 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" + # The priority is based upon order of creation: # first created -> highest priority. diff --git a/admin/config/unicorn.rb b/admin/config/unicorn.rb index 6a901300b..de93769c2 100644 --- a/admin/config/unicorn.rb +++ b/admin/config/unicorn.rb @@ -32,7 +32,7 @@ listen 3100, :tcp_nopush => true timeout 30 # feel free to point this anywhere accessible on the filesystem -pid "/var/run/jam-admin.pid" +pid "/var/run/jam-admin/jam-admin.pid" # By default, the Unicorn logger will write to stderr. # Additionally, ome applications/frameworks log to stderr or stdout, diff --git a/admin/jenkins b/admin/jenkins index 67733e8c2..9a8e7e5b8 100755 --- a/admin/jenkins +++ b/admin/jenkins @@ -7,20 +7,6 @@ echo "starting build..." if [ "$?" = "0" ]; then echo "build succeeded" - - if [ ! -z "$PACKAGE" ]; then - echo "publishing ubuntu package (.deb)" - DEBPATH=`find target/deb -name *.deb` - DEBNAME=`basename $DEBPATH` - - curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME - - if [ "$?" != "0" ]; then - echo "deb publish failed" - exit 1 - fi - echo "done publishing deb" - fi else echo "build failed" exit 1 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/admin/lib/utils.rb b/admin/lib/utils.rb index aa92de6f7..4af46d734 100644 --- a/admin/lib/utils.rb +++ b/admin/lib/utils.rb @@ -3,4 +3,5 @@ module Utils chars = ((('a'..'z').to_a + ('0'..'9').to_a) - %w(i o 0 1 l 0)) (1..size).collect{|a| cc = chars[rand(chars.size)]; 0==rand(2) ? cc.upcase : cc }.join end + end diff --git a/admin/script/package/jam-admin.conf b/admin/script/package/jam-admin.conf index 7c5fbc998..90e39314c 100644 --- a/admin/script/package/jam-admin.conf +++ b/admin/script/package/jam-admin.conf @@ -4,4 +4,10 @@ start on startup start on runlevel [2345] stop on runlevel [016] -exec start-stop-daemon --start --chdir /var/lib/jam-admin --exec /var/lib/jam-admin/script/package/upstart-run.sh +pre-start script + set -e + mkdir -p /var/run/jam-admin + chown jam-admin:jam-admin /var/run/jam-admin +end script + +exec start-stop-daemon --start --chuid jam-admin:jam-admin --chdir /var/lib/jam-admin --exec /var/lib/jam-admin/script/package/upstart-run.sh diff --git a/admin/spec/factories.rb b/admin/spec/factories.rb index 438107c40..227ce212f 100644 --- a/admin/spec/factories.rb +++ b/admin/spec/factories.rb @@ -9,7 +9,7 @@ FactoryGirl.define do musician true city "Apex" state "NC" - country "USA" + country "US" terms_of_service true diff --git a/admin/spec/spec_helper.rb b/admin/spec/spec_helper.rb index 7bded3dc9..f7ddad41a 100644 --- a/admin/spec/spec_helper.rb +++ b/admin/spec/spec_helper.rb @@ -1,6 +1,5 @@ - ENV["RAILS_ENV"] ||= 'test' - +require 'simplecov' # provision database require 'active_record' diff --git a/build b/build new file mode 100755 index 000000000..e5a50d463 --- /dev/null +++ b/build @@ -0,0 +1,135 @@ +#!/bin/bash + +# RUN_SLOW_TESTS, RUN_AWS_TESTS, SKIP_KARMA=1 SHOW_JS_ERRORS=1 PACKAGE=1 +# WORKSPACE=/var/lib/jenkins/jobs/jam-web/workspace + +set -e + +export BUNDLE_JOBS=1 # 6, which i want to use, makes the whole server crawl + +echo "" + +echo "BUILDING JAM-DB" +pushd db > /dev/null + ./jenkins +popd > /dev/null + +echo "" + +echo "BUILDING JAM-PB" +pushd pb > /dev/null +bash -l ./jenkins +popd > /dev/null + +echo "" + +echo "BUILDING JAM-RUBY" +pushd ruby > /dev/null +rm -f *.gem +bash -l ./jenkins +popd > /dev/null + +echo "" + +echo "BUILDING WEBSOCKET GATEWAY" +pushd websocket-gateway > /dev/null +bash -l ./jenkins +popd > /dev/null + +echo "" + +echo "BUILDING JAM-WEB" +pushd web > /dev/null +echo "kill any stuck rspec tests from previous run. need to debug how/why this happens on build server" +set +e +ps aux | grep -ie "jam-cloud.*rspec" | awk '{print $2}' | xargs kill -9 +set -e + +PACKAGE=1 bash ./jenkins + +# we do this so that the build won't fail in jenkins if no capybara error screenshot isn't there +mkdir -p tmp/capybara +touch tmp/capybara/success.png +popd > /dev/null + +echo "" + +echo "BUILDING JAM-ADMIN" +pushd admin /dev/null +bash -l ./jenkins +popd > /dev/null + + +if [ ! -z "$PACKAGE" ]; then + +DEB_SERVER=http://localhost:9010/apt-`uname -p` +GEM_SERVER=http://localhost:9000/gems + + # if still going, then push all debs up + if [[ "$GIT_BRANCH" == *develop* || "$GIT_BRANCH" == *master* || "$GIT_BRANCH" == *release* ]]; then + + echo "" + echo "PUSHING DB ARTIFACTS" + pushd db > /dev/null + echo "publishing ubuntu packages (.deb)" + for f in `find target -name '*.deb'`; do + DEBNAME=`basename $f` + DEBPATH="$f" + echo "publishing $DEBPATH to deb server" + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + if [ "$?" != "0" ]; then + echo "deb publish failed of $DEBPATH" + exit 1 + fi + done + echo "done publishing debs" + popd > /dev/null + + + echo "" + echo "PUSHING WEB" + pushd web > /dev/null + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + popd > /dev/null + + echo "" + echo "PUSHING WEBSOCKET-GATEWAY" + pushd websocket-gateway > /dev/null + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + popd > /dev/null + + echo "" + echo "PUSHING ADMIN" + pushd admin > /dev/null + echo "publishing ubuntu package (.deb)" + DEBPATH=`find target/deb -name *.deb` + DEBNAME=`basename $DEBPATH` + curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME + if [ "$?" != "0" ]; then + echo "deb publish failed" + exit 1 + fi + echo "done publishing deb" + popd > /dev/null + + else + echo "Skipping publish since branch is neither master or develop..." + fi + +fi diff --git a/db/.ruby-version b/db/.ruby-version index abf2ccea0..cb506813e 100644 --- a/db/.ruby-version +++ b/db/.ruby-version @@ -1 +1 @@ -ruby-2.0.0-p247 +2.0.0-p247 diff --git a/db/Gemfile b/db/Gemfile index e6d5a3717..903a1c2dc 100644 --- a/db/Gemfile +++ b/db/Gemfile @@ -1,6 +1,6 @@ -source 'https://rubygems.org' +source 'http://rubygems.org' # Assumes you have already cloned pg_migrate_ruby in your workspace # $ cd [workspace] # $ git clone https://github.com/sethcall/pg_migrate_ruby -gem 'pg_migrate', '0.1.11' +gem 'pg_migrate', '0.1.13' diff --git a/db/Gemfile.lock b/db/Gemfile.lock index e9646a77c..eb6aee107 100644 --- a/db/Gemfile.lock +++ b/db/Gemfile.lock @@ -1,20 +1,18 @@ GEM - remote: https://rubygems.org/ + remote: http://rubygems.org/ specs: little-plugger (1.1.3) logging (1.7.2) little-plugger (>= 1.1.3) - pg (0.15.1) - pg (0.15.1-x86-mingw32) - pg_migrate (0.1.11) + pg (0.17.1) + pg_migrate (0.1.13) logging (= 1.7.2) - pg (= 0.15.1) - thor (= 0.15.4) - thor (0.15.4) + pg (= 0.17.1) + thor + thor (0.18.1) PLATFORMS ruby - x86-mingw32 DEPENDENCIES - pg_migrate (= 0.1.11) + pg_migrate (= 0.1.13) diff --git a/db/build b/db/build index 259aea93b..a0084254e 100755 --- a/db/build +++ b/db/build @@ -19,7 +19,7 @@ rm -rf $TARGET mkdir -p $PG_BUILD_OUT mkdir -p $PG_RUBY_PACKAGE_OUT -bundle update +bundle install --path vendor/bundle echo "building migrations" bundle exec pg_migrate build --source . --out $PG_BUILD_OUT --test --verbose diff --git a/db/geodata/README.txt b/db/geodata/README.txt new file mode 100644 index 000000000..ff42edb3b --- /dev/null +++ b/db/geodata/README.txt @@ -0,0 +1 @@ +this is just for getting this maxmind data over there so i can use it. diff --git a/db/geodata/ca_region.csv b/db/geodata/ca_region.csv new file mode 100644 index 000000000..f24bd3902 --- /dev/null +++ b/db/geodata/ca_region.csv @@ -0,0 +1,13 @@ +AB,Alberta +BC,British Columbia +MB,Manitoba +NB,New Brunswick +NL,Newfoundland and Labrador +NS,Nova Scotia +NT,Northwest Territories +NU,Nunavut +ON,Ontario +PE,Prince Edward Island +QC,Quebec +SK,Saskatchewan +YT,Yukon diff --git a/db/geodata/iso3166.csv b/db/geodata/iso3166.csv new file mode 100644 index 000000000..454b99c4e --- /dev/null +++ b/db/geodata/iso3166.csv @@ -0,0 +1,254 @@ +A1,"Anonymous Proxy" +A2,"Satellite Provider" +O1,"Other Country" +AD,"Andorra" +AE,"United Arab Emirates" +AF,"Afghanistan" +AG,"Antigua and Barbuda" +AI,"Anguilla" +AL,"Albania" +AM,"Armenia" +AO,"Angola" +AP,"Asia/Pacific Region" +AQ,"Antarctica" +AR,"Argentina" +AS,"American Samoa" +AT,"Austria" +AU,"Australia" +AW,"Aruba" +AX,"Aland Islands" +AZ,"Azerbaijan" +BA,"Bosnia and Herzegovina" +BB,"Barbados" +BD,"Bangladesh" +BE,"Belgium" +BF,"Burkina Faso" +BG,"Bulgaria" +BH,"Bahrain" +BI,"Burundi" +BJ,"Benin" +BL,"Saint Bartelemey" +BM,"Bermuda" +BN,"Brunei Darussalam" +BO,"Bolivia" +BQ,"Bonaire, Saint Eustatius and Saba" +BR,"Brazil" +BS,"Bahamas" +BT,"Bhutan" +BV,"Bouvet Island" +BW,"Botswana" +BY,"Belarus" +BZ,"Belize" +CA,"Canada" +CC,"Cocos (Keeling) Islands" +CD,"Congo, The Democratic Republic of the" +CF,"Central African Republic" +CG,"Congo" +CH,"Switzerland" +CI,"Cote d'Ivoire" +CK,"Cook Islands" +CL,"Chile" +CM,"Cameroon" +CN,"China" +CO,"Colombia" +CR,"Costa Rica" +CU,"Cuba" +CV,"Cape Verde" +CW,"Curacao" +CX,"Christmas Island" +CY,"Cyprus" +CZ,"Czech Republic" +DE,"Germany" +DJ,"Djibouti" +DK,"Denmark" +DM,"Dominica" +DO,"Dominican Republic" +DZ,"Algeria" +EC,"Ecuador" +EE,"Estonia" +EG,"Egypt" +EH,"Western Sahara" +ER,"Eritrea" +ES,"Spain" +ET,"Ethiopia" +EU,"Europe" +FI,"Finland" +FJ,"Fiji" +FK,"Falkland Islands (Malvinas)" +FM,"Micronesia, Federated States of" +FO,"Faroe Islands" +FR,"France" +GA,"Gabon" +GB,"United Kingdom" +GD,"Grenada" +GE,"Georgia" +GF,"French Guiana" +GG,"Guernsey" +GH,"Ghana" +GI,"Gibraltar" +GL,"Greenland" +GM,"Gambia" +GN,"Guinea" +GP,"Guadeloupe" +GQ,"Equatorial Guinea" +GR,"Greece" +GS,"South Georgia and the South Sandwich Islands" +GT,"Guatemala" +GU,"Guam" +GW,"Guinea-Bissau" +GY,"Guyana" +HK,"Hong Kong" +HM,"Heard Island and McDonald Islands" +HN,"Honduras" +HR,"Croatia" +HT,"Haiti" +HU,"Hungary" +ID,"Indonesia" +IE,"Ireland" +IL,"Israel" +IM,"Isle of Man" +IN,"India" +IO,"British Indian Ocean Territory" +IQ,"Iraq" +IR,"Iran, Islamic Republic of" +IS,"Iceland" +IT,"Italy" +JE,"Jersey" +JM,"Jamaica" +JO,"Jordan" +JP,"Japan" +KE,"Kenya" +KG,"Kyrgyzstan" +KH,"Cambodia" +KI,"Kiribati" +KM,"Comoros" +KN,"Saint Kitts and Nevis" +KP,"Korea, Democratic People's Republic of" +KR,"Korea, Republic of" +KW,"Kuwait" +KY,"Cayman Islands" +KZ,"Kazakhstan" +LA,"Lao People's Democratic Republic" +LB,"Lebanon" +LC,"Saint Lucia" +LI,"Liechtenstein" +LK,"Sri Lanka" +LR,"Liberia" +LS,"Lesotho" +LT,"Lithuania" +LU,"Luxembourg" +LV,"Latvia" +LY,"Libyan Arab Jamahiriya" +MA,"Morocco" +MC,"Monaco" +MD,"Moldova, Republic of" +ME,"Montenegro" +MF,"Saint Martin" +MG,"Madagascar" +MH,"Marshall Islands" +MK,"Macedonia" +ML,"Mali" +MM,"Myanmar" +MN,"Mongolia" +MO,"Macao" +MP,"Northern Mariana Islands" +MQ,"Martinique" +MR,"Mauritania" +MS,"Montserrat" +MT,"Malta" +MU,"Mauritius" +MV,"Maldives" +MW,"Malawi" +MX,"Mexico" +MY,"Malaysia" +MZ,"Mozambique" +NA,"Namibia" +NC,"New Caledonia" +NE,"Niger" +NF,"Norfolk Island" +NG,"Nigeria" +NI,"Nicaragua" +NL,"Netherlands" +NO,"Norway" +NP,"Nepal" +NR,"Nauru" +NU,"Niue" +NZ,"New Zealand" +OM,"Oman" +PA,"Panama" +PE,"Peru" +PF,"French Polynesia" +PG,"Papua New Guinea" +PH,"Philippines" +PK,"Pakistan" +PL,"Poland" +PM,"Saint Pierre and Miquelon" +PN,"Pitcairn" +PR,"Puerto Rico" +PS,"Palestinian Territory" +PT,"Portugal" +PW,"Palau" +PY,"Paraguay" +QA,"Qatar" +RE,"Reunion" +RO,"Romania" +RS,"Serbia" +RU,"Russian Federation" +RW,"Rwanda" +SA,"Saudi Arabia" +SB,"Solomon Islands" +SC,"Seychelles" +SD,"Sudan" +SE,"Sweden" +SG,"Singapore" +SH,"Saint Helena" +SI,"Slovenia" +SJ,"Svalbard and Jan Mayen" +SK,"Slovakia" +SL,"Sierra Leone" +SM,"San Marino" +SN,"Senegal" +SO,"Somalia" +SR,"Suriname" +SS,"South Sudan" +ST,"Sao Tome and Principe" +SV,"El Salvador" +SX,"Sint Maarten" +SY,"Syrian Arab Republic" +SZ,"Swaziland" +TC,"Turks and Caicos Islands" +TD,"Chad" +TF,"French Southern Territories" +TG,"Togo" +TH,"Thailand" +TJ,"Tajikistan" +TK,"Tokelau" +TL,"Timor-Leste" +TM,"Turkmenistan" +TN,"Tunisia" +TO,"Tonga" +TR,"Turkey" +TT,"Trinidad and Tobago" +TV,"Tuvalu" +TW,"Taiwan" +TZ,"Tanzania, United Republic of" +UA,"Ukraine" +UG,"Uganda" +UM,"United States Minor Outlying Islands" +US,"United States" +UY,"Uruguay" +UZ,"Uzbekistan" +VA,"Holy See (Vatican City State)" +VC,"Saint Vincent and the Grenadines" +VE,"Venezuela" +VG,"Virgin Islands, British" +VI,"Virgin Islands, U.S." +VN,"Vietnam" +VU,"Vanuatu" +WF,"Wallis and Futuna" +WS,"Samoa" +YE,"Yemen" +YT,"Mayotte" +ZA,"South Africa" +ZM,"Zambia" +ZW,"Zimbabwe" diff --git a/db/geodata/supplement.sql b/db/geodata/supplement.sql new file mode 100644 index 000000000..5e06299be --- /dev/null +++ b/db/geodata/supplement.sql @@ -0,0 +1,36 @@ +-- to load the geoip data: +-- psql -U postgres -d jam -f GeoIP-20140304.sql +-- psql -U postgres -d jam -f supplement.sql + +DELETE FROM jamcompany; +ALTER SEQUENCE jamcompany_coid_seq RESTART WITH 1; +INSERT INTO jamcompany (company) SELECT DISTINCT company FROM geoipisp ORDER BY company; + +DELETE FROM jamisp; +INSERT INTO jamisp (beginip, endip, coid) SELECT x.beginip, x.endip, y.coid FROM geoipisp x, jamcompany y WHERE x.company = y.company; + +ALTER TABLE geoiplocations DROP COLUMN geog; +ALTER TABLE geoiplocations ADD COLUMN geog geography(point, 4326); +UPDATE geoiplocations SET geog = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)::geography; +CREATE INDEX geoiplocations_geog_gix ON geoiplocations USING GIST (geog); + +ALTER TABLE geoipblocks DROP COLUMN geom; +ALTER TABLE geoipblocks ADD COLUMN geom geometry(polygon); +-- DROP INDEX geoipblocks_geom_gix; +UPDATE geoipblocks SET geom = ST_MakeEnvelope(beginip, -1, endip, 1); +CREATE INDEX geoipblocks_geom_gix ON geoipblocks USING GIST (geom); + +ALTER TABLE jamisp DROP COLUMN geom; +ALTER TABLE jamisp ADD COLUMN geom geometry(polygon); +UPDATE jamisp SET geom = ST_MakeEnvelope(beginip, -1, endip, 1); +CREATE INDEX jamisp_geom_gix ON jamisp USING GIST (geom); + +DELETE FROM cities; +INSERT INTO cities (city, region, countrycode) SELECT DISTINCT city, region, countrycode FROM geoiplocations WHERE length(city) > 0 AND length(countrycode) > 0; +DELETE FROM regions; +INSERT INTO regions (region, countrycode) SELECT DISTINCT region, countrycode FROM cities; +DELETE FROM countries; +INSERT INTO countries (countrycode) SELECT DISTINCT countrycode FROM regions; + + +VACUUM ANALYSE; diff --git a/db/geodata/us_region.csv b/db/geodata/us_region.csv new file mode 100644 index 000000000..b8a27ee2e --- /dev/null +++ b/db/geodata/us_region.csv @@ -0,0 +1,57 @@ +AA,Armed Forces America +AE,Armed Forces +AP,Armed Forces Pacific +AK,Alaska +AL,Alabama +AR,Arkansas +AZ,Arizona +CA,California +CO,Colorado +CT,Connecticut +DC,District of Columbia +DE,Delaware +FL,Florida +GA,Georgia +GU,Guam +HI,Hawaii +IA,Iowa +ID,Idaho +IL,Illinois +IN,Indiana +KS,Kansas +KY,Kentucky +LA,Louisiana +MA,Massachusetts +MD,Maryland +ME,Maine +MI,Michigan +MN,Minnesota +MO,Missouri +MS,Mississippi +MT,Montana +NC,North Carolina +ND,North Dakota +NE,Nebraska +NH,New Hampshire +NJ,New Jersey +NM,New Mexico +NV,Nevada +NY,New York +OH,Ohio +OK,Oklahoma +OR,Oregon +PA,Pennsylvania +PR,Puerto Rico +RI,Rhode Island +SC,South Carolina +SD,South Dakota +TN,Tennessee +TX,Texas +UT,Utah +VA,Virginia +VI,Virgin Islands +VT,Vermont +WA,Washington +WI,Wisconsin +WV,West Virginia +WY,Wyoming diff --git a/db/jenkins b/db/jenkins index 8d2afbc49..275cb28a4 100755 --- a/db/jenkins +++ b/db/jenkins @@ -7,38 +7,19 @@ echo "starting build..." ./build if [ "$?" = "0" ]; then - echo "build succeeded" - echo "publishing gem" - pushd "target/ruby_package" - find . -name *.gem -exec curl -f -T {} $GEM_SERVER/{} \; - - if [ "$?" != "0" ]; then - echo "publish failed" - exit 1 - fi - popd - echo "done publishing gems" + echo "build succeeded" + echo "publishing gem" + pushd "target/ruby_package" + find . -name *.gem -exec curl -f -T {} $GEM_SERVER/{} \; - if [ ! -z "$PACKAGE" ]; then - echo "publishing ubuntu packages (.deb)" - for f in `find target -name '*.deb'`; do - DEBNAME=`basename $f` - DEBPATH="$f" - echo "publishing $DEBPATH to deb server" - curl -f -T $DEBPATH $DEB_SERVER/$DEBNAME - - if [ "$?" != "0" ]; then - echo "deb publish failed of $DEBPATH" - exit 1 - fi - done - - echo "done publishing debs" - fi + if [ "$?" != "0" ]; then + echo "publish failed" + exit 1 + fi + popd + echo "done publishing gems" else echo "build failed" exit 1 fi - - diff --git a/db/manifest b/db/manifest index 4bc66447b..232cb12ef 100755 --- a/db/manifest +++ b/db/manifest @@ -74,3 +74,72 @@ crash_dumps_idx.sql music_sessions_user_history_add_session_removed_at.sql user_progress_tracking.sql whats_next.sql +add_user_bio.sql +users_geocoding.sql +recordings_public_launch.sql +notification_band_invite.sql +band_photo_filepicker.sql +bands_geocoding.sql +store_s3_filenames.sql +discardable_recorded_tracks.sql +music_sessions_have_claimed_recording.sql +discardable_recorded_tracks2.sql +icecast.sql +home_page_promos.sql +mix_job_watch.sql +music_session_constraints.sql +mixes_drop_manifest_add_retry.sql +music_sessions_unlogged.sql +integrate_icecast_into_sessions.sql +ms_recording_anonymous_likes.sql +ms_user_history_add_instruments.sql +icecast_config_changed.sql +invited_users_facebook_support.sql +first_recording_at.sql +share_token.sql +facebook_signup.sql +audiomixer_mp3.sql +share_token_2.sql +large_photo_url.sql +add_secret_to_user_authorization.sql +track_connection_id_not_null.sql +recordings_all_discarded.sql +recordings_via_admin_web.sql +relax_band_model_varchar.sql +add_piano.sql +feed.sql +like_follower_poly_assoc.sql +feed_use_recording.sql +feed_autoincrement_primary_key.sql +music_sessions_plays.sql +plays_likes_counters.sql +add_upright_bass.sql +music_session_history_public.sql +track_claimed_recording.sql +scores_mod_users.sql +scores_mod_connections.sql +scores_create_schemas_and_extensions.sql +scores_create_tables.sql +remove_is_downloadable.sql +scores_mod_connections2.sql +track_download_counts.sql +scores_mod_users2.sql +user_bio.sql +track_changes_counter.sql +scores_better_test_data.sql +connection_client_type.sql +add_countries_regions_and_cities.sql +plays_refactor.sql +fix_max_mind_isp_and_geo.sql +update_get_work_for_client_type.sql +events.sql +cascading_delete_constraints_for_release.sql +events_social_description.sql +fix_broken_cities.sql +notifications_with_text.sql +notification_seen_at.sql +order_event_session.sql +emails.sql +email_batch.sql +user_progress_tracking2.sql +bands_did_session.sql diff --git a/db/up/add_countries_regions_and_cities.sql b/db/up/add_countries_regions_and_cities.sql new file mode 100644 index 000000000..c1c51c34e --- /dev/null +++ b/db/up/add_countries_regions_and_cities.sql @@ -0,0 +1,8 @@ +create table cities (city varchar(255) not null, region varchar(2) not null, regionname varchar(64), countrycode varchar(2) not null, countryname varchar(64)); +insert into cities (city, region, countrycode) select distinct city, region, countrycode from geoiplocations where length(city) > 0 and length(countrycode) > 0; + +create table regions (region varchar(2) not null, regionname varchar(64), countrycode varchar(2) not null); +insert into regions (region, countrycode) select distinct region, countrycode from cities; + +create table countries (countrycode varchar(2) not null, countryname varchar(64)); +insert into countries (countrycode) select distinct countrycode from regions; diff --git a/db/up/add_piano.sql b/db/up/add_piano.sql new file mode 100644 index 000000000..5bd01e480 --- /dev/null +++ b/db/up/add_piano.sql @@ -0,0 +1 @@ +INSERT INTO instruments (id, description, popularity) VALUES ('piano', 'Piano', 2); \ No newline at end of file diff --git a/db/up/add_secret_to_user_authorization.sql b/db/up/add_secret_to_user_authorization.sql new file mode 100644 index 000000000..2dab2c08c --- /dev/null +++ b/db/up/add_secret_to_user_authorization.sql @@ -0,0 +1 @@ +ALTER TABLE user_authorizations ADD COLUMN secret VARCHAR(255); \ No newline at end of file diff --git a/db/up/add_upright_bass.sql b/db/up/add_upright_bass.sql new file mode 100644 index 000000000..30cb9f0c8 --- /dev/null +++ b/db/up/add_upright_bass.sql @@ -0,0 +1 @@ +INSERT INTO instruments (id, description, popularity) VALUES ('upright bass', 'Upright Bass', 2); \ No newline at end of file diff --git a/db/up/add_user_bio.sql b/db/up/add_user_bio.sql new file mode 100644 index 000000000..725ff5b70 --- /dev/null +++ b/db/up/add_user_bio.sql @@ -0,0 +1 @@ +alter table users add column biography VARCHAR(4000); \ No newline at end of file diff --git a/db/up/audiomixer_mp3.sql b/db/up/audiomixer_mp3.sql new file mode 100644 index 000000000..d48cfed01 --- /dev/null +++ b/db/up/audiomixer_mp3.sql @@ -0,0 +1,9 @@ +-- add idea of a mix having mp3 as well as ogg + +ALTER TABLE mixes RENAME COLUMN md5 TO ogg_md5; +ALTER TABLE mixes RENAME COLUMN length TO ogg_length; +ALTER TABLE mixes RENAME COLUMN url TO ogg_url; + +ALTER TABLE mixes ADD COLUMN mp3_md5 VARCHAR(100); +ALTER TABLE mixes ADD COLUMN mp3_length INTEGER; +ALTER TABLE mixes ADD COLUMN mp3_url VARCHAR(1024); \ No newline at end of file diff --git a/db/up/band_photo_filepicker.sql b/db/up/band_photo_filepicker.sql new file mode 100644 index 000000000..181fc1469 --- /dev/null +++ b/db/up/band_photo_filepicker.sql @@ -0,0 +1,4 @@ +ALTER TABLE bands ADD COLUMN original_fpfile_photo VARCHAR(8000) DEFAULT NULL; +ALTER TABLE bands ADD COLUMN cropped_fpfile_photo VARCHAR(8000) DEFAULT NULL; +ALTER TABLE bands ADD COLUMN cropped_s3_path_photo VARCHAR(512) DEFAULT NULL; +ALTER TABLE bands ADD COLUMN crop_selection_photo VARCHAR(256) DEFAULT NULL; \ No newline at end of file diff --git a/db/up/bands_did_session.sql b/db/up/bands_did_session.sql new file mode 100644 index 000000000..62bb9222c --- /dev/null +++ b/db/up/bands_did_session.sql @@ -0,0 +1,2 @@ +ALTER TABLE bands ADD COLUMN did_real_session boolean default false; + diff --git a/db/up/bands_geocoding.sql b/db/up/bands_geocoding.sql new file mode 100644 index 000000000..cf612ac0e --- /dev/null +++ b/db/up/bands_geocoding.sql @@ -0,0 +1,4 @@ +ALTER TABLE bands ADD COLUMN lat NUMERIC(15,10); +ALTER TABLE bands ADD COLUMN lng NUMERIC(15,10); + +UPDATE bands SET country = 'US' WHERE country = 'USA'; diff --git a/db/up/cascading_delete_constraints_for_release.sql b/db/up/cascading_delete_constraints_for_release.sql new file mode 100644 index 000000000..1b9e541fb --- /dev/null +++ b/db/up/cascading_delete_constraints_for_release.sql @@ -0,0 +1,18 @@ +-- allow a user to be readily deleted by adding cascades +ALTER TABLE music_sessions_user_history DROP CONSTRAINT music_sessions_user_history_user_id_fkey; +ALTER TABLE ONLY music_sessions_user_history ADD CONSTRAINT music_sessions_user_history_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; + +ALTER TABLE crash_dumps DROP CONSTRAINT crash_dumps_user_id_fkey; +ALTER TABLE ONLY crash_dumps ADD CONSTRAINT crash_dumps_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL; + +ALTER TABLE music_sessions_history DROP CONSTRAINT music_sessions_history_user_id_fkey; +ALTER TABLE music_sessions_history ADD CONSTRAINT music_sessions_history_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; + +ALTER TABLE music_sessions_user_history DROP CONSTRAINT "music_sessions_user_history_music_session_id_fkey"; +ALTER TABLE music_sessions_user_history ADD CONSTRAINT "music_sessions_user_history_music_session_id_fkey" FOREIGN KEY (music_session_id) REFERENCES music_sessions_history(music_session_id) ON DELETE CASCADE; + +ALTER TABLE "recordings" DROP CONSTRAINT "recordings_creator_id_fkey"; +ALTER TABLE "recordings" ADD CONSTRAINT "recordings_creator_id_fkey" FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE; + +ALTER TABLE playable_plays DROP CONSTRAINT "playable_plays_claimed_recording_id_fkey"; +ALTER TABLE playable_plays ADD CONSTRAINT "playable_plays_claimed_recording_id_fkey" FOREIGN KEY (claimed_recording_id) REFERENCES claimed_recordings(id) ON DELETE CASCADE; \ No newline at end of file diff --git a/db/up/connection_client_type.sql b/db/up/connection_client_type.sql new file mode 100644 index 000000000..b38df8e9d --- /dev/null +++ b/db/up/connection_client_type.sql @@ -0,0 +1,3 @@ +ALTER TABLE connections ADD COLUMN client_type VARCHAR(256); +UPDATE connections SET client_type = 'old' WHERE client_type IS NULL; +ALTER TABLE connections ALTER COLUMN client_type SET NOT NULL; diff --git a/db/up/discardable_recorded_tracks.sql b/db/up/discardable_recorded_tracks.sql new file mode 100644 index 000000000..8e30f6528 --- /dev/null +++ b/db/up/discardable_recorded_tracks.sql @@ -0,0 +1,5 @@ +-- there are no valid recordings and mixes at this time +DELETE FROM recorded_tracks; +DELETE FROM mixes; + +ALTER TABLE recorded_tracks ADD COLUMN discard BOOLEAN DEFAULT FALSE NOT NULL; \ No newline at end of file diff --git a/db/up/discardable_recorded_tracks2.sql b/db/up/discardable_recorded_tracks2.sql new file mode 100644 index 000000000..0d46581f9 --- /dev/null +++ b/db/up/discardable_recorded_tracks2.sql @@ -0,0 +1,2 @@ +ALTER TABLE recorded_tracks ALTER COLUMN discard DROP DEFAULT; +ALTER TABLE recorded_tracks ALTER COLUMN discard DROP NOT NULL; \ No newline at end of file diff --git a/db/up/email_batch.sql b/db/up/email_batch.sql new file mode 100644 index 000000000..171ba98f1 --- /dev/null +++ b/db/up/email_batch.sql @@ -0,0 +1,30 @@ +CREATE TABLE email_batch_sets ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + email_batch_id VARCHAR(64) REFERENCES email_batches(id) ON DELETE CASCADE, + + started_at TIMESTAMP, + user_ids TEXT NOT NULL default '', + batch_count INTEGER, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); +ALTER TABLE email_batch_sets ADD CONSTRAINT email_batch_set_uniqkey UNIQUE (email_batch_id, started_at); +CREATE INDEX email_batch_set_fkidx ON email_batch_sets (email_batch_id); + +CREATE TABLE email_errors ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id VARCHAR(64) REFERENCES users(id) ON DELETE CASCADE, + + error_type VARCHAR(32), + email_address VARCHAR(256), + status VARCHAR(32), + email_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + reason TEXT, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE INDEX email_error_user_fkidx ON email_errors(user_id); +CREATE INDEX email_error_address_idx ON email_errors(email_address); diff --git a/db/up/emails.sql b/db/up/emails.sql new file mode 100644 index 000000000..704458a67 --- /dev/null +++ b/db/up/emails.sql @@ -0,0 +1,25 @@ +CREATE TABLE email_batches ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + subject VARCHAR(256) NOT NULL, + body TEXT NOT NULL, + from_email VARCHAR(64) NOT NULL default 'support@jamkazam.com', + + aasm_state VARCHAR(32) NOT NULL default 'pending', + + test_emails TEXT NOT NULL default 'test@jamkazam.com', + + opt_in_count INTEGER NOT NULL default 0, + sent_count INTEGER NOT NULL default 0, + + lock_version INTEGER, + + started_at TIMESTAMP, + completed_at TIMESTAMP, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE users ALTER COLUMN subscribe_email SET DEFAULT true; +UPDATE users SET subscribe_email = true WHERE subscribe_email = false; + diff --git a/db/up/events.sql b/db/up/events.sql new file mode 100644 index 000000000..c2992c07b --- /dev/null +++ b/db/up/events.sql @@ -0,0 +1,24 @@ +CREATE TABLE events ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + slug VARCHAR(512) NOT NULL UNIQUE, + title TEXT, + description TEXT, + show_sponser BOOLEAN NOT NULL DEFAULT false, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE event_sessions ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + starts_at TIMESTAMP, + ends_at TIMESTAMP, + pinned_state VARCHAR(255), + img_url VARCHAR(1024), + img_width INTEGER, + img_height INTEGER, + event_id VARCHAR(64) REFERENCES events(id) ON DELETE CASCADE, + user_id VARCHAR(64) REFERENCES users(id) ON DELETE SET NULL, + band_id VARCHAR(64) REFERENCES bands(id) ON DELETE SET NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/db/up/events_social_description.sql b/db/up/events_social_description.sql new file mode 100644 index 000000000..36f3675e1 --- /dev/null +++ b/db/up/events_social_description.sql @@ -0,0 +1 @@ +ALTER TABLE events ADD COLUMN social_description TEXT; diff --git a/db/up/facebook_signup.sql b/db/up/facebook_signup.sql new file mode 100644 index 000000000..d27ec0cdd --- /dev/null +++ b/db/up/facebook_signup.sql @@ -0,0 +1,16 @@ +-- when a user authorizes our application to signup, we create this row +CREATE UNLOGGED TABLE facebook_signups ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + lookup_id VARCHAR(255) UNIQUE NOT NULL, + last_name VARCHAR(100), + first_name VARCHAR(100), + gender VARCHAR(1), + email VARCHAR(1024), + uid VARCHAR(1024), + token VARCHAR(1024), + token_expires_at TIMESTAMP, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +ALTER TABLE user_authorizations ADD CONSTRAINT user_authorizations_uniqkey UNIQUE (provider, uid); \ No newline at end of file diff --git a/db/up/feed.sql b/db/up/feed.sql new file mode 100644 index 000000000..b7bb81333 --- /dev/null +++ b/db/up/feed.sql @@ -0,0 +1,9 @@ +ALTER TABLE music_sessions_history ADD PRIMARY KEY (id); + +CREATE TABLE feeds ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + claimed_recording_id VARCHAR(64) UNIQUE REFERENCES claimed_recordings(id) ON DELETE CASCADE, + music_session_id VARCHAR(64) UNIQUE REFERENCES music_sessions_history(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/db/up/feed_autoincrement_primary_key.sql b/db/up/feed_autoincrement_primary_key.sql new file mode 100644 index 000000000..9c481a2e9 --- /dev/null +++ b/db/up/feed_autoincrement_primary_key.sql @@ -0,0 +1,9 @@ +DROP TABLE feeds; + +CREATE TABLE feeds ( + id BIGSERIAL PRIMARY KEY, + recording_id VARCHAR(64) UNIQUE REFERENCES recordings(id) ON DELETE CASCADE, + music_session_id VARCHAR(64) UNIQUE REFERENCES music_sessions_history(id) ON DELETE CASCADE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); \ No newline at end of file diff --git a/db/up/feed_use_recording.sql b/db/up/feed_use_recording.sql new file mode 100644 index 000000000..598c7e495 --- /dev/null +++ b/db/up/feed_use_recording.sql @@ -0,0 +1,4 @@ +DELETE from feeds; + +ALTER TABLE feeds DROP COLUMN claimed_recording_id; +ALTER TABLE feeds ADD COLUMN recording_id VARCHAR(64) UNIQUE REFERENCES recordings(id) ON DELETE CASCADE; \ No newline at end of file diff --git a/db/up/first_recording_at.sql b/db/up/first_recording_at.sql new file mode 100644 index 000000000..1052ca36f --- /dev/null +++ b/db/up/first_recording_at.sql @@ -0,0 +1 @@ +alter table users add column first_recording_at TIMESTAMP; \ No newline at end of file diff --git a/db/up/fix_broken_cities.sql b/db/up/fix_broken_cities.sql new file mode 100644 index 000000000..baffc7cf1 --- /dev/null +++ b/db/up/fix_broken_cities.sql @@ -0,0 +1,2 @@ +alter table cities drop column regionname; +alter table cities drop column countryname; diff --git a/db/up/fix_max_mind_isp_and_geo.sql b/db/up/fix_max_mind_isp_and_geo.sql new file mode 100644 index 000000000..3183c2832 --- /dev/null +++ b/db/up/fix_max_mind_isp_and_geo.sql @@ -0,0 +1,37 @@ +-- fix up max_mind_isp + +delete from max_mind_isp; + +alter table max_mind_isp alter column ip_bottom type bigint using ip_bottom::bigint; +alter table max_mind_isp alter column ip_bottom set not null; + +alter table max_mind_isp alter column ip_top type bigint using ip_top::bigint; +alter table max_mind_isp alter column ip_top set not null; + +alter table max_mind_isp alter column isp type character varying(64); +alter table max_mind_isp alter column isp set not null; + +alter table max_mind_isp alter column country type character varying(2); +alter table max_mind_isp alter column country set not null; + +-- fix up max_mind_geo + +delete from max_mind_geo; + +alter table max_mind_geo alter column ip_start type bigint using 0; +alter table max_mind_geo alter column ip_start set not null; + +alter table max_mind_geo alter column ip_end type bigint using 0; +alter table max_mind_geo alter column ip_end set not null; + +alter table max_mind_geo alter column country type character varying(2); +alter table max_mind_geo alter column country set not null; + +alter table max_mind_geo alter column region type character varying(2); +alter table max_mind_geo alter column region set not null; + +alter table max_mind_geo alter column city set not null; + +alter table max_mind_geo alter column lat set not null; + +alter table max_mind_geo alter column lng set not null; diff --git a/db/up/home_page_promos.sql b/db/up/home_page_promos.sql new file mode 100644 index 000000000..9c0419b34 --- /dev/null +++ b/db/up/home_page_promos.sql @@ -0,0 +1,25 @@ +-- +CREATE TABLE promotionals( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + + /* allows for single table inheritance */ + type VARCHAR(128) NOT NULL DEFAULT 'JamRuby::PromoBuzz', + /* state machine */ + aasm_state VARCHAR(64) DEFAULT 'hidden', + /* order of promo within its types */ + position integer NOT NULL DEFAULT 0, + /* standard AR timestamps */ + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + + /* references latest recording or session polymorphically */ + latest_id VARCHAR(64) DEFAULT NULL, + latest_type VARCHAR(128) DEFAULT NULL, + + /* used for buzz promo type */ + image VARCHAR(1024) DEFAULT NULL, + text_short VARCHAR(512) DEFAULT NULL, + text_long VARCHAR(4096) DEFAULT NULL +); + +CREATE INDEX promo_latest_idx ON promotionals(latest_id, latest_type); diff --git a/db/up/icecast.sql b/db/up/icecast.sql new file mode 100644 index 000000000..430ca0d14 --- /dev/null +++ b/db/up/icecast.sql @@ -0,0 +1,381 @@ + +-- see http://www.icecast.org/docs/icecast-2.3.3/icecast2_config_file.html#limits +CREATE TABLE icecast_limits ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + + -- number of listening clients + clients INTEGER NOT NULL DEFAULT 1000, + + --number of sources include souce clients and relays + sources INTEGER NOT NULL DEFAULT 50, + + -- maximum size (in bytes) of the stream queue + queue_size INTEGER NOT NULL DEFAULT 102400, + + -- does not appear to be used + client_timeout INTEGER DEFAULT 30, + + -- The maximum time (in seconds) to wait for a request to come in once + -- the client has made a connection to the server. + -- In general this value should not need to be tweaked. + header_timeout INTEGER DEFAULT 15, + + -- If a connected source does not send any data within this + -- timeout period (in seconds), then the source connection + -- will be removed from the server. + source_timeout INTEGER DEFAULT 10, + + -- The burst size is the amount of data (in bytes) + -- to burst to a client at connection time. + burst_size INTEGER DEFAULT 65536, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + + ); + + +CREATE TABLE icecast_admin_authentications ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + + -- The unencrypted password used by sources to connect to icecast2. + -- The DEFAULT username for all source connections is 'source' but + -- this option allows to specify a DEFAULT password. This and the username + -- can be changed in the individual mount sections. + source_pass VARCHAR(64) NOT NULL, + + -- Used in the master server as part of the authentication when a slave requests + -- the list of streams to relay. The DEFAULT username is 'relay' + relay_user VARCHAR(64) NOT NULL, + relay_pass VARCHAR(64) NOT NULL, + + --The username/password used for all administration functions. + admin_user VARCHAR(64) NOT NULL, + admin_pass VARCHAR(64) NOT NULL, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ); + + +--contains all the settings for listing a stream on any of the Icecast2 YP Directory servers. +-- Multiple occurances of this section can be specified in order to be listed on multiple directory servers. +CREATE TABLE icecast_directories ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + yp_url_timeout INTEGER NOT NULL DEFAULT 15, + yp_url VARCHAR(1024) NOT NULL, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE icecast_listen_sockets ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + + -- The TCP port that will be used to accept client connections. + port INTEGER NOT NULL DEFAULT 8001, + + -- An optional IP address that can be used to bind to a specific network card. + -- If not supplied, then it will bind to all interfaces. + bind_address VARCHAR(1024), + + shoutcast_mount VARCHAR(1024), + shoutcast_compat INTEGER, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_relays ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + + -- ip address of server we are relaying from and port number + server VARCHAR(1024) NOT NULL, + port INTEGER NOT NULL DEFAULT 8001, + + -- mount at server. eg /example.ogg + mount VARCHAR(1024) NOT NULL, + -- eg /different.ogg + local_mount VARCHAR(1024), + -- eg joe. could be null + relay_username VARCHAR(64), + -- user password + relay_pass VARCHAR(64), + relay_shoutcast_metadata INTEGER DEFAULT 0, + --- relay only if we have someone wanting to listen + on_demand INTEGER DEFAULT 1, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE UNLOGGED TABLE icecast_user_authentications( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + --"htpasswd or url" + -- real name is type + authentication_type VARCHAR(16) DEFAULT 'url', + -- these are for httpasswd + filename VARCHAR(1024), + allow_duplicate_users INTEGER, + + -- these options are for url + -- eg value="http://myauthserver.com/stream_start.php" + mount_add VARCHAR(1024), + --value="http://myauthserver.com/stream_end.php" + mount_remove VARCHAR(1024), + --value="http://myauthserver.com/listener_joined.php" + listener_add VARCHAR(1024), + --value="http://myauthserver.com/listener_left.php" + listener_remove VARCHAR(1024), + -- value="user" + unused_username VARCHAR(64), + -- value="pass" + unused_pass VARCHAR(64), + -- value="icecast-auth-user: 1" + auth_header VARCHAR(64) DEFAULT 'icecast-auth-user: 1', + -- value="icecast-auth-timelimit:" + timelimit_header VARCHAR(64) DEFAULT 'icecast-auth-timelimit:', + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE UNLOGGED TABLE icecast_mounts ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + -- eg/example-complex.ogg + name VARCHAR(1024) UNIQUE NOT NULL, + source_username VARCHAR(64), + source_pass VARCHAR(64), + max_listeners INTEGER DEFAULT 4, + max_listener_duration INTEGER DEFAULT 3600, + -- dump of the stream coming through on this mountpoint. + -- eg /tmp/dump-example1.ogg + dump_file VARCHAR(1024), + -- intro music to play + -- This optional value specifies a mountpoint that clients are automatically moved to + -- if the source shuts down or is not streaming at the time a listener connects. + intro VARCHAR(1024), + fallback_mount VARCHAR(1024), + -- When enabled, this allows a connecting source client or relay on this mountpoint + -- to move listening clients back from the fallback mount. + fallback_override INTEGER DEFAULT 1, + + -- When set to 1, this will cause new listeners, when the max listener count for the mountpoint + -- has been reached, to move to the fallback mount if there is one specified. + fallback_when_full INTEGER DEFAULT 1, + + --For non-Ogg streams like MP3, the metadata that is inserted into the stream often + -- has no defined character set. + charset VARCHAR(1024) DEFAULT 'ISO8859-1', + -- possible values are -1, 0, 1 + -- real name is public but this is reserved word in ruby + is_public INTEGER DEFAULT 0, + + stream_name VARCHAR(1024), + stream_description VARCHAR(10000), + -- direct to user page + stream_url VARCHAR(1024), + -- get this from the session info + genre VARCHAR(256), + bitrate INTEGER, + -- real name is type but this is reserved name in ruby + mime_type VARCHAR(64) NOT NULL DEFAULT 'audio/ogg' , + subtype VARCHAR(64) NOT NULL DEFAULT 'vorbis', + + -- This optional setting allows for providing a burst size which overrides the + -- DEFAULT burst size as defined in limits. The value is in bytes. + burst_size INTEGER, + mp3_metadata_interval INTEGER, + + -- Enable this to prevent this mount from being shown on the xsl pages. + -- This is mainly for cases where a local relay is configured and you do + -- not want the source of the local relay to be shown + hidden INTEGER DEFAULT 1, + + --called when the source connects or disconnects. The scripts are called with the name of the mount + on_connect VARCHAR(1024), + on_disconnect VARCHAR(1024), + + -- references icecast_user_authentications(id) + authentication_id varchar(64) DEFAULT NULL, + + ------stats------ + listeners INTEGER NOT NULL DEFAULT 0, + sourced BOOLEAN NOT NULL DEFAULT FALSE, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_paths ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + base_dir VARCHAR(1024) NOT NULL DEFAULT './', + log_dir VARCHAR(1024) NOT NULL DEFAULT './logs', + pid_file VARCHAR(1024) DEFAULT './icecast.pid', + web_root VARCHAR(1024) NOT NULL DEFAULT './web', + admin_root VARCHAR(1024) NOT NULL DEFAULT './admin', + allow_ip VARCHAR(1024), + deny_ip VARCHAR(1024), + alias_source VARCHAR(1024), + alias_dest VARCHAR(1024), + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_loggings ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + access_log VARCHAR(1024) NOT NULL DEFAULT 'access.log', + error_log VARCHAR(1024) NOT NULL DEFAULT 'error.log', + playlist_log VARCHAR(1024), + -- 4 Debug, 3 Info, 2 Warn, 1 Error + log_level INTEGER NOT NULL DEFAULT 3 , + log_archive INTEGER, + -- 10 meg log file by default + log_size INTEGER DEFAULT 10000, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_securities ( + id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), + chroot INTEGER NOT NULL DEFAULT 0, + change_owner_user VARCHAR(64), + change_owner_group VARCHAR(64), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_master_server_relays( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + + -- ip address of the master icecast server and port number + master_server VARCHAR(1024) NOT NULL, + master_server_port INTEGER NOT NULL DEFAULT 8001, + --The interval (in seconds) that the Relay Server will poll the Master Server for any new mountpoints to relay. + master_update_interval INTEGER NOT NULL DEFAULT 120, + -- This is the relay username on the master server. It is used to query the server for a list of + -- mountpoints to relay. If not specified then 'relay' is used + master_username VARCHAR(64) NOT NULL, + master_pass VARCHAR(64) NOT NULL, + + --Global on-demand setting for relays. Because you do not have individual relay options when + -- using a master server relay, you still may want those relays to only pull the stream when + -- there is at least one listener on the slave. The typical case here is to avoid surplus + -- bandwidth costs when no one is listening. + relays_on_demand INTEGER NOT NULL DEFAULT 1, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_templates ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + + limit_id VARCHAR(64) REFERENCES icecast_limits(id), + admin_auth_id VARCHAR(64) REFERENCES icecast_admin_authentications(id), + directory_id VARCHAR(64) REFERENCES icecast_directories(id), + master_relay_id VARCHAR(64) REFERENCES icecast_master_server_relays(id), + path_id VARCHAR(64) REFERENCES icecast_paths(id), + logging_id VARCHAR(64) REFERENCES icecast_loggings(id), + security_id VARCHAR(64) REFERENCES icecast_securities(id), + + location VARCHAR(1024) NOT NULL, + name VARCHAR(256) NOT NULL, + admin_email VARCHAR(1024) NOT NULL DEFAULT 'admin@jamkazam.com', + fileserve INTEGER NOT NULL DEFAULT 1, + + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + + +CREATE TABLE icecast_servers ( + id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(), + --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), + admin_auth_id VARCHAR(64) REFERENCES icecast_admin_authentications(id), + directory_id VARCHAR(64) REFERENCES icecast_directories(id), + master_relay_id VARCHAR(64) REFERENCES icecast_master_server_relays(id), + path_id VARCHAR(64) REFERENCES icecast_paths(id), + logging_id VARCHAR(64) REFERENCES icecast_loggings(id), + security_id VARCHAR(64) REFERENCES icecast_securities(id), + template_id VARCHAR(64) NOT NULL REFERENCES icecast_templates(id), + + -- This is the DNS name or IP address that will be used for the stream directory lookups or possibily + -- the playlist generation if a Host header is not provided. While localhost is shown as an example, + -- in fact you will want something that your listeners can use. + hostname VARCHAR(1024) NOT NULL, + server_id VARCHAR(1024) UNIQUE NOT NULL, + --This sets the location string for this icecast instance. It will be shown e.g in the web interface. + location VARCHAR(1024), + --This should contain contact details for getting in touch with the server administrator. + admin_email VARCHAR(1024), + -- This flag turns on the icecast2 fileserver from which static files can be served. + -- All files are served relative to the path specified in the-This email was received because someone left feedback at http://www.jamkazam.com/corp/contact +This email was received because someone left feedback at http://www.jamkazam.com/corp/contact