loadshedding 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 42bf4bc279ad510d7501df68db0dadd3e33e5904
4
+ data.tar.gz: 723dea0d56f69444571a36049d0569381efe29ab
5
+ SHA512:
6
+ metadata.gz: 206fb610c9e867d879f12c39e24146003bada0a73cf668c18360b7fac6ddde70ff94cb9c5986032bb76f82abc610a7af0bd9ddfedf9b9045e6147c4d9b942d99
7
+ data.tar.gz: 7c4bdcda3e749eb913d4af3e207df738941642741bea1559c16c47afcb48d58260a98bcb668df01ec999317e0864e8f234aa044f36777c6444a7b1fae382b56a
data/bin/schedule ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'downloader'
4
+ require 'schedule'
5
+ require 'schedule_parser'
6
+ require 'group_scheduler'
7
+ require 'schedule_formatter'
8
+ require 'week_day'
9
+ require 'config_loader'
10
+ require 'byebug' #TODO: REMOVE BEFORE PUBLISHING
11
+ require 'httparty'
12
+ require 'optparse'
13
+ require 'ostruct'
14
+ require 'interfacer'
15
+ require 'day_finder'
16
+ require 'colorize'
17
+ require 'timer'
18
+
19
+ options = OpenStruct.new
20
+ option_parser = OptionParser.new do |opt|
21
+ opt.on('-g', '--group group_number', 'The group number') { |o| options.group = o }
22
+ opt.on('-w', '--week_day Weekday ', 'The day number in work week 1 being monday') { |o| options.week_day = o }
23
+ opt.on('-c', '--configure', 'Set the day number as default in work week 1 being monday') { |o| options.set_group = true }
24
+ end
25
+
26
+ option_parser.parse!
27
+
28
+
29
+ day_finder = DayFinder.new
30
+ date = day_finder.find_week_day(options.week_day.to_i)
31
+ ConfigLoader.set_group if options.set_group
32
+ group = options.group || ConfigLoader.load_group
33
+
34
+ schedule = Schedule.new
35
+ schedule = schedule.schedule_for date, group
36
+
37
+ formattor = ScheduleFormatter.new(schedule, date, group)
38
+ formattor.format
39
+ puts formattor.formatted_result.colorize(formattor.color)
40
+
@@ -0,0 +1,26 @@
1
+ class ConfigLoader
2
+ CONFIG_FILE=File.expand_path('~/.load_shedding_config')
3
+ class << self
4
+ def load_group
5
+ klass = File.exists?(CONFIG_FILE) ? self : Interfacer
6
+ obj = klass.new
7
+ group = obj.find_group
8
+ obj.persist(group, CONFIG_FILE) if obj.respond_to?(:persist)
9
+ group
10
+ end
11
+
12
+ def set_group
13
+ obj = Interfacer.new
14
+ group = obj.find_group
15
+ obj.persist(group,CONFIG_FILE)
16
+ end
17
+ end
18
+
19
+
20
+ def find_group
21
+ File.read(CONFIG_FILE)
22
+ end
23
+
24
+ end
25
+
26
+
data/lib/day_finder.rb ADDED
@@ -0,0 +1,24 @@
1
+ class DayFinder
2
+ def initialize
3
+ end
4
+
5
+ def find_week_day(week_day)
6
+ week_day==0 ? Date.today.cwday : validate_week_day(week_day)
7
+ end
8
+
9
+ def validate_week_day(week_day)
10
+ (1..7).cover?(week_day) ? week_day : invalid_week_day
11
+ end
12
+
13
+ def adjusted_week_date(week_day)
14
+ today = Date.today.cwday
15
+ difference = (today - week_day)
16
+ Date.today - difference
17
+ end
18
+
19
+ private
20
+ def invalid_week_day
21
+ puts "invalid week day supplied".colorize(:yellow).colorize(:background => :red)
22
+ abort
23
+ end
24
+ end
data/lib/downloader.rb ADDED
@@ -0,0 +1,28 @@
1
+ class Downloader
2
+
3
+ DOWNLOAD_PATH = 'https://acpmasquerade-nepal-loadshedding-schedule-by-sparrow-sms.p.mashape.com/schedule.php'
4
+ API_KEY = '8ibMI63bqPmshv9aq5XoZtwTDNxBp11nUMNjsnVVa3A88wMy1E'
5
+ HEADER = 'X-Mashape-Key'
6
+ INSTALL_PATH = File.expand_path('~/.schedule.yml')
7
+ attr_reader :path, :schedule_json
8
+
9
+ def initialize(download_path=nil)
10
+ @path ||= download_path || DOWNLOAD_PATH
11
+ @schedule_json = Hash.new
12
+ end
13
+
14
+ def download
15
+ (1..7).each do |group|
16
+ group_schedule = download_for_group(group)
17
+ @schedule_json.merge!({group => group_schedule})
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def download_for_group group
24
+ result = HTTParty.get(DOWNLOAD_PATH, verify: false ,query: {format: :json, group: group}, headers: {HEADER => API_KEY})
25
+ parsed_data = JSON.parse(result.parsed_response)
26
+ parsed_data["schedule"]
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ class GroupSchedule
2
+
3
+ attr_reader :group_schedule
4
+
5
+ def initialize group
6
+ @group = validate_group(group)
7
+ @group_schedule = load_schedule
8
+ end
9
+
10
+ def day_schedule week_day
11
+ week_day_obj = Weekday.new(week_day)
12
+ group_schedule[week_day_obj.symbol]
13
+ end
14
+
15
+ private
16
+
17
+ def validate_group(group)
18
+ (1..7).cover?(group.to_i) ? group : invalid_group
19
+ end
20
+
21
+ def load_schedule
22
+ p = ScheduleParser.new(Downloader::INSTALL_PATH)
23
+ p.parse
24
+ @group_schedule = p.group_schedule(@group)
25
+ end
26
+
27
+ def invalid_group
28
+ puts "Invalid group number supplied".colorize(:yellow).colorize(:background => :red)
29
+ abort
30
+ end
31
+ end
data/lib/interfacer.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'highline'
2
+ class Interfacer
3
+
4
+ def initialize
5
+ @cli_handler = HighLine.new
6
+ end
7
+
8
+ def find_group
9
+ @cli_handler.ask "Please enter your group number."
10
+ end
11
+
12
+ def persist(group, file)
13
+ File.open(file,'w') do |f|
14
+ f.write(group)
15
+ end
16
+ end
17
+ end
File without changes
data/lib/schedule.rb ADDED
@@ -0,0 +1,9 @@
1
+ class Schedule
2
+
3
+ def schedule_for date, group
4
+ group_schedule = GroupSchedule.new(group)
5
+ group_schedule.day_schedule date
6
+ end
7
+
8
+
9
+ end
@@ -0,0 +1,44 @@
1
+ class ScheduleFormatter
2
+ attr_reader :formatted_result, :color
3
+
4
+ def initialize unformatted_hash, date, group
5
+ @unformatted_hash = unformatted_hash
6
+ @date = find_date(date)
7
+ @formatted_result
8
+ @group = group
9
+ @current_status = set_timer
10
+ @color = set_color
11
+ end
12
+
13
+ def format
14
+ @formatted_result = <<-EOS
15
+
16
+ Load Shedding Schedule for #{@date} : #{@date.strftime('%A')}
17
+ Group Number : #{@group}
18
+ Morning : #{@unformatted_hash.first}
19
+ Evening : #{@unformatted_hash.last}
20
+ Currently: #{@current_status.status} : #{@current_status.alt_status} in #{@current_status.time_to_change}
21
+ EOS
22
+ end
23
+
24
+ private
25
+ def set_color
26
+ @current_status.status == "Off" ? :red : :green
27
+ end
28
+
29
+ def set_timer
30
+ morning_hours_range = range_from_array @unformatted_hash.first.values.map(&:to_i)
31
+ evening_hours_range = range_from_array @unformatted_hash.last.values.map(&:to_i)
32
+ Timer.new(morning_hours_range, evening_hours_range)
33
+ end
34
+
35
+ def range_from_array(array)
36
+ Range.new(array.first, array.last)
37
+ end
38
+
39
+ def find_date(date)
40
+ day_finder = DayFinder.new
41
+ date = day_finder.find_week_day date
42
+ day_finder.adjusted_week_date(date)
43
+ end
44
+ end
@@ -0,0 +1,50 @@
1
+ class ScheduleParser
2
+ attr_reader :schedule_yaml, :result_hash
3
+
4
+ def initialize schedule_path
5
+ @schedule_yaml = schedule_path
6
+ @result_hash = Hash.new
7
+ end
8
+
9
+ def parse
10
+ confirm_file
11
+ parse_from_file(schedule_yaml)
12
+ end
13
+
14
+ def group_schedule(group)
15
+ group = group.to_i
16
+ result_hash[group]
17
+ end
18
+
19
+ private
20
+
21
+ def confirm_file
22
+ unless File.exists?(schedule_yaml)
23
+ download
24
+ store_to_file
25
+ end
26
+ end
27
+
28
+ def download
29
+ d = Downloader.new
30
+ d.download
31
+ @result_hash = d.schedule_json
32
+ end
33
+
34
+ def parse_from_file(schedule_yaml)
35
+ @result_hash = YAML.load(File.read(schedule_yaml))
36
+ needs_update?
37
+ end
38
+
39
+ def needs_update?
40
+ date = @result_hash['date']
41
+ download if (Date.today - date).to_i > 7
42
+ end
43
+
44
+ def store_to_file
45
+ File.open(schedule_yaml, 'w') do |f|
46
+ result_hash.merge!({'date' => Date.today})
47
+ f.write(result_hash.to_yaml)
48
+ end
49
+ end
50
+ end
data/lib/timer.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'time_diff'
2
+
3
+ class Timer
4
+ attr_reader :status, :alt_status, :time_to_change
5
+ def initialize(morning_range, evening_range)
6
+ @morning_range = morning_range
7
+ @evening_range = evening_range
8
+ @current_time = Time.now
9
+ @time_to_change = find_remaining_time
10
+ @status = find_status
11
+ @alt_status = alternate_status
12
+ end
13
+
14
+
15
+
16
+
17
+ private
18
+
19
+ def alternate_status
20
+ currently_off? ? "On" : "Off"
21
+ end
22
+
23
+ def find_status
24
+ currently_off? ? "Off" : "On"
25
+ end
26
+
27
+ def currently_off?
28
+ @morning_range.cover?(@current_time.hour) || @evening_range.cover?(@current_time.hour)
29
+ end
30
+
31
+
32
+ def find_remaining_time
33
+ if currently_off?
34
+ time = time_to_on
35
+ else
36
+ time = time_to_off
37
+ end
38
+ " #{time[:hour]} hour : #{time[:minute]} minutes "
39
+ end
40
+
41
+ def time_to_on
42
+ if @morning_range.cover?(@current_time.hour)
43
+ t = change_to_time(@morning_range.last)
44
+ else
45
+ t = change_to_time(@evening_range.last)
46
+ end
47
+ diff = time_difference(t)
48
+ end
49
+
50
+ def time_to_off
51
+ upcoming_hours = [@morning_range.first, @morning_range.last, @evening_range.first, @evening_range.last].delete_if{|a| a < @current_time.hour}
52
+ closest_hour = upcoming_hours.min_by {|x| (x - @current_time.hour)}
53
+ t = change_to_time(closest_hour)
54
+ diff = time_difference(t)
55
+ end
56
+
57
+ def time_difference(t)
58
+ time_difference_components = Time.diff(@current_time , t)
59
+ end
60
+
61
+ def change_to_time(hour)
62
+ Time.parse("#{hour}:00",Time.now)
63
+ end
64
+
65
+
66
+ end
67
+
data/lib/week_day.rb ADDED
@@ -0,0 +1,13 @@
1
+ class Weekday
2
+
3
+ attr_reader :week_day
4
+
5
+ def initialize(week_day)
6
+ @week_day = week_day
7
+ @mapping = {7 => "Su", 1 => 'M', 2=> "Tu", 3 => "W", 4 => "Th", 5 => "F", 6 => "Sa"}
8
+ end
9
+
10
+ def symbol
11
+ @mapping[week_day]
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loadshedding
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kapil Raj Nakhwa (@xecutioner303)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.19.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.19.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.7'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 1.7.2
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '1.7'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.7.2
47
+ - !ruby/object:Gem::Dependency
48
+ name: colorize
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: 0.7.7
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.7.7
61
+ - !ruby/object:Gem::Dependency
62
+ name: httparty
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.13.7
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.13.7
75
+ - !ruby/object:Gem::Dependency
76
+ name: time_diff
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.3.0
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.3.0
89
+ description: Command line utility for checking the loadshedding schedule for Nepal
90
+ email: kapilnakhwa@gmail.com
91
+ executables:
92
+ - schedule
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - bin/schedule
97
+ - lib/config_loader.rb
98
+ - lib/day_finder.rb
99
+ - lib/downloader.rb
100
+ - lib/group_scheduler.rb
101
+ - lib/interfacer.rb
102
+ - lib/loadshedding.rb
103
+ - lib/schedule.rb
104
+ - lib/schedule_formatter.rb
105
+ - lib/schedule_parser.rb
106
+ - lib/timer.rb
107
+ - lib/week_day.rb
108
+ homepage: https://github.com/xecutioner/loadshedding-schedule
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message: type schedule to get started
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.4.6
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Command line utility for loadshedding schedule
132
+ test_files: []
133
+ has_rdoc: