require 'zip/zip' require 'uri' $:.unshift File.dirname(__FILE__) require 'utilities' DEPRECATION_MSG = "\n" + "*** Warning: As of version 4.0 of rhoconnect, the rake command will be deprecated. ***\n" + "*** Use the corresponding rhoconnect commands instead. ***\n" + "*** Type 'rhoconnect help' for more information on these commands. ***\n" + "\n" puts DEPRECATION_MSG if $0.include? 'rake' namespace :rhoconnect do include Utilities task :config do $settings = load_settings(File.join('settings','settings.yml')) $env = (ENV['RHO_ENV'] || ENV['RACK_ENV'] || :development).to_sym uri = URI.parse($settings[$env][:syncserver]) $url = "#{uri.scheme}://#{uri.host}" $url = "#{$url}:#{uri.port}" if uri.port && uri.port != 80 $host = uri.host $port = uri.port $appname = $settings[$env][:syncserver].split('/').last $token_file = File.join(ENV['HOME'],'.rhoconnect_token') $token = File.read($token_file) if File.exist?($token_file) end task :dtach_installed do if !windows? and (`which dtach` == '') puts "WARNING: dtach not installed or not on path, some tasks will not work!" puts " Install with '[sudo] rake dtach:install'" exit end end desc "Reset the rhoconnect database (you will need to run rhoconnect:get_token afterwards)" task :reset => :config do confirm = ask " Are you sure? Resetting will remove all data!\n It will also return an error code to all\n existing devices when they connect! (yes/no): " if confirm == 'yes' RestClient.post("#{$url}/api/admin/reset", { :api_token => $token }) puts "Database reset." else puts "Cancelling." end end desc "Fetches current api token from rhoconnect" task :get_token => :config do password = '' login = ask "admin login: " begin system "stty -echo" password = ask "\nadmin password: " system "stty echo" rescue NoMethodError, Interrupt system "stty echo" exit end puts '' begin $token = RestClient.post("#{$url}/api/admin/login", { :login => login, :password => password}) rescue puts "Login failed." exit end File.open($token_file,'w') {|f| f.write $token} puts "Token is saved in: #{$token_file}" end desc "Clean rhoconnect, get token, and create new user" task :clean_start => [:get_token, :reset, :get_token, :create_user] desc "Alias for `rake rhoconnect:stop; rake rhoconnect:start`" task :restart => [:stop, :start] desc "Creates and subscribes user for application in rhoconnect" task :create_user => :config do password = '' login = ask "new user login: " begin system "stty -echo" password = ask "\nnew user password: " system "stty echo" rescue NoMethodError, Interrupt system "stty echo" exit end puts '' RestClient.post("#{$url}/api/user/create_user", { :api_token => $token, :attributes => {:login => login, :password => password}}) end desc "Deletes a user from rhoconnect" task :delete_user => :config do login = ask "user to delete: " RestClient.post("#{$url}/api/user/delete_user", { :api_token => $token, :user_id => login }) end desc "Deletes a device from rhoconnect" task :delete_device => :config do user_id = ask "device's user_id: " device_id = ask "device to delete: " RestClient.post("#{$url}/api/client/delete_client", { :api_token => $token, :user_id => user_id, :client_id => device_id}) end desc "Sets the admin password" task :set_admin_password => :get_token do new_pass,new_pass_confirm = '','' begin system "stty -echo" new_pass = ask "\nnew admin password: " new_pass_confirm = ask "\nconfirm new admin password: " system "stty echo" rescue NoMethodError, Interrupt system "stty echo" exit end if new_pass == '' puts "\nNew password can't be empty." elsif new_pass == new_pass_confirm puts "" admin_user = 'rhoadmin' RestClient.put("#{$url}/rc/#{Rhoconnect::API_VERSION}/users/#{admin_user}", {:app_name => $appname, :api_token => $token, :attributes => {:new_password => new_pass}}) else puts "\nNew password and confirmation must match." end end desc "Reset source refresh time" task :reset_refresh => :config do user = ask "user: " source_name = ask "source name: " RestClient.put("#{$url}/rc/#{Rhoconnect::API_VERSION}/readstate/users/#{user}/sources/#{source_name}", {:api_token => $token}) end begin require 'rspec/core/rake_task' desc "Run source adapter specs" task :spec do files = File.join('spec','**','*_spec.rb') RSpec::Core::RakeTask.new('rhoconnect:spec') do |t| t.pattern = FileList[files] t.rspec_opts = %w(-fn -b --color) end end rescue Exception => e puts "Run source adapter specs error: #{e.inspect}" end desc "Start rhoconnect server" task :start => :dtach_installed do cmd = (jruby?) ? trinidad? : (thin? || mongrel? || report_missing_server) if windows? puts 'Starting rhoconnect...' system("#{cmd} config.ru -P #{rhoconnect_pid}") elsif jruby? puts 'Starting rhoconnect in jruby environment...' system("#{cmd}") else puts 'Detach with Ctrl+\ Re-attach with rake rhoconnect:attach' sleep 2 system "dtach -A #{rhoconnect_socket} #{cmd} config.ru -P #{rhoconnect_pid}" end end # desc "Start rhoconnect server in bg mode (Rhostudio) - this is an internal command" task :startbg do cmd = (jruby?) ? trinidad? : (thin? || mongrel? || report_missing_server) require 'win32/process' if windows? p1 = Process.fork { if windows? puts 'Starting rhoconnect ...' system("#{cmd} config.ru -P #{rhoconnect_pid}") elsif jruby? puts 'Starting rhoconnect in jruby environment...' system("#{cmd}") else system("bundle exec #{cmd} config.ru -P #{rhoconnect_pid}") end } Process.detach(p1) exit end # desc "Start rhoconnect server in debug mode (Rhostudio) - this is an internal command" task :startdebug do cmd = (jruby?) ? trinidad? : (thin? || mongrel? || report_missing_server) ENV['DEBUG'] = 'yes' require 'win32/process' if windows? p1 = Process.fork { if windows? puts 'Starting rhoconnect ...' system("#{cmd} config.ru -P #{rhoconnect_pid}") elsif jruby? puts 'Starting rhoconnect in jruby environment...' system("#{cmd}") else system("bundle exec #{cmd} config.ru -P #{rhoconnect_pid}") end } Process.detach(p1) exit end desc "run rhoconnect console" task :console, :environment do |t, args| if RedisRunner.running? application_file = ruby19? ? './application' : 'application' #load development environment by default ENV['RACK_ENV'] = args[:environment] || 'development' system "irb -rubygems -r #{File.join(File.dirname(__FILE__),'console')} " + "-r #{File.dirname(__FILE__)} " + "-r #{application_file}" else puts "Redis is not running. Please start it by running 'rake redis:start' command." end end desc "Stop rhoconnect server" task :stop => :dtach_installed do if windows? File.delete "#{rhoconnect_pid}" if system("FOR /F %A in (#{rhoconnect_pid}) do taskkill /F /PID %A") else system "cat #{rhoconnect_pid} | xargs kill -3" end end desc "Attach to rhoconnect console" task :attach => :dtach_installed do system "dtach -a #{rhoconnect_socket}" unless windows? end desc "Launch the web console in a browser - uses :syncserver: in settings.yml" task :web => :config do windows? ? sh("start #{$url}") : sh("open #{$url}") end desc "Flush data store - WARNING: THIS REMOVES ALL DATA IN RHOCONNECT" task :flushdb => :config do puts "*** WARNING: THIS WILL REMOVE ALL DATA FROM YOUR REDIS STORE ***" confirm = ask "Are you sure (please answer yes/no)? " if confirm == 'yes' Redis.new.flushdb puts "Database flushed..." else puts "Aborted..." end end desc "Generate a cryptographically secure secret session key" task :secret do begin require 'securerandom' puts SecureRandom.hex(64) rescue LoadError puts "Missing secure random generator. Try running `rake secret` in a rails application instead." end end desc "Build executable WAR file to be used in Java App Servers" task :war do if jruby? then puts "building the WAR file" if not File::exists? "config/warble.rb" puts "generating Warbler's config file" includeDirs = [] Dir.mkdir('config') if not File.exists?('config') aFile = File.new("config/warble.rb", "w+") if aFile includeDirs = FileList['*'].exclude do |entry| entry if (not File.directory? entry) || (entry == 'spec') end configFile = "Warbler::Config.new do |config|\n" + "config.dirs = %w(#{includeDirs.join(' ')})\n" + "config.includes = FileList[\"./*\"]\n" + "config.excludes = FileList[\"./*.war\",'spec']\nend" aFile.write("#{configFile}") aFile.close else puts "Unable to create config/warble.rb file!" end end # build the executable WAR using the config/warble.rb file ENV['BUNDLE_WITHOUT'] = ['development','test'].join(':') system 'warble executable war' else puts "Cannot build WAR files outside of JRuby environment!" end end end task :default => ['rhoconnect:spec'] load File.join(File.dirname(__FILE__),'..','..','tasks','redis.rake')