# Ensure the cron is using the proper version of ruby, and simply run this with: # ruby mix_cron.rb # require 'faraday' require 'json' require 'tempfile' MIXER_EXECUTABLE = "/usr/local/bin/audiomixerapp" S3CMD = "s3cmd" # FIXME: This should probably come from an environments file or something BASE_URL = "http://www.jamkazam.com" # This must be present on requests from the cron to prevent hackers from # hitting these routes. CRON_TOKEN = "2kkl39sjjf3ijdsflje2923j" AUDIOMIXER_LOG_FILE = "/var/log/audiomixer" MIX_CRON_WATCH_FILE = "/var/run/mix_cron" # Don't do anything if the cron is arleady running. There's a theoretical race # condition here, but it should never actually be a problem because the cron should # only run every minute or two. if File.exist?(MIX_CRON_WATCH_FILE) psret = `ps axuw | grep mix_cron.rb | grep ruby` unless psret.empty? puts "Cron still running" exit end end `touch #{MIX_CRON_WATCH_FILE}` # Get the next manifest to mix response = Faraday.get "#{BASE_URL}/mixes/next", :token => CRON_TOKEN if response.status > 299 puts "Error response getting next mix: #{response.status}, #{response.body}" do_exit end # This just means no mixes available. if response.status == 204 do_exit end if response.status != 200 puts "Unexpected response received: #{response.status}, #{response.body}" do_exit end json = JSON.parse(response.body) # This needs to download all the vorbis files, mix and then upload # the finished one, and tell the server about that. json['manifest']['files'].map! do |file| file['filename'] = Dir::Tmpname.make_tmpname ['/tmp/', '.ogg'], nil file_response = Faraday.get file.url if file_response.status != 200 puts "Error downloading url: #{file.url}" do_exit end File.open(file['filename'], 'wb') { |fp| fp.write(file_response.body) } end output_filename = "/tmp/mixout-#{json['id']}.ogg" IO.popen("#{MIXER_EXECUTABLE} #{output_filename} vorbis >>& #{AUDIOMIXER_LOG_FILE}", "w") do |f| f.puts JSON.generate(json) f.close end # First maybe make sure the length is reasonable or something? I bet sox can check that (duration i mean). # FIXME?: Need to check that the put succeeded before carrying on. Probably can use the exit code or some such. # Or maybe just do an ls to sanity check it. `#{S3CMD} -P put #{output_filename} #{json['destination']}` finish_response = Faraday.put "#{BASE_URL}/mixes/finish", :token => CRON_TOKEN, :id => json['id'] if finish_response.status != 204 puts "Error calling finish on server for mix_id #{json['id']}: #{finish_response.status}, #{finish_response.body}" do_exit end puts "Mix complete and uploaded to: #{json['destination']}" do_exit def do_exit `rm -f #{MIX_CRON_WATCH_FILE}` end