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 ADDED
@@ -0,0 +1,17 @@
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
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --readme README.md
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in schedule-scraper.gemspec
4
+ gemspec
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,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+
5
+ task :default => [:test]
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs.push "lib"
9
+ t.test_files = FileList['spec/**/*_spec.rb']
10
+ t.verbose = true
11
+ end
@@ -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,3 @@
1
+ module ScheduleScraper
2
+ VERSION = "0.1.0"
3
+ 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
@@ -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>&nbsp; Team Schedule</td>\t <td width=\"60%\"
61
+ align=\"right\"> gamesheet view&nbsp;<img src=\"http://static1.pointstreak.com/images/playersection/gs.gif\"
62
+ width=\"15\" height=\"15\" border=\"0\" align=\"absmiddle\">&nbsp;&nbsp;&nbsp;
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: