schedule-scraper 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.
- data/.gitignore +17 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +48 -0
- data/Rakefile +11 -0
- data/lib/schedule-scraper/event.rb +20 -0
- data/lib/schedule-scraper/pointstreak/event.rb +16 -0
- data/lib/schedule-scraper/pointstreak/schedule.rb +35 -0
- data/lib/schedule-scraper/schedule.rb +19 -0
- data/lib/schedule-scraper/version.rb +3 -0
- data/lib/schedule-scraper.rb +30 -0
- data/schedule-scraper.gemspec +25 -0
- data/spec/schedule-scraper/evet_spec.rb +9 -0
- data/spec/schedule-scraper/pointstreak/event_spec.rb +30 -0
- data/spec/schedule-scraper/pointstreak/schedule_spec.rb +48 -0
- data/spec/schedule-scraper/schedule_spec.rb +11 -0
- data/spec/schedule-scraper_spec.rb +25 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/vcr_cassettes/summit_summer_2012.yml +146 -0
- metadata +140 -0
data/.gitignore
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--readme README.md
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 John Allen
|
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,48 @@
|
|
1
|
+
# ScheduleScraper
|
2
|
+
|
3
|
+
A web calendar scraper for sites that do not provid portable (csv, i-cal etc) version.
|
4
|
+
|
5
|
+
Supported schedule sites:
|
6
|
+
|
7
|
+
* [PointStreak](http://pointstreak.com)
|
8
|
+
|
9
|
+
Supported output formats:
|
10
|
+
|
11
|
+
* CSV
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'schedule-scraper'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install schedule-scraper
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
Request a schedule:
|
30
|
+
|
31
|
+
schedule = ScheduleScrape.fetch(:point_streak, :season => 123, :team => 456)
|
32
|
+
|
33
|
+
Export the schedule to CSV:
|
34
|
+
|
35
|
+
schedule.to_csv
|
36
|
+
|
37
|
+
## TODO
|
38
|
+
|
39
|
+
1. Add more export options: iCal, Google Calendar (csv)
|
40
|
+
2. Add other schedule types: ezleagues
|
41
|
+
|
42
|
+
## Contributing
|
43
|
+
|
44
|
+
1. Fork it
|
45
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
46
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
47
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
48
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module ScheduleScraper
|
2
|
+
module Event
|
3
|
+
module ClassMethods
|
4
|
+
def export_fields
|
5
|
+
self.rules.keys
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_csv
|
14
|
+
self.class.export_fields.collect do |field|
|
15
|
+
self.send(field)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ScheduleScraper
|
2
|
+
module Pointstreak
|
3
|
+
class Event < Nibbler
|
4
|
+
include ScheduleScraper::Event
|
5
|
+
|
6
|
+
cleaner = lambda { |value| value.text.strip }
|
7
|
+
|
8
|
+
element 'td:first' => :home_team, :with => cleaner
|
9
|
+
element 'td:nth(2)' => :away_team, :with => cleaner
|
10
|
+
element 'td:nth(3)' => :date, :with => cleaner
|
11
|
+
element 'td:nth(4)' => :time, :with => cleaner
|
12
|
+
element 'td:nth(5)' => :rink, :with => cleaner
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ScheduleScraper
|
2
|
+
module Pointstreak
|
3
|
+
class Schedule < Nibbler
|
4
|
+
include ScheduleScraper::Schedule
|
5
|
+
|
6
|
+
POINT_STREAK_URL = "http://www.pointstreak.com/players/print/players-team-schedule.html"
|
7
|
+
|
8
|
+
element 'table table:last' => :list do
|
9
|
+
elements 'tr:not(.fields)' => :event_list, :with => Event
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.fetch(options)
|
13
|
+
parse html(options[:season], options[:team])
|
14
|
+
end
|
15
|
+
|
16
|
+
def events
|
17
|
+
list.event_list.reject { |event| event.away_team.nil? }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def self.html(season, team)
|
23
|
+
open(source_url(season, team))
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.source_url(season, team)
|
27
|
+
"#{POINT_STREAK_URL}?teamid=#{team}&seasonid=#{season}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def event_class
|
31
|
+
ScheduleScraper::Pointstreak::Event
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ScheduleScraper
|
2
|
+
module Schedule
|
3
|
+
module ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_csv
|
11
|
+
CSV.generate do |csv|
|
12
|
+
csv << event_class.export_fields
|
13
|
+
events.each do |event|
|
14
|
+
csv << event.to_csv
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'nibbler'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'csv'
|
4
|
+
require "schedule-scraper/version"
|
5
|
+
require "schedule-scraper/event"
|
6
|
+
require "schedule-scraper/schedule"
|
7
|
+
require "schedule-scraper/pointstreak/event"
|
8
|
+
require "schedule-scraper/pointstreak/schedule"
|
9
|
+
|
10
|
+
module ScheduleScraper
|
11
|
+
def self.fetch(type, options = {})
|
12
|
+
raise UnsupportedSchedule unless supported_schedules.include?(type.to_sym)
|
13
|
+
|
14
|
+
type_class(type).fetch(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.type_class(type)
|
18
|
+
case type
|
19
|
+
when :pointstreak then Pointstreak::Schedule
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.supported_schedules
|
24
|
+
[
|
25
|
+
:pointstreak
|
26
|
+
]
|
27
|
+
end
|
28
|
+
|
29
|
+
class UnsupportedSchedule < StandardError; end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/schedule-scraper/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["John Allen"]
|
6
|
+
gem.email = ["john@threedogconsulting.com"]
|
7
|
+
gem.description = %q{Scrapes online schedules and provides portable versions}
|
8
|
+
gem.summary = %q{A web calendar scraper for sites that do not provid portable (csv, i-cal etc) version. Initial version suport PointStreak.com. }
|
9
|
+
gem.homepage = "https://github.com/johnallen3d/schedule-scrape"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "schedule-scraper"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = ScheduleScraper::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency 'nibbler', '~> 1.3.0'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'minitest', '~> 3.1.0'
|
21
|
+
gem.add_development_dependency 'rake', '~> 0.9.2'
|
22
|
+
gem.add_development_dependency 'turn', '~> 0.9.5'
|
23
|
+
gem.add_development_dependency 'vcr', '~> 2.2.0'
|
24
|
+
gem.add_development_dependency 'fakeweb', '~> 1.3.0'
|
25
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
|
+
|
3
|
+
# describe ScheduleScraper::Event do
|
4
|
+
# subject() { ScheduleScraper::Event }
|
5
|
+
|
6
|
+
# it "uses elements to define fields for csv" do
|
7
|
+
# subject.send(:export_fields).must_equal subject.rules.keys
|
8
|
+
# end
|
9
|
+
# end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
|
2
|
+
|
3
|
+
describe ScheduleScraper::Pointstreak::Event do
|
4
|
+
let(:options) { POINTSTREAK_OPTIONS }
|
5
|
+
let(:fields) { [:home_team, :away_team, :date, :time, :rink] }
|
6
|
+
|
7
|
+
before do
|
8
|
+
VCR.use_cassette('summit_summer_2012') do
|
9
|
+
@schedule = ScheduleScraper::Pointstreak::Schedule.fetch(options)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
subject() { @schedule.events.first }
|
14
|
+
|
15
|
+
[:home_team, :away_team, :date, :time, :rink].each do |field|
|
16
|
+
it "can find the #{field.to_s.gsub('_', ' ')}" do
|
17
|
+
subject.send(field).wont_be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "uses elements to define fields for csv" do
|
22
|
+
klass = ScheduleScraper::Pointstreak::Event
|
23
|
+
klass.send(:export_fields).must_equal fields
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns a list of fields when you ask for csv" do
|
27
|
+
expected = ["BLADES 6", "SUMMIT 8", "Sun, Jun 03", "7:45 pm", "final"]
|
28
|
+
subject.to_csv.must_equal expected
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../spec_helper'))
|
2
|
+
|
3
|
+
describe ScheduleScraper::Pointstreak::Schedule do
|
4
|
+
subject() { ScheduleScraper::Pointstreak::Schedule }
|
5
|
+
let(:options) { POINTSTREAK_OPTIONS }
|
6
|
+
|
7
|
+
it "knows the root pointstreak url" do
|
8
|
+
subject::POINT_STREAK_URL.must_match /pointstreak/
|
9
|
+
end
|
10
|
+
|
11
|
+
it "builds a valid url" do
|
12
|
+
url = subject.send(:source_url, "123", "456")
|
13
|
+
expected = "#{subject::POINT_STREAK_URL}?teamid=456&seasonid=123"
|
14
|
+
|
15
|
+
url.must_equal expected
|
16
|
+
end
|
17
|
+
|
18
|
+
it "fetches html from pointstreak" do
|
19
|
+
VCR.use_cassette('summit_summer_2012') do
|
20
|
+
subject.html(options[:season], options[:team])
|
21
|
+
end # wont_raise
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "schedule instance" do
|
25
|
+
subject() do
|
26
|
+
VCR.use_cassette('summit_summer_2012') do
|
27
|
+
ScheduleScraper::Pointstreak::Schedule.fetch(options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns an instance of itself" do
|
32
|
+
subject.must_be_instance_of ScheduleScraper::Pointstreak::Schedule
|
33
|
+
end
|
34
|
+
|
35
|
+
it "finds an event list" do
|
36
|
+
subject.list.wont_be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it "has a list of events" do
|
40
|
+
subject.events.must_be_instance_of Array
|
41
|
+
subject.events.length.must_equal 8
|
42
|
+
end
|
43
|
+
|
44
|
+
it "generates a csv file" do
|
45
|
+
subject.to_csv.must_be_instance_of String
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
|
+
|
3
|
+
# describe ScheduleScraper::Schedule do
|
4
|
+
# subject() { ScheduleScraper::Schedule.new({}) }
|
5
|
+
|
6
|
+
# describe "#to_csv" do
|
7
|
+
# it "returns a schedule in CSV format" do
|
8
|
+
# subject.to_csv.must_be_instance_of String
|
9
|
+
# end
|
10
|
+
# end
|
11
|
+
# end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
+
|
3
|
+
describe ScheduleScraper do
|
4
|
+
subject() { ScheduleScraper }
|
5
|
+
let(:options) { POINTSTREAK_OPTIONS }
|
6
|
+
|
7
|
+
describe ".fetch" do
|
8
|
+
it "validates requested schedule type" do
|
9
|
+
VCR.use_cassette('summit_summer_2012') do
|
10
|
+
ScheduleScraper.fetch(:pointstreak, options) # wont_raise
|
11
|
+
end
|
12
|
+
|
13
|
+
-> {
|
14
|
+
ScheduleScraper.fetch(:xyz)
|
15
|
+
}.must_raise ScheduleScraper::UnsupportedSchedule
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns a schedule" do
|
19
|
+
VCR.use_cassette('summit_summer_2012') do
|
20
|
+
schedule = ScheduleScraper.fetch(:pointstreak, options)
|
21
|
+
schedule.must_be_instance_of ScheduleScraper::Pointstreak::Schedule
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'turn/autorun'
|
4
|
+
require 'vcr'
|
5
|
+
|
6
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/schedule-scraper'))
|
7
|
+
|
8
|
+
POINTSTREAK_OPTIONS = { :season => "9162", :team => "385368" }
|
9
|
+
|
10
|
+
VCR.configure do |c|
|
11
|
+
c.cassette_library_dir = 'spec/vcr_cassettes'
|
12
|
+
c.hook_into :fakeweb
|
13
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://www.pointstreak.com/players/print/players-team-schedule.html?teamid=385368&seasonid=9162
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
accept:
|
11
|
+
- ! '*/*'
|
12
|
+
user-agent:
|
13
|
+
- Ruby
|
14
|
+
response:
|
15
|
+
status:
|
16
|
+
code: 200
|
17
|
+
message: OK
|
18
|
+
headers:
|
19
|
+
server:
|
20
|
+
- Apache/1.3.41 (Unix) mod_gzip/1.3.26.1a PHP/5.2.11
|
21
|
+
x-powered-by:
|
22
|
+
- PHP/5.2.11
|
23
|
+
p3p:
|
24
|
+
- CP="NOI DSP CURa ADMa DEVa TAIa PSAa PSDa HISa OUR BUS IND PHY UNI COM NAV
|
25
|
+
INT"
|
26
|
+
expires:
|
27
|
+
- Mon, 18-Jun-12 03:30:00 GMT
|
28
|
+
last-modified:
|
29
|
+
- Mon, 18 Jun 2012 03:28:00 GMT
|
30
|
+
content-type:
|
31
|
+
- text/html; charset=UTF-8
|
32
|
+
content-length:
|
33
|
+
- '7867'
|
34
|
+
be:
|
35
|
+
- hockey
|
36
|
+
vclhockey:
|
37
|
+
- '1'
|
38
|
+
date:
|
39
|
+
- Mon, 18 Jun 2012 03:28:00 GMT
|
40
|
+
x-varnish:
|
41
|
+
- '3214697408'
|
42
|
+
age:
|
43
|
+
- '0'
|
44
|
+
via:
|
45
|
+
- 1.1 varnish
|
46
|
+
connection:
|
47
|
+
- keep-alive
|
48
|
+
body:
|
49
|
+
encoding: US-ASCII
|
50
|
+
string: ! "<html>\r\n<head>\r\n<LINK REL=\"STYLESHEET\" HREF=\"/common/playersprintstylesheet.css\">\r\n</head>\r\n<body>\r\n<table
|
51
|
+
width=518><tr><td align=\"center\"><table width=\"100%\" border=\"0\" cellspacing=\"0\"
|
52
|
+
cellpadding=\"4\">\r\n\t\t<tr class=\"headerTeam\">\r\n\t\t<td width=\"60%\"><font
|
53
|
+
class=\"conHeader\">EIAHL</font> <font class=\"season\">(Summer 2012)</font></td>\r\n\t\t<td
|
54
|
+
width=\"40%\" align=\"right\">POINTSTREAK PRINTABLE PAGE</td>\r\n\t\t</tr>\r\n\t\t<tr
|
55
|
+
class=\"subHeader\">\r\n\t\t<td width=\"60%\" colspan=\"2\"><font class=\"big\">\r\n\t\tSUMMIT\t\t\t\t(\r\n\t\tC-2\t\t)\r\n\t\t\t\t</td>\r\n\t</tr>\r\n\t</table>\r\n\t<table
|
56
|
+
width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\r\n\t<tr><td
|
57
|
+
class=\"intshim\"><img src=\"http://static2.pointstreak.com/images/shim.gif\"
|
58
|
+
width=\"1\" height=\"1\"></td></tr>\r\n\t</table><br>\n <table width=\"97%\"
|
59
|
+
border=\"0\" cellspacing=\"0\" cellpadding=\"3\">\n <tr class=\"cellTeamPlayer\">
|
60
|
+
\n <td> Team Schedule</td>\t <td width=\"60%\"
|
61
|
+
align=\"right\"> gamesheet view <img src=\"http://static1.pointstreak.com/images/playersection/gs.gif\"
|
62
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\">
|
63
|
+
printable gamesheett <img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
64
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></td> </tr>\n
|
65
|
+
\ </table>\n\t\t\t<table width=\"97%\" border=\"0\" cellspacing=\"1\"
|
66
|
+
cellpadding=\"3\">\n\t\t\t\t\t<tr class=\"fields\">\n\t\t\t\t\t\t\t\t\t\t\t<td
|
67
|
+
width=\"23%\" align=\"left\"> Home</td>\n\t\t\t\t\t\t<td width=\"23%\" align=\"left\">
|
68
|
+
Away</td>\n\t\t\t\t\t\t<td width=\"17%\"> Date</td>\n\t\t\t\t\t\t<td width=\"13%\">
|
69
|
+
Time</td>\n\t\t\t\t\t\t<td nowrap align=\"right\" width=\"21%\"> Rink/ GS</td>\n\t\t\t\t\t\t<td
|
70
|
+
width=\"2%\"> GT</td>\n\t\t\t\t\t</tr>\t\t\t\t<tr class=\"lightGrey\">\n\t\t\t\t\t\t\t\t\t\t\t<td><a
|
71
|
+
href=\"players-team.html?teamid=385373&seasonid=9162\">BLADES</a><b> 6</b></td><td><a
|
72
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a><b> 8</b>\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td
|
73
|
+
align=\"center\">Sun, Jun 03 </td>\n\t\t\t\t\t\t<td>7:45 pm</td>\n\t\t\t\t\t\t<td
|
74
|
+
align=\"right\"><a href=\"players-boxscore.html?gameid=1947934\">final</a>\t
|
75
|
+
<a href=\"gamesheet_full.html?gameid=1947934\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/gs.gif\"
|
76
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a></td>\n\t\t\t\t\t\t<td><img
|
77
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_manual.gif\"
|
78
|
+
border=\"0\"></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t<tr class=\"lightGrey\">\n\t\t\t\t\t\t\t\t\t\t\t<td><a
|
79
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a><b> 1</b></td><td><a
|
80
|
+
href=\"players-team.html?teamid=385375&seasonid=9162\">BLACK ICE</a><b> 6</b>\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td
|
81
|
+
align=\"center\">Sun, Jun 10 </td>\n\t\t\t\t\t\t<td>7:30 pm</td>\n\t\t\t\t\t\t<td
|
82
|
+
align=\"right\"><a href=\"players-boxscore.html?gameid=1947939\">final</a>\t
|
83
|
+
<a href=\"gamesheet_full.html?gameid=1947939\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/gs.gif\"
|
84
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a></td>\n\t\t\t\t\t\t<td><img
|
85
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_manual.gif\"
|
86
|
+
border=\"0\"></td>\n\t\t\t\t\t</tr>\n\t\t\t\t<tr><td><span class=\"highlight\"></span><a
|
87
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td><span
|
88
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385374&seasonid=9162\">OGIES</a></td>\n\t\t\t\t\t\t\t<td
|
89
|
+
align=\"center\">Sun, Jul 01</td><td>6:05 pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a
|
90
|
+
href=\"players-arenas.html?arenaid=963&seasonid=9162\">Training Rink </a>
|
91
|
+
<a href=\"gamesheet.html?gameid=1947947\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
92
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
93
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
94
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr><tr><td><span class=\"highlight\"></span><a
|
95
|
+
href=\"players-team.html?teamid=385370&seasonid=9162\">ANGRY BEAVERS</a></td>\n\t\t\t\t\t\t\t<td><span
|
96
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td
|
97
|
+
align=\"center\">Sun, Jul 15</td><td>7:20 pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a
|
98
|
+
href=\"players-arenas.html?arenaid=963&seasonid=9162\">Main Rink </a> <a href=\"gamesheet.html?gameid=1947952\"
|
99
|
+
target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
100
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
101
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
102
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr><tr><td><span class=\"highlight\"></span><a
|
103
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td><span
|
104
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385372&seasonid=9162\">REBELS</a></td>\n\t\t\t\t\t\t\t<td
|
105
|
+
align=\"center\">Sun, Jul 22</td><td>4:40 pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a
|
106
|
+
href=\"players-arenas.html?arenaid=963&seasonid=9162\">Training Rink </a>
|
107
|
+
<a href=\"gamesheet.html?gameid=1947969\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
108
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
109
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
110
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr><tr><td><span class=\"highlight\"></span><a
|
111
|
+
href=\"players-team.html?teamid=385371&seasonid=9162\">YELLOWSNOW</a></td>\n\t\t\t\t\t\t\t<td><span
|
112
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td
|
113
|
+
align=\"center\">Sun, Jul 29</td><td>4:40 pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a
|
114
|
+
href=\"players-arenas.html?arenaid=963&seasonid=9162\">Training Rink </a>
|
115
|
+
<a href=\"gamesheet.html?gameid=1947941\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
116
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
117
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
118
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr><tr><td><span class=\"highlight\"></span><a
|
119
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td><span
|
120
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385369&seasonid=9162\">AVERAGE
|
121
|
+
JOES</a></td>\n\t\t\t\t\t\t\t<td align=\"center\">Sun, Aug 05</td><td>6:05
|
122
|
+
pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a href=\"players-arenas.html?arenaid=963&seasonid=9162\">Training
|
123
|
+
Rink </a> <a href=\"gamesheet.html?gameid=1947974\" target=\"_blank\"><img
|
124
|
+
src=\"http://static1.pointstreak.com/images/playersection/ss.gif\" width=\"15\"
|
125
|
+
height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
126
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
127
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr><tr><td><span class=\"highlight\"></span><a
|
128
|
+
href=\"players-team.html?teamid=385368&seasonid=9162\">SUMMIT</a></td>\n\t\t\t\t\t\t\t<td><span
|
129
|
+
class=\"highlight\"></span><a href=\"players-team.html?teamid=385373&seasonid=9162\">BLADES</a></td>\n\t\t\t\t\t\t\t<td
|
130
|
+
align=\"center\">Sun, Aug 12</td><td>7:30 pm</td>\n\t\t\t\t\t\t\t<td align=\"right\"><a
|
131
|
+
href=\"players-arenas.html?arenaid=963&seasonid=9162\">Training Rink </a>
|
132
|
+
<a href=\"gamesheet.html?gameid=1947982\" target=\"_blank\"><img src=\"http://static1.pointstreak.com/images/playersection/ss.gif\"
|
133
|
+
width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\"></a>\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t<td><img
|
134
|
+
src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
135
|
+
border=\"0\"></td>\n\t\t\t\t\t\t</tr>\t\t\t\t<tr>\n\t\t\t\t<td align=\"right\"
|
136
|
+
colspan=\"6\"><br><a href=\"../aboutus/pointstreakis-entrytype.html\">Terminal
|
137
|
+
Game/Rink - <img src=\"http://static1.pointstreak.com/images/playersection/icon_terminal.gif\"
|
138
|
+
align=\"absmiddle\" border=0></a><br><a href=\"../aboutus/pointstreakis-entrytype.html\">Laptop
|
139
|
+
Game/Rink - <img src=\"http://static1.pointstreak.com/images/playersection/icon_laptop.gif\"
|
140
|
+
align=\"absmiddle\" border=0></a><br><a href=\"../aboutus/pointstreakis-entrytype.html\">Online
|
141
|
+
Entry Game/Rink - <img src=\"http://static1.pointstreak.com/images/playersection/icon_manual.gif\"
|
142
|
+
align=\"absmiddle\" border=0></a></td>\n\t\t \t\t</tr>\n\t\t</table>\n <br>\n
|
143
|
+
\ <br>\n\n</td>\r\n</tr>\r\n</table>\r\n</body>\r\n</html>"
|
144
|
+
http_version: '1.1'
|
145
|
+
recorded_at: Mon, 18 Jun 2012 03:28:00 GMT
|
146
|
+
recorded_with: VCR 2.2.2
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: schedule-scraper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John Allen
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nibbler
|
16
|
+
requirement: &70142865159900 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.3.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70142865159900
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: minitest
|
27
|
+
requirement: &70142865156300 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.1.0
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70142865156300
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70142865155280 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.9.2
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70142865155280
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: turn
|
49
|
+
requirement: &70142865153960 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.9.5
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70142865153960
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: vcr
|
60
|
+
requirement: &70142865171400 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 2.2.0
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70142865171400
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fakeweb
|
71
|
+
requirement: &70142865170560 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 1.3.0
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70142865170560
|
80
|
+
description: Scrapes online schedules and provides portable versions
|
81
|
+
email:
|
82
|
+
- john@threedogconsulting.com
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files: []
|
86
|
+
files:
|
87
|
+
- .gitignore
|
88
|
+
- .yardopts
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- lib/schedule-scraper.rb
|
94
|
+
- lib/schedule-scraper/event.rb
|
95
|
+
- lib/schedule-scraper/pointstreak/event.rb
|
96
|
+
- lib/schedule-scraper/pointstreak/schedule.rb
|
97
|
+
- lib/schedule-scraper/schedule.rb
|
98
|
+
- lib/schedule-scraper/version.rb
|
99
|
+
- schedule-scraper.gemspec
|
100
|
+
- spec/schedule-scraper/evet_spec.rb
|
101
|
+
- spec/schedule-scraper/pointstreak/event_spec.rb
|
102
|
+
- spec/schedule-scraper/pointstreak/schedule_spec.rb
|
103
|
+
- spec/schedule-scraper/schedule_spec.rb
|
104
|
+
- spec/schedule-scraper_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
- spec/vcr_cassettes/summit_summer_2012.yml
|
107
|
+
homepage: https://github.com/johnallen3d/schedule-scrape
|
108
|
+
licenses: []
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.8.10
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: A web calendar scraper for sites that do not provid portable (csv, i-cal
|
131
|
+
etc) version. Initial version suport PointStreak.com.
|
132
|
+
test_files:
|
133
|
+
- spec/schedule-scraper/evet_spec.rb
|
134
|
+
- spec/schedule-scraper/pointstreak/event_spec.rb
|
135
|
+
- spec/schedule-scraper/pointstreak/schedule_spec.rb
|
136
|
+
- spec/schedule-scraper/schedule_spec.rb
|
137
|
+
- spec/schedule-scraper_spec.rb
|
138
|
+
- spec/spec_helper.rb
|
139
|
+
- spec/vcr_cassettes/summit_summer_2012.yml
|
140
|
+
has_rdoc:
|