playwhe 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +25 -0
- data/Rakefile +2 -0
- data/data/playwhe.db +0 -0
- data/lib/playwhe.rb +148 -0
- data/lib/playwhe/storage.rb +109 -0
- data/lib/playwhe/storage/models.rb +74 -0
- data/lib/playwhe/version.rb +3 -0
- data/playwhe.gemspec +23 -0
- metadata +90 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dwayne R. Crooks
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Play Whe
|
2
|
+
|
3
|
+
A ruby gem for retrieving and storing Play Whe results.
|
4
|
+
|
5
|
+
The gem provides a ruby API for retrieving and storing Play Whe results from the
|
6
|
+
National Lotteries Control Board (NLCB) website at http://www.nlcb.co.tt/.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'playwhe'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install playwhe
|
21
|
+
|
22
|
+
## Help
|
23
|
+
|
24
|
+
You can get help, report bugs, make suggestions or ask questions by contacting
|
25
|
+
Dwayne R. Crooks via email at me@dwaynecrooks.com.
|
data/Rakefile
ADDED
data/data/playwhe.db
ADDED
Binary file
|
data/lib/playwhe.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require 'playwhe/version'
|
5
|
+
|
6
|
+
module PlayWhe
|
7
|
+
# The day that Play Whe had its first draw; its start date
|
8
|
+
BIRTHDAY = Date.parse('4th July 1994')
|
9
|
+
|
10
|
+
# The day that Play Whe changed to having 3 draws per day
|
11
|
+
THREE_DRAWS_DAY = Date.parse('21st November 2011')
|
12
|
+
|
13
|
+
HOST = 'nlcb.co.tt'
|
14
|
+
QUERY_PATH = 'search/pwq/countdateCash.php'
|
15
|
+
QUERY_URL = URI("http://#{HOST}/#{QUERY_PATH}")
|
16
|
+
|
17
|
+
# the lowest and highest Play Whe marks
|
18
|
+
LOWEST_MARK = 1
|
19
|
+
HIGHEST_MARK = 36
|
20
|
+
|
21
|
+
# marks associated with their standard spirit
|
22
|
+
SPIRITS = {
|
23
|
+
1 => 'centipede',
|
24
|
+
2 => 'old lady',
|
25
|
+
3 => 'carriage',
|
26
|
+
4 => 'dead man',
|
27
|
+
5 => 'parson man',
|
28
|
+
6 => 'belly',
|
29
|
+
7 => 'hog',
|
30
|
+
8 => 'tiger',
|
31
|
+
9 => 'cattle',
|
32
|
+
10 => 'monkey',
|
33
|
+
11 => 'corbeau',
|
34
|
+
12 => 'king',
|
35
|
+
13 => 'crapaud',
|
36
|
+
14 => 'money',
|
37
|
+
15 => 'sick woman',
|
38
|
+
16 => 'jamette',
|
39
|
+
17 => 'pigeon',
|
40
|
+
18 => 'water boat',
|
41
|
+
19 => 'horse',
|
42
|
+
20 => 'dog',
|
43
|
+
21 => 'mouth',
|
44
|
+
22 => 'rat',
|
45
|
+
23 => 'house',
|
46
|
+
24 => 'queen',
|
47
|
+
25 => 'morocoy',
|
48
|
+
26 => 'fowl',
|
49
|
+
27 => 'little snake',
|
50
|
+
28 => 'red fish',
|
51
|
+
29 => 'opium man',
|
52
|
+
30 => 'house cat',
|
53
|
+
31 => 'parson wife',
|
54
|
+
32 => 'shrimps',
|
55
|
+
33 => 'spider',
|
56
|
+
34 => 'blind man',
|
57
|
+
35 => 'big snake',
|
58
|
+
36 => 'donkey'
|
59
|
+
}
|
60
|
+
|
61
|
+
def self.results_for_month(year, month)
|
62
|
+
if date_in_range?(year, month)
|
63
|
+
params = { 'year' => (year%100).to_s.rjust(2, '0'),
|
64
|
+
'month' => Date::ABBR_MONTHNAMES[month] }
|
65
|
+
|
66
|
+
begin
|
67
|
+
response = Net::HTTP.post_form(QUERY_URL, params)
|
68
|
+
rescue
|
69
|
+
raise ServiceUnavailable
|
70
|
+
end
|
71
|
+
|
72
|
+
case response
|
73
|
+
when Net::HTTPOK
|
74
|
+
return parse_body(year, params['year'], month, params['month'], response.body)
|
75
|
+
else
|
76
|
+
raise ServiceUnavailable
|
77
|
+
end
|
78
|
+
else
|
79
|
+
# obviously we won't have any results
|
80
|
+
return []
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.results_for_year(year, callbacks = {})
|
85
|
+
all_results = []
|
86
|
+
|
87
|
+
12.times do |m|
|
88
|
+
month = m + 1
|
89
|
+
|
90
|
+
skip = callbacks[:before] ? callbacks[:before].call(month) : false
|
91
|
+
|
92
|
+
unless skip
|
93
|
+
begin
|
94
|
+
flag = :ok
|
95
|
+
results = results_for_month(year, month)
|
96
|
+
rescue ServiceUnavailable
|
97
|
+
flag = :error
|
98
|
+
results = []
|
99
|
+
ensure
|
100
|
+
begin
|
101
|
+
continue = callbacks[:after] ? callbacks[:after].call(month, flag, results) : true
|
102
|
+
rescue
|
103
|
+
raise
|
104
|
+
ensure
|
105
|
+
all_results += results if results
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
break unless continue
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
all_results
|
114
|
+
end
|
115
|
+
|
116
|
+
class ServiceUnavailable < Exception
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def self.date_in_range?(year, month)
|
122
|
+
mday = year == BIRTHDAY.year && month == BIRTHDAY.month ? BIRTHDAY.day : 1
|
123
|
+
date = Date.new(year, month, mday)
|
124
|
+
|
125
|
+
date >= BIRTHDAY && date <= Date.today
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.parse_body(year, yy, month, abbr_month, body)
|
129
|
+
# Here's the current form of the data on the page as of 27/05/2012:
|
130
|
+
#
|
131
|
+
# <date>: Draw # <draw> : <period>'s draw was <mark>
|
132
|
+
#
|
133
|
+
# where
|
134
|
+
#
|
135
|
+
# <date> : dd-Mmm-yy
|
136
|
+
# <draw> : a positive integer
|
137
|
+
# <period>: Morning | Midday | Evening
|
138
|
+
# <mark> : 1..36
|
139
|
+
results = body.scan(/(\d{2})-#{abbr_month}-#{yy}: Draw # (\d+) : (Morning|Midday|Evening)'s draw was (\d+)/)
|
140
|
+
|
141
|
+
results.collect! do |r|
|
142
|
+
{ draw: r[1].to_i,
|
143
|
+
date: Date.new(year, month, r[0].to_i),
|
144
|
+
period: {'Morning' => 1, 'Midday' => 2, 'Evening' => 3}[r[2]],
|
145
|
+
mark: r[3].to_i }
|
146
|
+
end.sort_by! { |r| r[:draw] }
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
require 'playwhe/storage/models'
|
5
|
+
|
6
|
+
module PlayWhe
|
7
|
+
|
8
|
+
module Storage
|
9
|
+
|
10
|
+
def self.connect(path_to_db, log_level = :debug)
|
11
|
+
DataMapper::Logger.new($stdout, log_level)
|
12
|
+
DataMapper.setup(:default, "sqlite://#{File.expand_path(path_to_db)}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.create(path = nil, log_level = :debug)
|
16
|
+
setup(path, log_level)
|
17
|
+
|
18
|
+
DataMapper.auto_migrate!
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.update(path = nil, log_level = :debug)
|
22
|
+
setup(path, log_level)
|
23
|
+
|
24
|
+
(PlayWhe::BIRTHDAY.year..Date.today.year).each do |year|
|
25
|
+
task = Task.first_or_create({ year: year },
|
26
|
+
{ month: year == PlayWhe::BIRTHDAY.year ? PlayWhe::BIRTHDAY.month : 1,
|
27
|
+
status: 'pending' })
|
28
|
+
|
29
|
+
unless task.completed?
|
30
|
+
DataMapper.logger << "retrieving results for year #{year}..."
|
31
|
+
|
32
|
+
before = Proc.new do |month|
|
33
|
+
if month < task.month
|
34
|
+
DataMapper.logger << " - skipping #{Date::MONTHNAMES[month]}"
|
35
|
+
true # skip
|
36
|
+
else
|
37
|
+
DataMapper.logger << " + at #{Date::MONTHNAMES[month]}..."
|
38
|
+
false # do not skip
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
after = Proc.new do |month, flag, results|
|
43
|
+
case flag
|
44
|
+
when :ok
|
45
|
+
Result.transaction do |t|
|
46
|
+
begin
|
47
|
+
results.each do |r|
|
48
|
+
result = Result.first_or_new(draw: r[:draw], date: r[:date], period: r[:period], mark: r[:mark])
|
49
|
+
|
50
|
+
unless result.save
|
51
|
+
DataMapper.logger << " - invalid data: #{result.draw} #{result.date} #{result.period} #{result.mark}"
|
52
|
+
Error.create(message: r.to_s)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
today = Date.today
|
57
|
+
if Date.new(year, month) < Date.new(today.year, today.month)
|
58
|
+
if month == 12
|
59
|
+
task.status = 'completed'
|
60
|
+
else
|
61
|
+
task.month += 1
|
62
|
+
end
|
63
|
+
|
64
|
+
if task.save
|
65
|
+
DataMapper.logger << " + completed #{Date::MONTHNAMES[month]}!"
|
66
|
+
DataMapper.logger << "completed year #{year}!" if task.completed?
|
67
|
+
|
68
|
+
true # continue
|
69
|
+
else
|
70
|
+
DataMapper.logger << ' - task not completed!'
|
71
|
+
|
72
|
+
false # do not continue
|
73
|
+
end
|
74
|
+
else
|
75
|
+
DataMapper.logger << 'All tasks completed!'
|
76
|
+
|
77
|
+
false # do not continue
|
78
|
+
end
|
79
|
+
rescue
|
80
|
+
t.rollback
|
81
|
+
|
82
|
+
DataMapper.logger << 'Encountered an error during processing'
|
83
|
+
|
84
|
+
false # do not continue
|
85
|
+
end
|
86
|
+
end
|
87
|
+
when :error
|
88
|
+
DataMapper.logger << 'Encountered an error during processing'
|
89
|
+
|
90
|
+
false # do not continue
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
PlayWhe.results_for_year(year, before: before, after: after)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def self.setup(path, log_level)
|
102
|
+
path ||= File.join(Dir.home, '.playwhe')
|
103
|
+
path = File.expand_path(path)
|
104
|
+
Dir.mkdir(path) unless File.directory?(path)
|
105
|
+
|
106
|
+
self.connect("#{path}/playwhe.db", log_level)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'data_mapper'
|
2
|
+
|
3
|
+
module PlayWhe
|
4
|
+
|
5
|
+
module Storage
|
6
|
+
|
7
|
+
DataMapper::Property.required(true)
|
8
|
+
|
9
|
+
class Result
|
10
|
+
include DataMapper::Resource
|
11
|
+
|
12
|
+
storage_names[:default] = 'results'
|
13
|
+
|
14
|
+
property :draw, Integer, key: true
|
15
|
+
property :date, Date
|
16
|
+
property :period, Integer
|
17
|
+
property :mark, Integer
|
18
|
+
|
19
|
+
validates_with_method :draw, method: :check_draw
|
20
|
+
validates_within :period, set: 1..3
|
21
|
+
validates_within :mark, set: PlayWhe::LOWEST_MARK..PlayWhe::HIGHEST_MARK
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def check_draw
|
26
|
+
self.draw >= 1 ? true : [false, 'The draw must be a positive integer']
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Task
|
31
|
+
include DataMapper::Resource
|
32
|
+
|
33
|
+
storage_names[:default] = 'tasks'
|
34
|
+
|
35
|
+
property :id, Serial
|
36
|
+
property :year, Integer, unique: true
|
37
|
+
property :month, Integer
|
38
|
+
property :status, String
|
39
|
+
property :created_at, DateTime, required: false
|
40
|
+
property :updated_at, DateTime, required: false
|
41
|
+
|
42
|
+
validates_with_method :year, method: :check_year
|
43
|
+
validates_within :month, set: 1..12
|
44
|
+
validates_within :status, set: ['pending', 'completed']
|
45
|
+
|
46
|
+
def completed?
|
47
|
+
self.status == 'completed'
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def check_year
|
53
|
+
if self.year >= PlayWhe::BIRTHDAY.year && self.year <= Date.today.year
|
54
|
+
true
|
55
|
+
else
|
56
|
+
[false, 'The year is out of range']
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class Error
|
62
|
+
include DataMapper::Resource
|
63
|
+
|
64
|
+
storage_names[:default] = 'errors'
|
65
|
+
|
66
|
+
property :id, Serial
|
67
|
+
property :message, Text
|
68
|
+
property :created_at, DateTime, required: false
|
69
|
+
property :updated_at, DateTime, required: false
|
70
|
+
end
|
71
|
+
|
72
|
+
DataMapper.finalize
|
73
|
+
end
|
74
|
+
end
|
data/playwhe.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/playwhe/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Dwayne R. Crooks"]
|
6
|
+
gem.email = ["me@dwaynecrooks.com"]
|
7
|
+
gem.description = %q{A ruby gem for retrieving and storing Play Whe results.
|
8
|
+
|
9
|
+
The gem provides a ruby API for retrieving and storing Play Whe results from
|
10
|
+
the National Lotteries Control Board (NLCB) website at http://www.nlcb.co.tt/.}
|
11
|
+
gem.summary = %q{A ruby gem for retrieving and storing Play Whe results.}
|
12
|
+
gem.homepage = "http://rubygems.org/gems/playwhe"
|
13
|
+
|
14
|
+
gem.add_dependency('data_mapper', '~> 1.2.0')
|
15
|
+
gem.add_dependency('dm-sqlite-adapter', '~> 1.2.0')
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($\)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.name = "playwhe"
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
gem.version = PlayWhe::VERSION
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: playwhe
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dwayne R. Crooks
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: data_mapper
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.2.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: dm-sqlite-adapter
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 1.2.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.2.0
|
46
|
+
description: ! "A ruby gem for retrieving and storing Play Whe results.\n\n The gem
|
47
|
+
provides a ruby API for retrieving and storing Play Whe results from\n the National
|
48
|
+
Lotteries Control Board (NLCB) website at http://www.nlcb.co.tt/."
|
49
|
+
email:
|
50
|
+
- me@dwaynecrooks.com
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- data/playwhe.db
|
61
|
+
- lib/playwhe.rb
|
62
|
+
- lib/playwhe/storage.rb
|
63
|
+
- lib/playwhe/storage/models.rb
|
64
|
+
- lib/playwhe/version.rb
|
65
|
+
- playwhe.gemspec
|
66
|
+
homepage: http://rubygems.org/gems/playwhe
|
67
|
+
licenses: []
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.24
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: A ruby gem for retrieving and storing Play Whe results.
|
90
|
+
test_files: []
|