schedule-scraper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: