schedule-checker 0.0.4

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9adf8745c8e04282d98a235b0133b6641c23ce6c
4
+ data.tar.gz: 3e5a646261bf9436c0668bac97e7f346d40feadc
5
+ SHA512:
6
+ metadata.gz: 8d9eceedce95b4fbba1172984011d213a2bfc17fd5ac73044813beb6e49fd8a02fc112697ce186759afee4cc5e21221412066615ccffd4e91cbd953b167a2f9e
7
+ data.tar.gz: 7237505954b1800dba60416cdae16a601e0c67c68a938f70ee493a648e6cac98ca266931260bcd1c06df9065809cdebf8d647e2193a2e780c2390e6e16d78be5
@@ -0,0 +1,14 @@
1
+ require 'schedule-checker/schedule'
2
+
3
+ module ScheduleChecker
4
+
5
+ def self.parse_schedule_file(filename)
6
+ str = File.read(filename)
7
+ ScheduleChecker::Parser.new(str).schedule
8
+ end
9
+
10
+ def self.nonstop_schedule
11
+ ScheduleChecker::Schedule.nonstop
12
+ end
13
+
14
+ end
@@ -0,0 +1,87 @@
1
+ require 'schedule-checker/schedule'
2
+ require 'schedule-checker/session'
3
+ require 'schedule-checker/timepoint'
4
+ require 'yaml'
5
+
6
+ module ScheduleChecker
7
+
8
+ class Parser
9
+ attr_reader :config, :schedule
10
+
11
+ ALLOWED_KEYS = ["sessions","timezone"]
12
+
13
+ def initialize(s)
14
+ session_string_pairs = []
15
+ nonstop = false
16
+
17
+ @config = Parser.downcase_keys(YAML.load(s))
18
+
19
+ check_keys
20
+
21
+ is_utc = is_utc?
22
+
23
+ raise "no sessions specified" unless @config["sessions"] and @config["sessions"].length > 0
24
+
25
+ sessions = []
26
+ raise "sessions should be a list" unless @config["sessions"].is_a? Array
27
+
28
+ @config["sessions"].each do |session_string|
29
+ s = session_string.downcase.strip
30
+
31
+ #TODO - come back later and make this nonstop-session processing better
32
+ # Should probably have non-stop be a property of Session, not Schedule, and
33
+ # rely on Schedule to check for timed/nonstop session conflicts.
34
+
35
+ if ["nonstop","non-stop"].include?(s)
36
+ raise "config can't simultaneously be non-stop and have scheduled sessions" if sessions.length>0
37
+ nonstop = true
38
+ else
39
+ raise "config can't simultaneously be non-stop and have scheduled sessions" if nonstop
40
+ sessions << Parser.parse_session(s,is_utc)
41
+ end
42
+ end
43
+
44
+ if(nonstop)
45
+ @schedule = ScheduleChecker::Schedule.nonstop
46
+ else
47
+ @schedule = ScheduleChecker::Schedule.new
48
+ sessions.each{|s| @schedule.add_session(s)}
49
+ end
50
+ end
51
+
52
+ private
53
+ def self.downcase_keys(h)
54
+ rv = {}
55
+ h.each{|k,v| rv[k.downcase] = v }
56
+ rv
57
+ end
58
+
59
+ def check_keys
60
+ @config.keys.each{|k| raise "unsupported setting '#{k}'" unless ALLOWED_KEYS.include?(k) }
61
+ end
62
+
63
+ def is_utc?
64
+ return true unless @config.has_key?("timezone")
65
+ case @config["timezone"].downcase
66
+ when "utc"
67
+ true
68
+ when "local"
69
+ return false
70
+ else
71
+ raise "unsupported timezone value: #{s}"
72
+ end
73
+ end
74
+
75
+ def self.parse_session(s,is_utc)
76
+ raise "malformed session value: #{s}" unless s.include?("-")
77
+ starttime,endtime = s.split("-",2)
78
+ raise "malformed session value: #{s}" if starttime.nil? or endtime.nil?
79
+ starttime.strip!
80
+ endtime.strip!
81
+ ScheduleChecker::Session.new(
82
+ ScheduleChecker::Timepoint.from_string(starttime,is_utc),
83
+ ScheduleChecker::Timepoint.from_string(endtime,is_utc))
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,33 @@
1
+ require 'schedule-checker/parser'
2
+ require 'schedule-checker/session'
3
+
4
+ module ScheduleChecker
5
+ class Schedule
6
+ attr_reader :sessions,:nonstop
7
+
8
+ def initialize(nonstop=false)
9
+ @sessions = [] # Session objects
10
+ @nonstop = nonstop
11
+ end
12
+
13
+ def self.nonstop
14
+ ScheduleChecker::Schedule.new(true)
15
+ end
16
+
17
+ def add_session(session)
18
+ raise "can't add to a non-stop schedule" if @nonstop
19
+
20
+ if self.in_a_session?(session.startpoint) || self.in_a_session?(session.endpoint)
21
+ raise "new session overlaps with existing session"
22
+ end
23
+ @sessions << session
24
+ end
25
+
26
+ def in_a_session?(t) # t is a timestamp
27
+ return true if @nonstop
28
+ @sessions.each{|s| return true if s.in_session?(t) }
29
+ false
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ module ScheduleChecker
2
+ class Session
3
+ attr_reader :startpoint,:endpoint
4
+
5
+ def initialize(startpoint,endpoint)
6
+ @startpoint = startpoint
7
+ @endpoint = endpoint
8
+ end
9
+
10
+ def in_session?(t) #t is a timestamp or Timepoint
11
+ if startpoint.gt(endpoint)
12
+ return startpoint.lte(t) || endpoint.gt(t)
13
+ end
14
+ startpoint.lte(t) && endpoint.gt(t)
15
+ end
16
+
17
+ def to_s
18
+ "Session:#{startpoint.to_s}-#{endpoint.to_s}"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,66 @@
1
+ module ScheduleChecker
2
+ class Timepoint
3
+ attr_reader :normalized_ts
4
+
5
+ # day: 0-6 for Sunday-Saturday
6
+ # hour: 0-24
7
+ def initialize(day,hour,minute,second,is_utc=true)
8
+ raise "invalid day (must be 0-6, 0 is Monday)" unless (0..6).to_a.include?(day)
9
+ @normalized_ts = is_utc ?
10
+ Time.utc(2012,1,day+1,hour,minute,second) :
11
+ Time.local(2012,1,day+1,hour,minute,second).getutc
12
+ end
13
+
14
+ def self.from_string(s,is_utc=true)
15
+ raise "bad format '#{s}'" unless s.match(/^\w\w\w[\w]*\/\d\d:\d\d:\d\d$/)
16
+ day_str,time_str = s.split("/")
17
+ day = ScheduleChecker::Timepoint.day_str_to_i(day_str)
18
+ h,m,s = time_str.split(":")
19
+ ScheduleChecker::Timepoint.new(day,h.to_i,m.to_i,s.to_i,is_utc)
20
+ end
21
+
22
+ def normalized_ts_as_local
23
+ @normalized_ts.get_local
24
+ end
25
+
26
+ def to_s
27
+ @normalized_ts.strftime("#{wday_abbrev}/%H:%M:%S")
28
+ end
29
+
30
+ def lte(t)
31
+ #only cares about wday and time
32
+ x = t.is_a?(ScheduleChecker::Timepoint) ? t.normalized_ts : ScheduleChecker::Timepoint.normalize_timestamp(t)
33
+ self.normalized_ts <= x
34
+ end
35
+
36
+ def gt(t)
37
+ #only cares about wday and time
38
+ x = t.is_a?(ScheduleChecker::Timepoint) ? t.normalized_ts : ScheduleChecker::Timepoint.normalize_timestamp(t)
39
+ self.normalized_ts > x
40
+ end
41
+
42
+ def self.normalize_timestamp(ts)
43
+ x = ts.getutc
44
+ ScheduleChecker::Timepoint.new(x.wday,x.hour,x.min,x.sec).normalized_ts
45
+ end
46
+
47
+ DAYS = ["sun","mon","tue","wed","thu","fri","sat"]
48
+ def self.pretty_day(n)
49
+ raise "Illegal day int '#{n}'" unless (0..6).to_a.include?(n)
50
+ DAYS[n].capitalize
51
+ end
52
+
53
+ def self.day_str_to_i(str)
54
+ d = str.downcase.slice(0,3)
55
+ rv = DAYS.find_index(d)
56
+ raise "Illegal day string '#{str}'" unless rv
57
+ rv
58
+ end
59
+
60
+ private
61
+ def wday_abbrev
62
+ ScheduleChecker::Timepoint.pretty_day(@normalized_ts.wday)
63
+ end
64
+
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schedule-checker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Grant Birchmeier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: grant@grantb.net
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/schedule-checker.rb
20
+ - lib/schedule-checker/parser.rb
21
+ - lib/schedule-checker/schedule.rb
22
+ - lib/schedule-checker/session.rb
23
+ - lib/schedule-checker/timepoint.rb
24
+ homepage: http://github.com/gbirchmeier/schedule-checker
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.2.2
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: A simple file format and module for specifying a weekly schedule of sessions
48
+ and checking if a given time is within a session or not.
49
+ test_files: []
50
+ has_rdoc: