blackcal 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +3 -0
- data/CHANGELOG.md +8 -0
- data/README.md +15 -10
- data/blackcal.gemspec +3 -0
- data/lib/blackcal/range/day_range.rb +12 -1
- data/lib/blackcal/range/month_range.rb +12 -0
- data/lib/blackcal/range/time_of_day_range.rb +79 -11
- data/lib/blackcal/range/time_range.rb +22 -0
- data/lib/blackcal/range/weekday_range.rb +12 -0
- data/lib/blackcal/schedule.rb +37 -17
- data/lib/blackcal/slot_matrix.rb +3 -0
- data/lib/blackcal/time_of_day.rb +36 -0
- data/lib/blackcal/version.rb +2 -1
- metadata +46 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: db977cf2c574a0e8d76891abfa30a6b8140e5ec07bfc0f2b23a215b03732d166
         | 
| 4 | 
            +
              data.tar.gz: 8b3deb0295ba37f2ff1440cf8e4eed055dcdd77ac728a25e26b48edce491e381
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: f13e108edab2e980c18b9650145b084bf01ec391e007d78612991a4a4337d47040a7dae5bcce4ad61acc8ddcb786809bafbdea3b6cf743d5e4e14c7b26035e03
         | 
| 7 | 
            +
              data.tar.gz: 31e1e04b3929f06519a67a855e276b3771fc360b4e889d3f35b7bc5b3f4e0928617c8dfe2f0edd0cccca671b95e54d9d01c532cbaa4d7f08a145d219ed903271
         | 
    
        data/.yardopts
    ADDED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -24,27 +24,27 @@ Schedule Mondays and Tuesdays | |
| 24 24 | 
             
            ```ruby
         | 
| 25 25 | 
             
            schedule = Blackcal.schedule(weekdays: [:monday, :tuesday])
         | 
| 26 26 | 
             
            schedule.cover?('2019-01-01 19:00')
         | 
| 27 | 
            -
            # => false
         | 
| 28 | 
            -
            schedule.cover?('2019-01-02 11:00')
         | 
| 29 27 | 
             
            # => true
         | 
| 28 | 
            +
            schedule.cover?('2019-01-02 19:00')
         | 
| 29 | 
            +
            # => false
         | 
| 30 30 | 
             
            ```
         | 
| 31 31 |  | 
| 32 32 | 
             
            Schedule between 6pm and 7am every day
         | 
| 33 33 | 
             
            ```ruby
         | 
| 34 34 | 
             
            schedule = Blackcal.schedule(start_hour: 18, finish_hour: 7)
         | 
| 35 35 | 
             
            schedule.cover?('2019-01-01 19:00')
         | 
| 36 | 
            -
            # => false
         | 
| 37 | 
            -
            schedule.cover?('2019-01-01 11:00')
         | 
| 38 36 | 
             
            # => true
         | 
| 37 | 
            +
            schedule.cover?('2019-01-01 11:00')
         | 
| 38 | 
            +
            # => false
         | 
| 39 39 | 
             
            ```
         | 
| 40 40 |  | 
| 41 41 | 
             
            Schedule day 15 and 17 of month
         | 
| 42 42 | 
             
            ```ruby
         | 
| 43 43 | 
             
            schedule = Blackcal.schedule(days: [15, 17])
         | 
| 44 44 | 
             
            schedule.cover?('2019-01-15 19:00')
         | 
| 45 | 
            -
            # => false
         | 
| 46 | 
            -
            schedule.cover?('2019-01-01 11:00')
         | 
| 47 45 | 
             
            # => true
         | 
| 46 | 
            +
            schedule.cover?('2019-01-01 11:00')
         | 
| 47 | 
            +
            # => false
         | 
| 48 48 | 
             
            ```
         | 
| 49 49 |  | 
| 50 50 | 
             
            All options at once - schedule January, Mondays and Tuesdays, day 15-25, between 18pm and 7am
         | 
| @@ -56,9 +56,9 @@ schedule = Blackcal.schedule( | |
| 56 56 | 
             
              days: (15..25).to_a
         | 
| 57 57 | 
             
            )
         | 
| 58 58 | 
             
            schedule.cover?('2019-01-15 19:00')
         | 
| 59 | 
            -
            # => false
         | 
| 60 | 
            -
            schedule.cover?('2019-02-01 11:00')
         | 
| 61 59 | 
             
            # => true
         | 
| 60 | 
            +
            schedule.cover?('2019-02-01 11:00')
         | 
| 61 | 
            +
            # => false
         | 
| 62 62 | 
             
            ```
         | 
| 63 63 |  | 
| 64 64 | 
             
            Define when the schedule is active
         | 
| @@ -68,9 +68,14 @@ Blackcal.schedule(start_time: '2018-01-01 11:00', finish_time: '2019-01-01 11:00 | |
| 68 68 |  | 
| 69 69 | 
             
            Matrix representation
         | 
| 70 70 | 
             
            ```ruby
         | 
| 71 | 
            -
            schedule = Blackcal.schedule(weekdays: :friday, start_hour:  | 
| 71 | 
            +
            schedule = Blackcal.schedule(weekdays: :friday, start_hour: 0, finish_hour: 14)
         | 
| 72 72 | 
             
            schedule.to_matrix(start_date: '2018-09-14', finish_date: '2018-09-16')
         | 
| 73 | 
            -
            # => [[true, ...], [ | 
| 73 | 
            +
            # => [[true, ...], [false, ...]]
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            # defaults to hour resolution, but you can get minute resolution too
         | 
| 76 | 
            +
            schedule = Blackcal.schedule(weekdays: :friday, start_hour: 0, finish_hour: 14)
         | 
| 77 | 
            +
            schedule.to_matrix(resolution: :min, start_date: '2018-09-14', finish_date: '2018-09-16')
         | 
| 78 | 
            +
            # => [[true, ...], [false, ...]]
         | 
| 74 79 | 
             
            ```
         | 
| 75 80 |  | 
| 76 81 | 
             
            ## Development
         | 
    
        data/blackcal.gemspec
    CHANGED
    
    | @@ -24,6 +24,9 @@ Gem::Specification.new do |spec| | |
| 24 24 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 25 25 | 
             
              spec.require_paths = ['lib']
         | 
| 26 26 |  | 
| 27 | 
            +
              spec.add_development_dependency 'github-markup', '~> 2.0'
         | 
| 28 | 
            +
              spec.add_development_dependency 'redcarpet', '~> 3.4'
         | 
| 29 | 
            +
              spec.add_development_dependency 'simplecov', '~> 0.16'
         | 
| 27 30 | 
             
              spec.add_development_dependency 'bundler', '~> 1.16'
         | 
| 28 31 | 
             
              spec.add_development_dependency 'byebug'
         | 
| 29 32 | 
             
              spec.add_development_dependency 'rake', '~> 10.0'
         | 
| @@ -3,7 +3,9 @@ | |
| 3 3 | 
             
            module Blackcal
         | 
| 4 4 | 
             
              # Number range
         | 
| 5 5 | 
             
              class DayRange
         | 
| 6 | 
            -
                 | 
| 6 | 
            +
                include Enumerable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # @return [Array<Integer>] numbers in range
         | 
| 7 9 | 
             
                attr_reader :numbers
         | 
| 8 10 |  | 
| 9 11 | 
             
                # Initialize numbers range
         | 
| @@ -23,5 +25,14 @@ module Blackcal | |
| 23 25 |  | 
| 24 26 | 
             
                  numbers.include?(timestamp.day)
         | 
| 25 27 | 
             
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # @return [Array<Integer>] numbers in range
         | 
| 30 | 
            +
                alias_method :to_a, :numbers
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                # Iterate over range
         | 
| 33 | 
            +
                # @see #to_a
         | 
| 34 | 
            +
                def each(&block)
         | 
| 35 | 
            +
                  to_a.each(&block)
         | 
| 36 | 
            +
                end
         | 
| 26 37 | 
             
              end
         | 
| 27 38 | 
             
            end
         | 
| @@ -3,6 +3,9 @@ | |
| 3 3 | 
             
            module Blackcal
         | 
| 4 4 | 
             
              # Month range
         | 
| 5 5 | 
             
              class MonthRange
         | 
| 6 | 
            +
                include Enumerable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Map month name to number
         | 
| 6 9 | 
             
                MONTH_MAP = {
         | 
| 7 10 | 
             
                  january: 1,
         | 
| 8 11 | 
             
                  february: 2,
         | 
| @@ -40,5 +43,14 @@ module Blackcal | |
| 40 43 | 
             
                    MONTH_MAP.fetch(month) == timestamp.month
         | 
| 41 44 | 
             
                  end
         | 
| 42 45 | 
             
                end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
                # @return [Array<Symbol>] months in range
         | 
| 48 | 
            +
                alias_method :to_a, :months
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                # Iterate over range
         | 
| 51 | 
            +
                # @see #to_a
         | 
| 52 | 
            +
                def each(&block)
         | 
| 53 | 
            +
                  to_a.each(&block)
         | 
| 54 | 
            +
                end
         | 
| 43 55 | 
             
              end
         | 
| 44 56 | 
             
            end
         | 
| @@ -1,26 +1,94 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
            require 'blackcal/time_of_day'
         | 
| 4 | 
            +
             | 
| 3 5 | 
             
            module Blackcal
         | 
| 4 6 | 
             
              # Time of day range
         | 
| 5 7 | 
             
              class TimeOfDayRange
         | 
| 8 | 
            +
                include Enumerable
         | 
| 9 | 
            +
             | 
| 6 10 | 
             
                # Initialize time of day range
         | 
| 11 | 
            +
                # @param [TimeOfDay, Time, Integer, nil] start
         | 
| 12 | 
            +
                # @param [TimeOfDay, Time, Integer, nil] finish
         | 
| 7 13 | 
             
                def initialize(start, finish = nil)
         | 
| 8 | 
            -
                  @start = start | 
| 9 | 
            -
                  @finish = finish | 
| 10 | 
            -
             | 
| 11 | 
            -
                  @disallowed_hours = if @finish < @start
         | 
| 12 | 
            -
                                        (@start..23).to_a + (0..@finish).to_a
         | 
| 13 | 
            -
                                      else
         | 
| 14 | 
            -
                                        (@start..@finish).to_a
         | 
| 15 | 
            -
                                      end
         | 
| 14 | 
            +
                  @start = start
         | 
| 15 | 
            +
                  @finish = finish
         | 
| 16 16 | 
             
                end
         | 
| 17 17 |  | 
| 18 18 | 
             
                # Returns true if it covers timestamp
         | 
| 19 19 | 
             
                # @return [Boolean]
         | 
| 20 20 | 
             
                def cover?(timestamp)
         | 
| 21 | 
            -
                   | 
| 22 | 
            -
             | 
| 23 | 
            -
                   | 
| 21 | 
            +
                  return false if @start.nil? && @finish.nil?
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  t1 = TimeOfDay.new(timestamp.hour, timestamp.min)
         | 
| 24 | 
            +
                  if start == finish
         | 
| 25 | 
            +
                    t1 == start
         | 
| 26 | 
            +
                  elsif start > finish
         | 
| 27 | 
            +
                    t1 <= finish || t1 >= start
         | 
| 28 | 
            +
                  else
         | 
| 29 | 
            +
                    t1 >= start && t1 <= finish
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # Return start hour
         | 
| 34 | 
            +
                # @return [TimeOfDay]
         | 
| 35 | 
            +
                def start
         | 
| 36 | 
            +
                  @start_time ||= to_time_of_day(@start || 0)
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                # Return finish hour
         | 
| 40 | 
            +
                # @return [TimeOfDay]
         | 
| 41 | 
            +
                def finish
         | 
| 42 | 
            +
                  @finish_time ||= to_time_of_day(@finish || 0)
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                # Returns range as an array
         | 
| 46 | 
            +
                # @param resolution [Symbol] :hour our :min
         | 
| 47 | 
            +
                # @return [Array<Array<Integer>>] times
         | 
| 48 | 
            +
                def to_a(resolution: :hour)
         | 
| 49 | 
            +
                  return [] if @start.nil? && @finish.nil?
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  if finish < start
         | 
| 52 | 
            +
                    to_time_array(start, TimeOfDay.new(23), resolution) +
         | 
| 53 | 
            +
                      to_time_array(TimeOfDay.new(0), finish, resolution)
         | 
| 54 | 
            +
                  else
         | 
| 55 | 
            +
                    to_time_array(start, finish, resolution)
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                # Iterate over range
         | 
| 60 | 
            +
                # @param resolution [Symbol] :hour our :min
         | 
| 61 | 
            +
                def each(resolution: :hour, &block)
         | 
| 62 | 
            +
                  to_a(resolution: resolution).each(&block)
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                private
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                def to_time_array(start, finish, resolution)
         | 
| 68 | 
            +
                  if resolution == :hour
         | 
| 69 | 
            +
                    return (start.hour..finish.hour).map { |hour| [hour, 0] }
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                  # minute resolution
         | 
| 73 | 
            +
                  times = []
         | 
| 74 | 
            +
                  (start.hour..finish.hour).each do |hour|
         | 
| 75 | 
            +
                    finish_min = if hour == finish.hour && finish.min != 0
         | 
| 76 | 
            +
                                   finish.min
         | 
| 77 | 
            +
                                 else
         | 
| 78 | 
            +
                                   59
         | 
| 79 | 
            +
                                 end
         | 
| 80 | 
            +
                    (start.min..finish_min).each { |min| times << [hour, min] }
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                  times
         | 
| 83 | 
            +
                end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                def to_time_of_day(number_or_day)
         | 
| 86 | 
            +
                  return number_or_day if number_or_day.is_a?(TimeOfDay)
         | 
| 87 | 
            +
                  if number_or_day.is_a?(Time)
         | 
| 88 | 
            +
                    return TimeOfDay.new(number_or_day.hour, number_or_day.min)
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  TimeOfDay.new(number_or_day)
         | 
| 24 92 | 
             
                end
         | 
| 25 93 | 
             
              end
         | 
| 26 94 | 
             
            end
         | 
| @@ -3,9 +3,13 @@ | |
| 3 3 | 
             
            module Blackcal
         | 
| 4 4 | 
             
              # Time range
         | 
| 5 5 | 
             
              class TimeRange
         | 
| 6 | 
            +
                include Enumerable
         | 
| 7 | 
            +
             | 
| 6 8 | 
             
                attr_reader :start, :finish
         | 
| 7 9 |  | 
| 8 10 | 
             
                # Initialize time range
         | 
| 11 | 
            +
                # @param [Time, nil] start_time
         | 
| 12 | 
            +
                # @param [Time, nil] finish_time optional
         | 
| 9 13 | 
             
                def initialize(start_time, finish_time = nil)
         | 
| 10 14 | 
             
                  @start = start_time
         | 
| 11 15 | 
             
                  @finish = finish_time
         | 
| @@ -23,5 +27,23 @@ module Blackcal | |
| 23 27 |  | 
| 24 28 | 
             
                  false
         | 
| 25 29 | 
             
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                # Returns range as array
         | 
| 32 | 
            +
                # @param resolution [Symbol] :hour our :min
         | 
| 33 | 
            +
                # @return [Array<Array<Integer>>] times
         | 
| 34 | 
            +
                def to_a(resolution: :hour)
         | 
| 35 | 
            +
                  resolution_multiplier = resolution == :hour ? 60 * 60 : 60
         | 
| 36 | 
            +
                  time_units = ((start - finish) / resolution_multiplier).abs.to_i
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  time_units.times.map do |time_unit|
         | 
| 39 | 
            +
                    start + (time_unit * resolution_multiplier)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                # Iterate over range
         | 
| 44 | 
            +
                # @param resolution [Symbol] :hour our :min
         | 
| 45 | 
            +
                def each(resolution: :hour, &block)
         | 
| 46 | 
            +
                  to_a(resolution: resolution).each(&block)
         | 
| 47 | 
            +
                end
         | 
| 26 48 | 
             
              end
         | 
| 27 49 | 
             
            end
         | 
| @@ -3,6 +3,9 @@ | |
| 3 3 | 
             
            module Blackcal
         | 
| 4 4 | 
             
              # Weekday range
         | 
| 5 5 | 
             
              class WeekdayRange
         | 
| 6 | 
            +
                include Enumerable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Map weekday name to number
         | 
| 6 9 | 
             
                WEEKDAY_MAP = {
         | 
| 7 10 | 
             
                  sunday: 0,
         | 
| 8 11 | 
             
                  monday: 1,
         | 
| @@ -35,5 +38,14 @@ module Blackcal | |
| 35 38 | 
             
                    WEEKDAY_MAP.fetch(weekday) == timestamp.wday
         | 
| 36 39 | 
             
                  end
         | 
| 37 40 | 
             
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                # @return [Array<Symbol>] weekdays in range
         | 
| 43 | 
            +
                alias_method :to_a, :weekdays
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                # Iterate over range
         | 
| 46 | 
            +
                # @see #to_a
         | 
| 47 | 
            +
                def each(&block)
         | 
| 48 | 
            +
                  to_a.each(&block)
         | 
| 49 | 
            +
                end
         | 
| 38 50 | 
             
              end
         | 
| 39 51 | 
             
            end
         | 
    
        data/lib/blackcal/schedule.rb
    CHANGED
    
    | @@ -15,11 +15,16 @@ module Blackcal | |
| 15 15 | 
             
                # Initialize rule
         | 
| 16 16 | 
             
                # @param start_time [Time, Date, String, nil]
         | 
| 17 17 | 
             
                # @param finish_time [Time, Date, String, nil]
         | 
| 18 | 
            -
                # @param start_hour [Integer, nil]
         | 
| 19 | 
            -
                # @param finish_hour [Integer, nil]
         | 
| 18 | 
            +
                # @param start_hour [TimeOfDay, Time, Integer, nil]
         | 
| 19 | 
            +
                # @param finish_hour [TimeOfDay, Time, Integer, nil]
         | 
| 20 20 | 
             
                # @param months [Array<String>, Array<Symbol>, String, Symbol, nil]
         | 
| 21 21 | 
             
                # @param weekdays [Array<String>, Array<Symbol>, String, Symbol, nil]
         | 
| 22 22 | 
             
                # @param days [Array<Integer>, Integer, nil]
         | 
| 23 | 
            +
                # @see TimeRange#initialize
         | 
| 24 | 
            +
                # @see TimeOfDayRange#initialize
         | 
| 25 | 
            +
                # @see MonthRange#initialize
         | 
| 26 | 
            +
                # @see WeekdayRange#initialize
         | 
| 27 | 
            +
                # @see DayRange#initialize
         | 
| 23 28 | 
             
                def initialize(
         | 
| 24 29 | 
             
                  start_time: nil,
         | 
| 25 30 | 
             
                  finish_time: nil,
         | 
| @@ -30,11 +35,25 @@ module Blackcal | |
| 30 35 | 
             
                  # weeks_of_month: nil, # TODO
         | 
| 31 36 | 
             
                  days: nil
         | 
| 32 37 | 
             
                )
         | 
| 33 | 
            -
                   | 
| 34 | 
            -
             | 
| 35 | 
            -
                   | 
| 36 | 
            -
             | 
| 37 | 
            -
                   | 
| 38 | 
            +
                  if start_time || finish_time
         | 
| 39 | 
            +
                    @rule_range = TimeRange.new(parse_time(start_time), parse_time(finish_time))
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  if start_hour || finish_hour
         | 
| 43 | 
            +
                    @time_of_day = TimeOfDayRange.new(start_hour, finish_hour)
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  if months
         | 
| 47 | 
            +
                    @months = MonthRange.new(months)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  if weekdays
         | 
| 51 | 
            +
                    @weekdays = WeekdayRange.new(weekdays)
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  if days
         | 
| 55 | 
            +
                    @days = DayRange.new(days)
         | 
| 56 | 
            +
                  end
         | 
| 38 57 | 
             
                end
         | 
| 39 58 |  | 
| 40 59 | 
             
                # Returns true if calendar is open for timestamp
         | 
| @@ -42,28 +61,29 @@ module Blackcal | |
| 42 61 | 
             
                # @return [Boolean]
         | 
| 43 62 | 
             
                def cover?(timestamp)
         | 
| 44 63 | 
             
                  timestamp = parse_time(timestamp)
         | 
| 45 | 
            -
                  return  | 
| 64 | 
            +
                  return false if @rule_range && !@rule_range.cover?(timestamp)
         | 
| 46 65 |  | 
| 47 | 
            -
                  [@months, @weekdays, @days, @time_of_day]. | 
| 48 | 
            -
             | 
| 49 | 
            -
                  end
         | 
| 66 | 
            +
                  ranges = [@months, @weekdays, @days, @time_of_day].compact
         | 
| 67 | 
            +
                  return false if ranges.empty?
         | 
| 50 68 |  | 
| 51 | 
            -
                   | 
| 69 | 
            +
                  ranges.all? { |range| range.cover?(timestamp) }
         | 
| 52 70 | 
             
                end
         | 
| 53 71 |  | 
| 54 72 | 
             
                # Returns schedule represented as a matrix
         | 
| 55 73 | 
             
                # @param start_date [Date]
         | 
| 56 74 | 
             
                # @param finish_date [Date]
         | 
| 57 75 | 
             
                # @return [Array<Array<Boolean>>]
         | 
| 58 | 
            -
                def to_matrix(start_date:, finish_date:)
         | 
| 76 | 
            +
                def to_matrix(start_date:, finish_date:, resolution: :hour)
         | 
| 59 77 | 
             
                  start_time = parse_time(start_date).to_time
         | 
| 60 78 | 
             
                  finish_time = parse_time(finish_date).to_time
         | 
| 61 | 
            -
                   | 
| 79 | 
            +
                  slots = resolution == :hour ? 24 : 24 * 60
         | 
| 80 | 
            +
                  matrix = SlotMatrix.new(slots)
         | 
| 62 81 |  | 
| 63 82 | 
             
                  # TODO: This is needlessly inefficient..
         | 
| 64 | 
            -
                   | 
| 65 | 
            -
                   | 
| 66 | 
            -
             | 
| 83 | 
            +
                  time_range = TimeRange.new(start_time, finish_time)
         | 
| 84 | 
            +
                  time_range.each(resolution: resolution) do |time|
         | 
| 85 | 
            +
                    matrix << cover?(time)
         | 
| 86 | 
            +
                  end
         | 
| 67 87 |  | 
| 68 88 | 
             
                  matrix.data
         | 
| 69 89 | 
             
                end
         | 
    
        data/lib/blackcal/slot_matrix.rb
    CHANGED
    
    
| @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Blackcal
         | 
| 4 | 
            +
              # Represents a time of day (hour and min)
         | 
| 5 | 
            +
              class TimeOfDay
         | 
| 6 | 
            +
                include Comparable
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # @return [Integer] hour
         | 
| 9 | 
            +
                attr_reader :hour
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                # @return [Integer] minutes defaults to 0
         | 
| 12 | 
            +
                attr_reader :min
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # Initialize time of day
         | 
| 15 | 
            +
                # @param [Integer] hour
         | 
| 16 | 
            +
                # @param [Integer, nil] min optional argument
         | 
| 17 | 
            +
                def initialize(hour, min = nil)
         | 
| 18 | 
            +
                  @hour = hour
         | 
| 19 | 
            +
                  @min = min || 0
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # Compares two time of days
         | 
| 23 | 
            +
                # @param [TimeOfDay, Integer] other if a number is passed it will be used as the hour
         | 
| 24 | 
            +
                # @return [Integer] 1 if greater than, 0 if equal, -1 if less than
         | 
| 25 | 
            +
                def <=>(other)
         | 
| 26 | 
            +
                  other_seconds = if other.is_a?(self.class)
         | 
| 27 | 
            +
                                    (other.hour * 60 * 60) + (other.min * 60)
         | 
| 28 | 
            +
                                  else
         | 
| 29 | 
            +
                                    other * 60 * 60
         | 
| 30 | 
            +
                                  end
         | 
| 31 | 
            +
                  seconds = (hour * 60 * 60) + (min * 60)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  seconds <=> other_seconds
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
            end
         | 
    
        data/lib/blackcal/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,15 +1,57 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: blackcal
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.3.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Jacob Burenstam
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2018-09- | 
| 11 | 
            +
            date: 2018-09-16 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: github-markup
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '2.0'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '2.0'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: redcarpet
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '3.4'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '3.4'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: simplecov
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - "~>"
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: '0.16'
         | 
| 48 | 
            +
              type: :development
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - "~>"
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: '0.16'
         | 
| 13 55 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 56 | 
             
              name: bundler
         | 
| 15 57 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -79,6 +121,7 @@ files: | |
| 79 121 | 
             
            - ".rubocop.yml"
         | 
| 80 122 | 
             
            - ".ruby-style-guide.yml"
         | 
| 81 123 | 
             
            - ".travis.yml"
         | 
| 124 | 
            +
            - ".yardopts"
         | 
| 82 125 | 
             
            - CHANGELOG.md
         | 
| 83 126 | 
             
            - Gemfile
         | 
| 84 127 | 
             
            - LICENSE.txt
         | 
| @@ -95,6 +138,7 @@ files: | |
| 95 138 | 
             
            - lib/blackcal/range/weekday_range.rb
         | 
| 96 139 | 
             
            - lib/blackcal/schedule.rb
         | 
| 97 140 | 
             
            - lib/blackcal/slot_matrix.rb
         | 
| 141 | 
            +
            - lib/blackcal/time_of_day.rb
         | 
| 98 142 | 
             
            - lib/blackcal/version.rb
         | 
| 99 143 | 
             
            homepage: https://github.com/buren/blackcal
         | 
| 100 144 | 
             
            licenses:
         |