From 27d38820a67751a898d5d17073adc556c4bb56a9 Mon Sep 17 00:00:00 2001 From: Patrick J Cherry Date: Wed, 2 May 2012 10:44:34 +0100 Subject: Added configuration options for daytime_hours, dead_zone, and working_hours. --- lib/mauve/configuration.rb | 107 ++++++++++++++++++++++++++++++++++++++++----- lib/mauve/mauve_time.rb | 43 +++++++++++++----- lib/mauve/notification.rb | 28 +++++++++++- 3 files changed, 157 insertions(+), 21 deletions(-) (limited to 'lib/mauve') diff --git a/lib/mauve/configuration.rb b/lib/mauve/configuration.rb index 8a0b982..55bdd9f 100644 --- a/lib/mauve/configuration.rb +++ b/lib/mauve/configuration.rb @@ -27,7 +27,7 @@ module Mauve # People # @return [Hash] attr_reader :people - + # Alert groups # @return [Array] attr_reader :alert_groups @@ -43,7 +43,7 @@ module Mauve # Various further configuration items # attr_reader :bytemark_auth_url, :bytemark_calendar_url, :remote_http_timeout, :remote_https_verify_mode, :failed_login_delay - attr_reader :max_acknowledgement_time + attr_reader :max_acknowledgement_time, :working_hours, :dead_zone, :daytime_hours # @@ -66,23 +66,30 @@ module Mauve # # Set a couple of params for remote HTTP requests. # - @remote_http_timeout = 5 - @remote_https_verify_mode = OpenSSL::SSL::VERIFY_PEER + self.remote_http_timeout = 5 + self.remote_https_verify_mode = "peer" # # Rate limit login attempts to limit the success of brute-forcing. # - @failed_login_delay = 1 + self.failed_login_delay = 1 # # Maximum amount of time to acknowledge for # - @max_acknowledgement_time = 15.days + self.max_acknowledgement_time = 15.days + + # + # Working hours + # + self.dead_zone = 3...6 + self.daytime_hours = 8...20 + self.working_hours = 9...17 end # Set the calendar URL. # - # @param [String] arg + # @param [String] arg # @return [URI] def bytemark_calendar_url=(arg) raise ArgumentError, "bytemark_calendar_url must be a string" unless arg.is_a?(String) @@ -104,7 +111,7 @@ module Mauve # Set the Bytemark Authentication URL # - # @param [String] arg + # @param [String] arg # @return [URI] def bytemark_auth_url=(arg) raise ArgumentError, "bytemark_auth_url must be a string" unless arg.is_a?(String) @@ -128,7 +135,7 @@ module Mauve # @param [Integer] arg # @return [Integer] def remote_http_timeout=(arg) - raise ArgumentError, "remote_http_timeout must be an integer" unless s.is_a?(Integer) + raise ArgumentError, "remote_http_timeout must be an integer" unless arg.is_a?(Integer) @remote_http_timeout = arg end @@ -156,7 +163,7 @@ module Mauve raise ArgumentError, "failed_login_delay must be numeric" unless arg.is_a?(Numeric) @failed_login_delay = arg end - + # Set the maximum amount of time alerts can be ack'd for # # @@ -169,5 +176,85 @@ module Mauve lambda{|at| CalendarInterface.get_attendees(x,at)} end + def working_hours=(arg) + @working_hours = do_parse_range(arg) + end + + def daytime_hours=(arg) + @daytime_hours = do_parse_range(arg) + end + + def dead_zone=(arg) + @dead_zone = do_parse_range(arg) + end + + private + + # This method takes a range, and wraps it within the specs defined by + # allowed_range. + # + # It can take an array of Numerics, Strings, Ranges etc + # + # @param + # + def do_parse_range(arg, allowed_range = (0...24)) + args = [arg].flatten + + # + # Tidy up our allowed ranges + # + min = allowed_range.first + max = allowed_range.last + + # + # If we've been given a numeric range, make sure they're all floats. + # + min = min.to_f if min.is_a?(Numeric) + max = max.to_f if max.is_a?(Numeric) + + ranges = [] + + args.each do |arg| + case arg + when Range + from = arg.first + to = arg.last + exclude_end = arg.exclude_end? + else + from = arg + to = arg + end + + from = min unless allowed_range.include?(from) + + # + # In the case of integers, we want to match up until, but not including + # the next integer. + # + if to.is_a?(Integer) + to = (exclude_end ? to : to.succ) + exclude_end = true + end + + to = max unless allowed_range.include?(to) + + from = from.to_f if from.is_a?(Numeric) + to = to.to_f if to.is_a?(Numeric) + + if from > to or (from >= to and exclude_end) + ranges << Range.new(from, max, allowed_range.exclude_end?) + ranges << Range.new(min, to, exclude_end) + else + ranges << Range.new(from, to, exclude_end) + end + + end + + ranges + end + + end + + end diff --git a/lib/mauve/mauve_time.rb b/lib/mauve/mauve_time.rb index dfbf99b..ab0734a 100644 --- a/lib/mauve/mauve_time.rb +++ b/lib/mauve/mauve_time.rb @@ -103,17 +103,38 @@ class Time # # def bank_holidays - @bank_holidays ||= [] + @bank_holidays = if defined? Server and Server.instance + Server.instance.bank_holidays + else + @bank_holidays || [] + end end - # This sets the bank holiday dates for the bank_holiday? check. + # Returns an array of ranges of working hours # - # @param [Array] arg An array of Date of bank holidays - # @returns [Array] # - def bank_holidays=(arg) - raise ArgumentError unless arg.is_a?(Array) and arg.all?{|a| a.is_a?(Date)} - @bank_holidays = arg + def working_hours + if defined? Configuration and Configuration.current + Configuration.current.working_hours + else + [9.0...17.0] + end + end + + def dead_zone + if defined? Configuration and Configuration.current + Configuration.current.working_hours + else + [3.0...7.0] + end + end + + def daytime_hours + if defined? Configuration and Configuration.current + Configuration.current.working_hours + else + [8.0...20.0] + end end # This relies on bank_holidays being set. @@ -128,14 +149,16 @@ class Time # # @return [Boolean] def working_hours? - !bank_holiday? and (1..5).include?(self.wday) and ((9..16).include?(self.hour) or (self.hour == 8 && self.min >= 30)) + (1..5).include?(self.wday) and + self.working_hours.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)} and + !self.bank_holiday? end # Test to see if it is currently daytime. The daytime day is 14 hours long # # @return [Boolean] def daytime_hours? - (8..21).include?(self.hour) + self.daytime_hours.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)} end # We're always in wallclock hours @@ -149,7 +172,7 @@ class Time # # @return [Boolean] def dead_zone? - (3..6).include?(self.hour) + self.dead_zone.any?{|r| r.include?(self.hour.to_f + self.min.to_f/60.0)} end # Format the time as a string, relative to +now+ diff --git a/lib/mauve/notification.rb b/lib/mauve/notification.rb index 899972b..6ff9541 100644 --- a/lib/mauve/notification.rb +++ b/lib/mauve/notification.rb @@ -157,6 +157,18 @@ module Mauve (@test_time - @alert.raised_at) >= seconds end + # Tests if the alert has raised for a certain time. + # + # @param [Integer] seconds Number of seconds + # @return [Boolean] + def raised_for(seconds) + @test_time = @time if @test_time.nil? + @alert && + @alert.raised? && + (@test_time - @alert.raised_at) >= seconds + end + + # Checks to see if x is contained in y # # @param [Array] y Array to search for +x+ @@ -177,10 +189,17 @@ module Mauve # @return [Boolean] def working_hours? @test_time = @time if @test_time.nil? - @test_time.bank_holidays = Server.instance.bank_holidays @test_time.working_hours? end + # + # Return true if today is a bank holiday + # + def bank_holiday? + @test_time = @time if @test_time.nil? + @test_time.bank_holiday? + end + # Test to see if we're in the dead zone. See Time#dead_zone? # # @return [Boolean] @@ -189,6 +208,13 @@ module Mauve @test_time.dead_zone? end + # + # Return true if we're in daytime_hours. See Time#daytime_hours? + # + def daytime_hours? + @test_time = @time if @test_time.nil? + @test_time.daytime_hours? + end end # A Notification is an instruction to notify a person, or a list of people, -- cgit v1.2.1