open_hours 0.0.2

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: a6f8f536435f8ad892773bfd9fe96de0143f8441
4
+ data.tar.gz: 35f3c93fc1d76be1b0e1bd4be1200caaf15e733d
5
+ SHA512:
6
+ metadata.gz: 6ed6fd97c3ea35c1868e0db631b8a97454994d269352a0e9d328f2b45bec12124288cab690ee8112b6a3911c17633e85d1a81f2799682f3de2961890f3a5b291
7
+ data.tar.gz: db19438117d15fb5feeb0b995579077b0174d7894105dad38ee5f5ae4a6c39f12affab298b9039cbd8589b322c9889974c5680f60e772908b253185c29924d4d
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ vendor/bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in opening_hours.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # OpenHours
2
+
3
+ Library that parses date ranges in the openingHours format https://schema.org/openingHours.
4
+
5
+ The main use for this is to take a set of openingHours rules and then find out if the place is open at a specific time.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'opening_hours'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install opening_hours
20
+
21
+ ## Usage
22
+
23
+ ### With just one openingHours rule
24
+
25
+ ```ruby
26
+ one_day = "Mo 08:00-16:30"
27
+ op = OpeningHours.parse(one_day)
28
+
29
+ op.class #=> OpeningHours::OpenHours
30
+
31
+ time = DateTime.parse("Monday, June 14 2014 08:00")
32
+ op.open_at?(time) #=> true
33
+
34
+ time = DateTime.parse("Tuesday, June 14 2014 08:00")
35
+ op.open_at?(time) #=> false
36
+ ```
37
+
38
+ ### With a range of openingHours rules
39
+
40
+ ```ruby
41
+ multi_day = ["Mo-Th 08:00-16:30", "Fr 08:00-16:00"]
42
+ op = OpeningHours.parse(multi_day)
43
+
44
+ op.class #=> OpeningHours::OpenHours
45
+
46
+ time = DateTime.parse("Monday, June 14 2014 08:00")
47
+ op.open_at?(time) #=> true
48
+
49
+ time = DateTime.parse("Monday, June 14 2014 07:59")
50
+ op.open_at?(time) #=> false
51
+
52
+ time = DateTime.parse("Monday, June 14 2014 16:30")
53
+ op.open_at?(time) #=> true
54
+
55
+ time = DateTime.parse("Monday, June 14 2014 16:31")
56
+ op.open_at?(time) #=> false
57
+
58
+ time = DateTime.parse("Saturday, June 19 2014 08:30")
59
+ op.open_at?(time) #=> false
60
+ ```
61
+
62
+ ## Limitations
63
+
64
+ This gem is in early days. There are parts of the openingHours spec it doesn't handle. Such as,
65
+
66
+ - Comma-separated days (ex: "Mo,Th")
67
+ - The shorthand "Mo-Su" to define being open 24 hours a day, 7 days a week
68
+ - Hours for a specific day that override the normal hours for that day.
69
+ - This functionality is part of [openingHoursSpecfication](http://schema.org/OpeningHoursSpecification), so may not ever be implemented in this gem.
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it ( https://github.com/[my-github-username]/opening_hours/fork )
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
6
+
@@ -0,0 +1,3 @@
1
+ module OpenHours
2
+ VERSION = "0.0.2"
3
+ end
data/lib/open_hours.rb ADDED
@@ -0,0 +1,106 @@
1
+ require "open_hours/version"
2
+ require "ostruct"
3
+
4
+ module OpeningHours
5
+ def self.parse(params)
6
+ OpenHours.new(params)
7
+ end
8
+
9
+ class OpenHours
10
+ def initialize(params)
11
+ params = Array(params)
12
+ check_params(params)
13
+
14
+ params.each do |param|
15
+ param_values = parse_param(param)
16
+ param_values.days.each do |day|
17
+ open_time = time_parse(param_values.times[0])
18
+ close_time = time_parse(param_values.times[1])
19
+ open_hours[valid_days.index(day)] << (open_time..close_time)
20
+ end
21
+ end
22
+ self
23
+ end
24
+
25
+ def open_at?(date_time)
26
+ dt = date_time.to_datetime
27
+ day = dt.wday
28
+ time = dt.strftime("%H:%M")
29
+ time = time_parse(time)
30
+ if open_hours[day]
31
+ open_hours[day].any? {|x| x.cover?(time) }
32
+ else
33
+ false
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def check_params(params)
40
+ params.each do |param|
41
+ day_and_time = param.split(' ')
42
+ raise ArgumentError unless day_and_time.count == 2
43
+
44
+ day_range = day_and_time[0]
45
+ time_range = day_and_time[1]
46
+
47
+ days = day_range.split('-')
48
+
49
+ raise ArgumentError unless (1..2).cover?(days.count)
50
+
51
+ days.each do |day|
52
+ raise ArgumentError unless valid_days.include?(day)
53
+ end
54
+
55
+ times = time_range.split('-')
56
+
57
+ raise ArgumentError unless times.count == 2
58
+
59
+ times.each do |time|
60
+ raise ArgumentError unless time.match(/\d\d:\d\d/)
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ def parse_param(param)
67
+ day_and_time = param.split(' ')
68
+ day_range = day_and_time[0]
69
+ time_range = day_and_time[1]
70
+
71
+ days = day_range.split('-')
72
+
73
+ if day_range.include?('-') && days.count == 2
74
+ start_day = valid_days.index(days[0])
75
+ end_day = valid_days.index(days[1])
76
+ days = valid_days[start_day..end_day]
77
+ end
78
+
79
+ days.each do |day|
80
+ unless open_hours[valid_days.index(day)]
81
+ open_hours[valid_days.index(day)] = []
82
+ end
83
+ end
84
+
85
+ times = time_range.split('-')
86
+ x = OpenStruct.new
87
+ x.times = times
88
+ x.days = days
89
+ x
90
+ end
91
+
92
+
93
+ def open_hours
94
+ @open_hours ||= {}
95
+ end
96
+
97
+ def time_parse(t)
98
+ t = Time.parse(t)
99
+ (t.hour * 60) + t.min
100
+ end
101
+
102
+ def valid_days
103
+ %w(Su Mo Tu We Th Fr Sa)
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'open_hours/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "open_hours"
8
+ spec.version = OpenHours::VERSION
9
+ spec.authors = ["Ian Whitney"]
10
+ spec.email = ["whit0694@umn.edu"]
11
+ spec.summary = %q{Parser for the OpeningHours schema from schema.org.}
12
+ spec.description = %q{Library that parses date ranges in the openingHours format https://schema.org/openingHours.}
13
+ spec.homepage = "https://github.com/umn-asr/open_hours"
14
+ spec.license = ""
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ end
@@ -0,0 +1,114 @@
1
+ require "rspec/core"
2
+ require_relative "../lib/open_hours"
3
+
4
+ describe OpeningHours::OpenHours do
5
+ let(:good_param_examples) {[
6
+ ["Mo-Th 08:00-16:30", "Fr 08:00-16:00"],
7
+ "Mo-Th 08:00-16:30",
8
+ ]}
9
+
10
+ describe "parse" do
11
+ describe "with good params" do
12
+ it "returns an instance of OpenHours" do
13
+ good_param_examples.each do |good_params|
14
+ it = OpeningHours.parse(good_params)
15
+ expect(it).to be_a OpeningHours::OpenHours
16
+ end
17
+ end
18
+ end
19
+
20
+ describe "with no params" do
21
+ it "raises an ArgumentError" do
22
+ expect {OpeningHours.parse()}.to raise_error(ArgumentError)
23
+ end
24
+ end
25
+
26
+ describe "with params that don't conform to the openingHours schema" do
27
+ let(:bad_param_examples) {[
28
+ "Mon 08:00-16:00",
29
+ "08:00-16:00",
30
+ "Mo 0800-16:00",
31
+ "Mo 08:00-1600",
32
+ "Mo 08:0016:00",
33
+ "No 08:00-16:00",
34
+ "Mo08:00-16:00",
35
+ "Mo-Thu 08:00-16:00",
36
+ "MoTh 08:00-16:00",
37
+ "Mo-Th08:00-16:00"
38
+ ]}
39
+
40
+ it "raises an ArgumentError" do
41
+ bad_param_examples.each do |bad_params|
42
+ expect {OpeningHours.parse(bad_params)}.to raise_error(ArgumentError)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "open_at?" do
49
+ describe "params" do
50
+ it "requires something that can be parsed with strftime" do
51
+ param = DateTime.now
52
+ expect(param).to receive(:to_datetime) { DateTime.now }
53
+ it = OpeningHours.parse(good_param_examples.sample)
54
+ it.open_at?(param)
55
+ end
56
+ end
57
+
58
+ describe "date/time within opening hours" do
59
+ before do
60
+ @it = OpeningHours.parse(["Mo-Th 08:00-16:30", "Fr 08:00-16:00"])
61
+ end
62
+
63
+ it "returns true if date and time is the first mintue of open hours" do
64
+ time = DateTime.parse("Monday, June 16 2014 08:00")
65
+ expect(@it.open_at?(time)).to be_truthy
66
+ end
67
+
68
+ it "returns true if date and time is the last minute of open hours" do
69
+ time = DateTime.parse("Monday, June 16 2014 16:30")
70
+ expect(@it.open_at?(time)).to be_truthy
71
+ end
72
+
73
+ it "returns true for a time for each day in range" do
74
+ %w(Tuesday Wednesday Thursday).each do |day|
75
+ time = DateTime.parse("#{day}, June 16 2014 16:30")
76
+ expect(@it.open_at?(time)).to be_truthy
77
+ end
78
+ end
79
+
80
+ it "returns true for a time for a single day" do
81
+ time = DateTime.parse("Friday, June 16 2014 12:30")
82
+ expect(@it.open_at?(time)).to be_truthy
83
+ end
84
+ end
85
+
86
+ describe "date/time outside opening hours" do
87
+ before do
88
+ @it = OpeningHours.parse(["Mo-Th 08:00-16:30", "Fr 08:00-16:00"])
89
+ end
90
+
91
+ it "returns false if the time is before open hours" do
92
+ time = DateTime.parse("Monday, June 16 2014 07:59")
93
+ expect(@it.open_at?(time)).to be_falsey
94
+ end
95
+
96
+ it "returns false if the time is after open hours" do
97
+ time = DateTime.parse("Monday, June 16 2014 16:31")
98
+ expect(@it.open_at?(time)).to be_falsey
99
+ end
100
+
101
+ it "returns false if the time is in open hours, but on an unspecified day" do
102
+ time = DateTime.parse("Saturday, June 21 2014 12:30")
103
+ expect(@it.open_at?(time)).to be_falsey
104
+ time = DateTime.parse("Sunday, June 22 2014 12:30")
105
+ expect(@it.open_at?(time)).to be_falsey
106
+ end
107
+
108
+ it "returns false if the time is in open hours for a different day, but not this day" do
109
+ time = DateTime.parse("Friday, June 20 2014 16:01")
110
+ expect(@it.open_at?(time)).to be_falsey
111
+ end
112
+ end
113
+ end
114
+ end
File without changes
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open_hours
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Ian Whitney
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Library that parses date ranges in the openingHours format https://schema.org/openingHours.
56
+ email:
57
+ - whit0694@umn.edu
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/open_hours.rb
68
+ - lib/open_hours/version.rb
69
+ - open_hours.gemspec
70
+ - spec/open_hours_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: https://github.com/umn-asr/open_hours
73
+ licenses:
74
+ - ''
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.2.2
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: Parser for the OpeningHours schema from schema.org.
96
+ test_files:
97
+ - spec/open_hours_spec.rb
98
+ - spec/spec_helper.rb