rhs-schedule 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5f4b56aac9c5af3965c8a84dac2647175e3bdeb
4
- data.tar.gz: cb30b9a7ad916b9b2c747f5631f4dc705dcd358a
3
+ metadata.gz: 45d9d22b1f06bf65d5f7f19cbb0f865696c07088
4
+ data.tar.gz: 83e50e970284e01b6812b0b35e0600fa0a0dcefa
5
5
  SHA512:
6
- metadata.gz: 76999fe34edc375a0a64ab1b406a78c7e29a1c921e217e75e6ae224b4c81f78406f900392cf431b06d392337823ed406aa70c3918811d817ee1fb8f7f149db1f
7
- data.tar.gz: 0362805402a3df7e53b294d395e55ca4152c0fbe515b0d7f23898f26f3ff1b6e39e5adf03cc57aea6aa9ceab224c323856c7a926f3a1f917595b2ef3b9342f02
6
+ metadata.gz: e4935fae5a8bb3fa729b7b5e49be49b18958aef622af9192a401ed0b055e10b44d6bcf5ceafde6e4eb97718a76b60a796cdfd96db41021c9b3132fc371337578
7
+ data.tar.gz: 26dc3d276c130f0a6b552ce4233389478a66d1324c1edeb09a630090071acb2b6b96fe7e150f770c71a04e90f01cc2f6e7d8389248f3b2f3133c318b797339c0
data/lib/rhs-schedule.rb CHANGED
@@ -3,8 +3,10 @@ require 'json'
3
3
 
4
4
  require_relative 'rhs-schedule/scheduleday'
5
5
  require_relative 'rhs-schedule/period'
6
+ require_relative 'rhs-schedule/exports'
7
+ require_relative 'rhs-schedule/errors'
6
8
 
7
- VERSION = '0.2.0'.freeze
9
+ VERSION = '0.3.0'.freeze
8
10
 
9
11
  # 05/25/16 08:50 AM
10
12
  DATE_FORMAT = '%m/%d/%y'.freeze
@@ -13,8 +15,14 @@ DATETIME_FORMAT = "#{DATE_FORMAT} #{TIME_FORMAT}".freeze
13
15
  EXCEPTIONS = ['0', '1', '2', '3', 'WEBEIM Scheduled', 'SIS Scheduled'].freeze
14
16
 
15
17
  class ScheduleSystem
18
+ include Exports
19
+
16
20
  attr_reader :schedule_days
17
21
 
22
+ # Creates a new ScheduleSystem by parsing the schedule text file passed to it.
23
+ # If it cannot read the file the program aborts.
24
+ #
25
+ # @param path [String] the path to the text file (not the folder!)
18
26
  def initialize(path)
19
27
  puts "Initializing Schedule System v#{VERSION}"
20
28
  abort "Cannot find schedule text file at '#{path}'. Please download it from http://intranet.regis.org/downloads/outlook_calendar_import/outlook_schedule_download.cfm." unless File.file? path
@@ -23,8 +31,13 @@ class ScheduleSystem
23
31
  @classdays = []
24
32
  @schedule_days = {}
25
33
  parse
34
+ super(self) # Initialize the exports with the parsed schedule
26
35
  end
27
36
 
37
+ # Gets the schedule day of the date passed.
38
+ #
39
+ # @param date [Date, DateTime] the date
40
+ # @return [String] the schedule day
28
41
  def get_sd date
29
42
  if date.is_a? DateTime
30
43
  @schedule_days[date]
@@ -34,102 +47,131 @@ class ScheduleSystem
34
47
  end
35
48
  end
36
49
 
50
+ # Displays formatted info on the current day, including it's schedule day and classes in order.
37
51
  def today
38
52
  #false_date = Date.strptime('05/20/16', DATE_FORMAT)
39
53
  @classdays.find { |cd| cd.schedule_day == @schedule_days[Date.parse(Time.now.to_s)]}
40
54
  #@classdays.find { |cd| cd.schedule_day == @schedule_days[false_date] }
41
55
  end
42
56
 
43
- def parse
44
- sds = [] # Schedule day lines
45
- ps = [] # Period lines
46
-
47
- File.open(@path, 'r') do |f|
48
- f.each_line do |line|
49
- next if line.include? 'Start Date' or line.strip.empty?
50
-
51
- # Split the line and remove all the unnecessary values
52
- values = line.split("\t")
53
-
54
- # Determine schedule day or period
55
- if line.include? ' Day'
56
- # Use only date and schedule day
57
- vital = [values[0], values[4]]
58
- sds << vital
59
- elsif values.length == 10
60
- # Use only date, start time, end time, class name, and location
61
- vital = [values[0], values[1], values[3], values[4], values[5]]
62
- ps << vital
63
- end
64
- end
57
+ # Outputs a JSON object of all class days and their schedule days into the given file.
58
+ #
59
+ # @param path [String] the file path
60
+ def to_json(path)
61
+ puts 'Exporting schedule days to JSON'
62
+ File.open(path,'w') do |f|
63
+ f.write(JSON.pretty_generate(@schedule.schedule_days))
65
64
  end
65
+ end
66
66
 
67
- puts "Found #{ps.length} periods for #{sds.length} class days"
67
+ private
68
+ def check_valid_schedule lines
69
+ # Check for headers
70
+ first_line = lines.first.strip
71
+ raise InvalidScheduleError, 'Correct headers are missing.' if first_line != 'Start Date Start Time End Date End Time Subject Location All day event Reminder on/off Show time as Categories'
68
72
 
69
- sds.each { |values| handle_schedule_day_line values }
70
- handled = [] # Holds what schedules have been made
71
- @schedule_days.each do |date, sd|
72
- next if handled.include? sd
73
+ # Check length of file
74
+ raise InvalidScheduleError, 'File has less than 200 lines.' if lines.length < 200
75
+
76
+ # Check if there are period lines and schedule day lines
77
+ expected = lines.length * 10 # Expected data over all split by tabs
78
+ actual = 0
79
+ lines.each { |l| actual += l.split("\t").length }
80
+ raise InvalidScheduleError, 'Not all lines are valid.' unless expected == actual
81
+ #raise InvalidScheduleError, 'Missing schedule day lines' unless lines
73
82
 
74
- lines = ps.find_all { |values| values[0] == date.strftime(DATE_FORMAT) }
75
- next if lines.empty?
76
- create_class_day sd, lines
77
- handled << sd
78
83
  end
79
- end
80
84
 
81
- def handle_schedule_day_line values
82
- date = Date.strptime(values[0], DATE_FORMAT)
83
- sd = values[1][0] # A Day -> A
84
- @schedule_days[date] = sd
85
- end
85
+ # Reads the schedule text file and parses each line to decide periods and schedule days.
86
+ def parse
87
+ sds = [] # Schedule day lines
88
+ ps = [] # Period lines
89
+
90
+ File.open(@path, 'r') do |f|
91
+ lines = f.read.split("\r")
92
+
93
+ check_valid_schedule lines
94
+
95
+ lines.each do |line|
96
+ next if line.include? 'Start Date' or line.strip.empty?
97
+
98
+ # Split the line and remove all the unnecessary values
99
+ values = line.split("\t")
100
+
101
+ # Determine schedule day or period
102
+ if line.include? ' Day'
103
+ # Use only date and schedule day
104
+ vital = [values[0], values[4]]
105
+ sds << vital
106
+ elsif values.length == 10
107
+ # Use only date, start time, end time, class name, and location
108
+ vital = [values[0], values[1], values[3], values[4], values[5]]
109
+ ps << vital
110
+ end
111
+ end
112
+ end
86
113
 
87
- def create_class_day sd, lines
88
- periods = []
89
- lines.each do |values|
90
- # [date, start time, end time, class name, location]
91
- course_title = values[3]
92
- start_time = DateTime.strptime(values[1], TIME_FORMAT)
93
- end_time = DateTime.strptime(values[2], TIME_FORMAT)
94
- location = values[4]
114
+ puts "Found #{ps.length} periods for #{sds.length} class days"
95
115
 
96
- periods << Period.new(course_title, start_time, end_time, location)
97
- end
116
+ sds.each { |values| handle_schedule_day_line values }
117
+ handled = [] # Holds what schedules have been made
118
+ @schedule_days.each do |date, sd|
119
+ next if handled.include? sd
98
120
 
99
- day = ScheduleDay.new(sd, periods)
100
- fill_periods day
101
- @classdays << day
102
- end
121
+ lines = ps.find_all { |values| values[0] == date.strftime(DATE_FORMAT) }
122
+ next if lines.empty?
123
+ create_class_day sd, lines
124
+ handled << sd
125
+ end
126
+ end
103
127
 
104
- # Take a just created periods list and fill in the holes (lunch and frees)
105
- def fill_periods(day)
106
- old = day.periods
128
+ def handle_schedule_day_line values
129
+ date = Date.strptime(values[0], DATE_FORMAT)
130
+ sd = values[1][0] # A Day -> A
131
+ @schedule_days[date] = sd
132
+ end
107
133
 
108
- # AM Advisement isn't in schedule text file
109
- filled = [Period.new('Morning Advisement', DateTime.strptime('8:40 AM', TIME_FORMAT), DateTime.strptime('8:50 AM', TIME_FORMAT), 'Advisement')]
134
+ def create_class_day sd, lines
135
+ periods = []
136
+ lines.each do |values|
137
+ # [date, start time, end time, class name, location]
138
+ course_title = values[3]
139
+ start_time = DateTime.strptime(values[1], TIME_FORMAT)
140
+ end_time = DateTime.strptime(values[2], TIME_FORMAT)
141
+ location = values[4]
110
142
 
111
- last_end = filled.first.end_time # Don't use old.first since the day could start with a free period
112
- old.each do |p|
113
- filled << Period.new('Unstructured Time', last_end, p.start_time, 'Anywhere') if p.start_time != last_end # I <3 Ruby
143
+ periods << Period.new(course_title, start_time, end_time, location)
144
+ end
114
145
 
115
- filled << p
116
- last_end = p.end_time
146
+ day = ScheduleDay.new(sd, periods)
147
+ fill_periods day
148
+ @classdays << day
117
149
  end
118
150
 
119
- if filled.last.end_time.strftime('%I:%M %p') != '02:50 PM'
120
- end_time = DateTime.strptime('2:50 PM', TIME_FORMAT)
121
- filled << Period.new('Unstructured Time', filled.last.end_time, end_time, 'Anywhere')
122
- end
151
+ # Take a just created periods list and fill in the holes (lunch and frees)
152
+ def fill_periods(day)
153
+ old = day.periods
123
154
 
124
- # PM Advisement isn't in schedule text file
125
- filled << Period.new('Afternoon Advisement', DateTime.strptime('2:50 PM', TIME_FORMAT), DateTime.strptime('3:00 PM', TIME_FORMAT), 'Advisement')
126
- day.periods = filled
127
- end
155
+ # AM Advisement isn't in schedule text file
156
+ filled = [Period.new('Morning Advisement', DateTime.strptime('8:40 AM', TIME_FORMAT), DateTime.strptime('8:50 AM', TIME_FORMAT), 'Advisement')]
128
157
 
129
- def to_json(path)
130
- puts 'Exporting schedule days to JSON'
131
- File.open(path,'w') do |f|
132
- f.write(JSON.pretty_generate(@schedule.schedule_days))
158
+ last_end = filled.first.end_time # Don't use old.first since the day could start with a free period
159
+ old.each do |p|
160
+ filled << Period.new('Unstructured Time', last_end, p.start_time, 'Anywhere') if p.start_time != last_end # I <3 Ruby
161
+
162
+ filled << p
163
+ last_end = p.end_time
164
+ end
165
+
166
+ if filled.last.end_time.strftime('%I:%M %p') != '02:50 PM'
167
+ end_time = DateTime.strptime('2:50 PM', TIME_FORMAT)
168
+ filled << Period.new('Unstructured Time', filled.last.end_time, end_time, 'Anywhere')
169
+ end
170
+
171
+ # PM Advisement isn't in schedule text file
172
+ filled << Period.new('Afternoon Advisement', DateTime.strptime('2:50 PM', TIME_FORMAT), DateTime.strptime('3:00 PM', TIME_FORMAT), 'Advisement')
173
+ day.periods = filled
133
174
  end
134
- end
175
+
176
+
135
177
  end
@@ -13,6 +13,8 @@ class Period
13
13
  "#{@course_title} in #{@location} for #{duration} minutes"
14
14
  end
15
15
 
16
+ # Returns the duration of the period in minutes
17
+ # @return [Integer] duration in minutes
16
18
  def duration
17
19
  ((@end_time - @start_time) * 24 * 60).to_i
18
20
  end
@@ -9,14 +9,6 @@ class ScheduleDay
9
9
  @periods = periods
10
10
  end
11
11
 
12
- def add_period(period)
13
- @periods << period
14
- end
15
-
16
- def sort_periods
17
- @periods.sort! { |a, b| a.start_time <=> b.start_time }
18
- end
19
-
20
12
  def to_s
21
13
  to_return = ["#{@schedule_day}-Day: #{@periods.length} periods"]
22
14
  @periods.each do |p|
@@ -26,4 +18,13 @@ class ScheduleDay
26
18
 
27
19
  to_return.join("\n")
28
20
  end
21
+
22
+ private
23
+ def add_period(period)
24
+ @periods << period
25
+ end
26
+
27
+ def sort_periods
28
+ @periods.sort! { |a, b| a.start_time <=> b.start_time }
29
+ end
29
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhs-schedule
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Matranga