All pastes #918574 Raw Edit

Anonymous

public ruby v1 · immutable
#918574 ·published 2008-02-26 05:41 UTC
rendered paste body
#!/usr/bin/rubyrequire 'fileutils'=begin	This is a daemon that executes backup_script	Goal:Backup once a day, but only do it when I'm asleep.	Soloution: This script watches monitor_file, sleeps until it is 12 hours old.	If mouse movement is detected, the script will sleep for an additional 3 hours	until the mouse hasn't moved for 3 hours.	Must be ran as root.	BUG: Mouse won't move, and/or dissapears after script is killed/stopped=endclass Log	@@fp = false	@@filename = ""	def initialize(msg, filename = "")		if filename != ""			@@filename = filename			begin				@@fp = File.new(filename,'a')			rescue				STDERR.write("Can't open file:#{filename}\n");				exit			end		end		w(msg)	end	def w(msg)		t = "[" + Time.now.strftime("%Y-%m-%d %H:%M:%S") + "] "		nmsg = t + msg.to_s		# puts "#{nmsg}<br />"		if (@@fp)			@@fp.write("#{nmsg}\n")			@@fp.flush		end	end	def close()		@@fp.close();	endenddef format_time(sec)	hr = (sec / (60 * 60))	sec = (sec - (hr * (60*60)));	min = (sec / 60)	sec = (sec % 60)	return sprintf("%d:%02d:%02d", hr, min, sec)endmodule Daemon  WorkingDirectory = File.expand_path(File.dirname(__FILE__))  class Base    def self.pid_fn     # File.join(WorkingDirectory, "#{name}.pid")     return  "/var/run/backup-when-idle.pid"    end    def self.daemonize      Controller.daemonize(self)    end  end  module PidFile    def self.store(daemon, pid)      File.open(daemon.pid_fn, 'w') {|f| f << pid}    end    def self.recall(daemon)      IO.read(daemon.pid_fn).to_i rescue nil    end  end  module Controller    def self.daemonize(daemon)      case !ARGV.empty? && ARGV[0]      when 'start'        start(daemon)      when 'stop'        stop(daemon)      when 'restart'        stop(daemon)        start(daemon)      else        puts "Invalid command. Please specify start, stop or restart."        exit      end    end    def self.start(daemon)      if (File.exists?(daemon.pid_fn))          fp = File.new(daemon.pid_fn)          pid = fp.readpartial(1024)          fp.close          if (File.exists?("/proc/#{pid}/exe"))            exit 1          end      end      fork do        Process.setsid        exit if fork        PidFile.store(daemon, Process.pid)        Dir.chdir WorkingDirectory        File.umask 0000        STDIN.reopen "/dev/null"        STDOUT.reopen "/dev/null", "a"        STDERR.reopen STDOUT        trap("TERM") {daemon.stop; exit}        daemon.start      end      exit 0    end    def self.stop(daemon)      #   0 if daemon has been stopped      #   1 if daemon was already stopped      #   2 if daemon could not be stopped      #   other if a failure occurred      if !File.file?(daemon.pid_fn)        puts "Pid file not found. Is the daemon started?"        exit 1      end      pid = PidFile.recall(daemon)      FileUtils.rm(daemon.pid_fn)      pid && Process.kill("TERM", pid)      exit 0    end  endendclass MouseWatcher	def initialize(filename, hours_of_idle_time, l)		@filename = filename		min = 60		hr = min * 60		@l = l		@hours_of_idle_time = hours_of_idle_time		@last_move = Time.now - (hr * hours_of_idle_time) + (10 * min)		@mouse = File.new(filename,'r')		@l.w("opened:#{filename}")		@thread = Thread.new() {			while !@mouse.closed?				data = @mouse.readpartial(1024)				# print data				@last_move = Time.now				# @l.w("#{filename} last_move:#{@last_move}")			end		}	end	def seconds_to_inactive()		min = 60		hr = min * 60		inactive_at = (@last_move + (@hours_of_idle_time * hr))		seconds_to_inactive = inactive_at.to_i - Time.now.to_i		return seconds_to_inactive	end	def close		@mouse.close		@thread.kill		@l.w("closed:#{@filename}")	endendclass Wait_for_idle < Daemon::Base	def self.start		@mice = []		min = 60		hr = min * 60		log_file = "/var/log/backup-when-idle.log"		monitor_file = '/media/backup/last_ran_backup.txt'		backup_script = '/home/erm/bin/backup.sh'		hours_between_backups = 12		hours_of_idle_time = 1		backup_script = '/home/erm/bin/backup.sh'		mount_command = "mount /dev/hdb1 /media/backup"		# Set to 10 min to start with if the mouse hasn't moved by then		# it should be ok to backup.		@l = Log.new("Opened log", log_file)		if (!File.exists?(monitor_file))			@l.w("missing:#{monitor_file}")			`#{mount_command}`		end		if (!File.exists?(monitor_file))			# `mount /dev/hdb1 /media/backup`			@l.w("Unable to mount using #{mount_command}")			self.stop()			exit		end		Dir['/dev/input/mouse*'].each  {			|m| @mice.push(MouseWatcher.new(m, hours_of_idle_time, @l))		}		# check what time it is.		loop do			mtime = File.mtime(monitor_file)			time_to_backup = (mtime + (hr * hours_between_backups))			seconds_to_backup_time = (time_to_backup - Time.now).to_i;			seconds_to_inactive = 0			@mice.each {				|m|				# get the largest "seconds to inactive."				tmp_seconds_to_inactive = m.seconds_to_inactive()				if (tmp_seconds_to_inactive > seconds_to_inactive)					seconds_to_inactive = tmp_seconds_to_inactive				end			}			if seconds_to_backup_time > 0				@l.w("sleeping for #{seconds_to_backup_time} seconds " + format_time(seconds_to_backup_time) + " - it's not time to backup yet. Backup @#{time_to_backup} Last backup:#{mtime}")				sleep seconds_to_backup_time			elsif seconds_to_inactive > 0				@l.w("sleeping for #{seconds_to_inactive} seconds " + format_time(seconds_to_inactive) + " - mouse movement detected. Past time: "+ format_time(seconds_to_backup_time) + " Backup was scheduled @#{time_to_backup}")				sleep seconds_to_inactive			else				@l.w("Time to backup started:" + Time.now.to_s)				start_time = Time.now.to_i				#`nice -n 19 #{backup_script} > /media/backup/backup.log`				@l.w("Finished:" + Time.now.to_s + " = " + format_time((Time.now.to_i - start_time)))				FileUtils.touch([monitor_file])			end		end	end	def self.stop		@mice.each { |m| m.close() }		@l.w("Shutting down")		@l.close()		#   0 if daemon has been stopped		#   1 if daemon was already stopped		#   2 if daemon could not be stopped		#   other if a failure occurred	endendWait_for_idle.daemonizeexit 0# Exit#   0 if daemon has been started#   1 if daemon was already running#   2 if daemon could not be started