standings 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14e739692474cfd75e542d448de6970e2db4c55e
4
- data.tar.gz: bb7c094302d98b0d0ed43c83c1b740cd598d7644
3
+ metadata.gz: 700e9733621553724b05a8a746763f723e7d18bc
4
+ data.tar.gz: 9c18dec1572ed95d2065352b7421b27408ef925d
5
5
  SHA512:
6
- metadata.gz: bfd75712159f6175f2b64e6c45f63703a9253be582394ca7f56f73b36bc4184af671a36cc9722008cd55b73cb4a3fbf5f2d6ffd9d9e11bba9c6edc2f9ddffb3c
7
- data.tar.gz: 320461c8c23fb7304257f8c14557483ae91817a6eb7887902bbe298debb0b776c8d7c3932c9d92c05dab86b186bfe4e7fb26fb7d1998a96538013a1440ce20c4
6
+ metadata.gz: 75d2738153f30ce9ad054d422d2b01f2f1d95a50b2726a7a7ce0b903113f0a3e8e2c8689912b521ea7621af4e318186ca14877bce19d54eef4b95f69279cb20f
7
+ data.tar.gz: ee40e8af850813cbd7fb7d19c1e63afffb2e6670ed261e5d4f8372931552dbce5818509b11eac46c021a4aadab6fb0d4a20c4b1b200c24828029b95ad0f8f2a0
@@ -1,2 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- require 'standings'
2
+ # encoding: utf-8
3
+
4
+ require 'standings'
5
+ Standings::CLI.new.record_user_selection_and_show_results!
@@ -1,37 +1,11 @@
1
- #!/bin/env ruby
2
- # encoding: utf-8
3
-
4
- require_relative '../config/environment'
5
- opts = Trollop::options do
6
- version <<-EOS
7
-
8
- ⚽ Standings
9
- Version 0.3.0 | original version published December 2013
10
- Scott Luptowski | @scottluptowski
11
-
12
- EOS
13
- banner <<-EOS
14
- \n⚽ Standings is a command line gem which lets users check the current standings in a number of European football/soccer leagues. The data is scraped and thus subject to availability.
15
-
16
- Usage:
17
- \n
18
-
19
- EOS
20
- opt :epl, "🇬🇧 English Premier League"
21
- opt :championship, "🇬🇧 English Championship"
22
- opt :spl, "🇬🇧 Scottish Premier League"
23
- opt :liga, "🇪🇸 La Liga"
24
- opt :ligue, "🇫🇷 Ligue 1"
25
- opt :seriea, "🇮🇹 Seria A"
26
- opt :bundesliga, "🇩🇪 Bundesliga"
27
- end
28
-
29
- league_selection = opts.keys.detect { |k| opts[k] }
30
-
31
- if league_selection
32
- LeagueReference.set_league_info(league_selection)
33
- TableScraper.new.call
34
- Displayer.new.call
35
- else
36
- puts "⚽ Standings requires you to pass in the flag of a league. Run with --help for help."
37
- end
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+ require 'colorize'
4
+ require 'trollop'
5
+ require 'ostruct'
6
+
7
+ require 'standings/cli'
8
+ require 'standings/displayer'
9
+ require 'standings/league_reference'
10
+ require 'standings/league_results'
11
+ require 'standings/table_fetcher'
@@ -0,0 +1,58 @@
1
+ module Standings
2
+ class CLI
3
+ def record_user_selection_and_show_results!
4
+ league_selection = accept_input
5
+
6
+ if league_selection
7
+ handle_valid_league_selection(league_selection)
8
+ else
9
+ handle_help_message
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def accept_input
16
+ opts = Trollop::options do
17
+ version <<-EOS
18
+ ⚽ Standings
19
+ Version 1.0 | September 2016
20
+ Scott Luptowski | @scottluptowski
21
+ EOS
22
+ banner <<-EOS
23
+ \n⚽ Standings is a command line gem which lets users check the current standings in a number of European football/soccer leagues.
24
+ Usage:
25
+ \n
26
+ EOS
27
+ opt :epl, "🇬🇧 English Premier League", short: :e
28
+ opt :championship, "🇬🇧 English Championship", short: :c
29
+ opt :league1, "🇬🇧 English League One", short: :o
30
+ opt :league2, "🇬🇧 English League Two", short: :t
31
+ opt :spl, "🇬🇧 Scottish Premiership", short: :s
32
+ opt :liga, "🇪🇸 La Liga", short: :l
33
+ opt :ligue, "🇫🇷 Ligue 1", short: :f
34
+ opt :seriea, "🇮🇹 Seria A", short: :i
35
+ opt :bundesliga, "🇩🇪 Bundesliga", short: :d
36
+ end
37
+
38
+ opts.keys.detect { |k| opts[k] }
39
+ end
40
+
41
+ def handle_valid_league_selection(league_selection)
42
+ begin
43
+ results = TableFetcher.new(league_selection).call
44
+ Displayer.new(results).display_table
45
+ rescue TableFetcher::FetchError, TableFetcher::ParseError
46
+ handle_failure
47
+ end
48
+ end
49
+
50
+ def handle_help_message
51
+ puts "⚽ Standings requires you to pass in the flag of a league. Run with --help for help."
52
+ end
53
+
54
+ def handle_failure
55
+ puts "⚽ There was an error retrieving the scores!"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,55 @@
1
+ module Standings
2
+ class Displayer
3
+ attr_reader :results
4
+
5
+ def initialize(results)
6
+ @results = results
7
+ end
8
+
9
+ def display_table
10
+ puts dividing_line
11
+ puts "# GP Pts W D L Team"
12
+ puts dividing_line
13
+
14
+ results.teams.each do |team|
15
+ puts template(team)
16
+ sleep 0.01
17
+ end
18
+
19
+ puts dividing_line
20
+ end
21
+
22
+ def template(team)
23
+ output =
24
+ "#{(team.position.to_s).ljust(3," ")} " \
25
+ "#{team.played.to_s.ljust(3, " ")} " \
26
+ "#{team.points.to_s.ljust(5, " ")}" \
27
+ "#{team.wins.to_s.ljust(5, " ")}" \
28
+ "#{team.draws.to_s.ljust(5, " ")}" \
29
+ "#{team.losses.to_s.ljust(5, " ")}"
30
+
31
+ if results.top?(team)
32
+ output += team.name.green
33
+ elsif results.middle?(team)
34
+ output += team.name.light_blue
35
+ elsif results.bottom?(team)
36
+ output += team.name.red
37
+ else
38
+ output += team.name
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def dividing_line
45
+ # draw enough dashes so that teams with long names are still covered
46
+ # by the dashes. Given a team length integer, add it to 31
47
+ # (the length of the static puts statement in #display_table)
48
+ "-" * (31 + longest_team_name_length)
49
+ end
50
+
51
+ def longest_team_name_length
52
+ results.teams.map {|t| t.name.length }.max
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,58 @@
1
+ module Standings
2
+ LeagueReference = {
3
+ epl: {
4
+ league_full_name: "premierleague",
5
+ top_teams: 4,
6
+ middle_teams: 5,
7
+ bottom_teams: 3
8
+ },
9
+ championship: {
10
+ league_full_name: "championship",
11
+ top_teams: 2,
12
+ middle_teams: 6,
13
+ bottom_teams: 3
14
+ },
15
+ league1: {
16
+ league_full_name: "leagueonefootball",
17
+ top_teams: 2,
18
+ middle_teams: 6,
19
+ bottom_teams: 4,
20
+ },
21
+ league2: {
22
+ league_full_name: "leaguetwofootball",
23
+ top_teams: 3,
24
+ middle_teams: 7,
25
+ bottom_teams: 2
26
+ },
27
+ spl: {
28
+ league_full_name: "scottish-premiership",
29
+ top_teams: 1,
30
+ middle_teams: 3,
31
+ bottom_teams: 2
32
+ },
33
+ liga: {
34
+ league_full_name: "laligafootball",
35
+ top_teams: 4,
36
+ middle_teams: 6,
37
+ bottom_teams: 3
38
+ },
39
+ ligue: {
40
+ league_full_name: "ligue1football",
41
+ top_teams: 3,
42
+ middle_teams: 4,
43
+ bottom_teams: 3
44
+ },
45
+ seriea: {
46
+ league_full_name: "serieafootball",
47
+ top_teams: 3,
48
+ middle_teams: 5,
49
+ bottom_teams: 3
50
+ },
51
+ bundesliga: {
52
+ league_full_name: "bundesligafootball",
53
+ top_teams: 4,
54
+ middle_teams: 6,
55
+ bottom_teams: 3
56
+ }
57
+ }
58
+ end
@@ -0,0 +1,24 @@
1
+ module Standings
2
+ class LeagueResults
3
+ class Team < OpenStruct; end
4
+
5
+ attr_accessor :league, :teams
6
+
7
+ def initialize(league)
8
+ @league = league
9
+ end
10
+
11
+ def top?(team)
12
+ team.position <= LeagueReference[league][:top_teams]
13
+ end
14
+
15
+ def middle?(team)
16
+ LeagueReference[league][:middle_teams] &&
17
+ team.position <= LeagueReference[league][:middle_teams]
18
+ end
19
+
20
+ def bottom?(team)
21
+ team.position >= (teams.count - LeagueReference[league][:bottom_teams] + 1)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,70 @@
1
+ module Standings
2
+ class TableFetcher
3
+ class FetchError < StandardError; end
4
+ class ParseError < StandardError; end
5
+
6
+ attr_reader :league_selection
7
+
8
+ def initialize(league_selection)
9
+ @league_selection = league_selection
10
+ end
11
+
12
+ def call
13
+ begin
14
+ url = "https://www.theguardian.com/football/#{LeagueReference[league_selection][:league_full_name]}/table"
15
+ site = Nokogiri::HTML(open(url))
16
+ rescue
17
+ throw FetchError
18
+ end
19
+
20
+ begin
21
+ team_data = site.css('.table--league-table tbody tr')
22
+
23
+ LeagueResults.new(league_selection).tap do |lr|
24
+ lr.teams = build_teams(team_data)
25
+ end
26
+ rescue
27
+ throw ParseError
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def build_teams(team_data_xml)
34
+ team_data_xml.length.times.map do |i|
35
+ source = team_data_xml[i].children.text
36
+ build_team(source)
37
+ end
38
+ end
39
+
40
+ def build_team(source)
41
+ team_info = source.split("\n").select { |s| s != "" }
42
+
43
+ # ["1", Position
44
+ # "Chelsea", Team
45
+ # "12", Played
46
+ # "10", Win
47
+ # "2", Draw
48
+ # "0", Loss
49
+ # "30", Goals For
50
+ # "11", Goals Against
51
+ # "19", Goal Difference
52
+ # "32", Points
53
+ # "Won against C Palace",
54
+ # "Drew with Man Utd",
55
+ # "Won against QPR",
56
+ # "Won against Liverpool",
57
+ # "Won against West Brom"]
58
+
59
+ LeagueResults::Team.new({
60
+ position: team_info[0].to_i,
61
+ name: team_info[1],
62
+ played: team_info[2].to_i,
63
+ wins: team_info[3].to_i,
64
+ draws: team_info[4].to_i,
65
+ losses: team_info[5].to_i,
66
+ points: team_info[9].to_i
67
+ })
68
+ end
69
+ end
70
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standings
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Luptowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-18 00:00:00.000000000 Z
11
+ date: 2016-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -53,8 +53,8 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  description: View European football/soccer standings from your terminal. Currently
56
- supports Premier League, Scottish Premier League, La Liga, Ligue 1, Serie A, and
57
- Bundesliga
56
+ supports English Premier League, Championship, League One and Two, Scottish Premiership,
57
+ La Liga, Ligue 1, Serie A, and Bundesliga
58
58
  email: scottluptowski@gmail.com
59
59
  executables:
60
60
  - standings
@@ -62,12 +62,12 @@ extensions: []
62
62
  extra_rdoc_files: []
63
63
  files:
64
64
  - bin/standings
65
- - config/environment.rb
66
- - lib/displayer.rb
67
- - lib/league_reference.rb
68
65
  - lib/standings.rb
69
- - lib/table_scraper.rb
70
- - lib/team.rb
66
+ - lib/standings/cli.rb
67
+ - lib/standings/displayer.rb
68
+ - lib/standings/league_reference.rb
69
+ - lib/standings/league_results.rb
70
+ - lib/standings/table_fetcher.rb
71
71
  homepage: http://www.github.com/scottluptowski/standings
72
72
  licenses:
73
73
  - MIT
@@ -88,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
88
  version: '0'
89
89
  requirements: []
90
90
  rubyforge_project:
91
- rubygems_version: 2.5.1
91
+ rubygems_version: 2.4.5.1
92
92
  signing_key:
93
93
  specification_version: 4
94
94
  summary: football/soccer standings
@@ -1,10 +0,0 @@
1
- require 'nokogiri'
2
- require 'open-uri'
3
- require 'colorize'
4
- require 'trollop'
5
- require 'pry'
6
-
7
- require_relative '../lib/league_reference.rb'
8
- require_relative '../lib/displayer.rb'
9
- require_relative '../lib/table_scraper.rb'
10
- require_relative '../lib/team.rb'
@@ -1,35 +0,0 @@
1
- class Displayer
2
-
3
- def call
4
- display_table
5
- end
6
-
7
- def template(team)
8
- output = "#{(team.position).ljust(3," ")} #{team.played.ljust(3, " ")} #{team.points.to_s.ljust(5, " ")}"
9
-
10
- if team.top?
11
- output += team.name.green
12
- elsif team.middle?
13
- output += team.name.light_blue
14
- elsif team.bottom?
15
- output += team.name.red
16
- else
17
- output += team.name
18
- end
19
- end
20
-
21
- def display_table
22
- puts dashes_for_display_table
23
- puts "# P Pts Team"
24
- puts dashes_for_display_table
25
- Team::teams.each { |team| puts template(team); sleep 0.01 }
26
- puts dashes_for_display_table
27
- end
28
-
29
- def dashes_for_display_table
30
- # draw enough dashes so that teams with long names are still covered
31
- #by the dashes. Given a team length integer, add it to 17
32
- #(the length of the static puts statement in #display_table)
33
- "-" * (17 + Team.get_longest_team_name_length)
34
- end
35
- end
@@ -1,59 +0,0 @@
1
- class LeagueReference
2
- class << self
3
- attr_accessor :league_symbol, :league_full_name, :top_teams, :middle_teams, :bottom_teams
4
- end
5
-
6
- LeaguesHash = {
7
- :epl => {
8
- :league_full_name => "premierleague",
9
- :top_teams => 4,
10
- :middle_teams => 5,
11
- :bottom_teams => 3
12
- },
13
- :championship => {
14
- :league_full_name => "championship",
15
- :top_teams => 2,
16
- :middle_teams => 6,
17
- :bottom_teams => 3
18
- },
19
- :spl => {
20
- :league_full_name => "scottishpremierleague",
21
- :top_teams => 1,
22
- :middle_teams => 3,
23
- :bottom_teams => 2
24
- },
25
- :liga => {
26
- :league_full_name => "laligafootball",
27
- :top_teams => 3,
28
- :middle_teams => 6,
29
- :bottom_teams => 3
30
- },
31
- :ligue => {
32
- :league_full_name => "ligue1football",
33
- :top_teams => 3,
34
- :middle_teams => 4,
35
- :bottom_teams => 3
36
- },
37
- :seriea => {
38
- :league_full_name => "serieafootball",
39
- :top_teams => 3,
40
- :middle_teams => 5,
41
- :bottom_teams => 3
42
- },
43
- :bundesliga => {
44
- :league_full_name => "bundesligafootball",
45
- :top_teams => 4,
46
- :middle_teams => 6,
47
- :bottom_teams => 3
48
- }
49
- }
50
-
51
- def self.set_league_info(league_selection)
52
- self.league_symbol = league_selection
53
- %w(league_full_name top_teams middle_teams bottom_teams).each do |attr|
54
- self.send("#{attr}=", LeaguesHash[league_symbol][attr.to_sym])
55
- end
56
-
57
- league_selection
58
- end
59
- end
@@ -1,31 +0,0 @@
1
- class TableScraper
2
-
3
- attr_accessor :url, :teams
4
-
5
- def initialize
6
- @url = "https://www.theguardian.com/football/" + LeagueReference::league_full_name + "/table"
7
- end
8
-
9
- def call
10
- site = Nokogiri::HTML(open(@url))
11
- self.teams = site.css('.table--league-table tbody tr')
12
- build_teams
13
- end
14
-
15
- def build_teams
16
- teams.length.times do |i|
17
- source = teams[i].children.text
18
- team_data = source.split("\n").select { |s| s != "" }
19
-
20
- #["1", "Spurs", "2", "2", "0", "0", "5", "0", "5", "6"]
21
- #Pos Team P W D L F A GD Pts
22
-
23
- Team.new({
24
- :position => team_data[0],
25
- :name => team_data[1],
26
- :played => team_data[2],
27
- :points => team_data[9]
28
- })
29
- end
30
- end
31
- end
@@ -1,41 +0,0 @@
1
- class Team
2
- class << self
3
- attr_accessor :longest_team_name_length
4
- end
5
-
6
- attr_accessor :name, :position, :played, :points
7
-
8
- @@teams = []
9
-
10
- def initialize(info)
11
- @name = info[:name]
12
- @played = info[:played]
13
- @points = info[:points]
14
- @position = info[:position]
15
- @@teams << self
16
- end
17
-
18
- def top?
19
- position.to_i <= LeagueReference.top_teams
20
- end
21
-
22
- def middle?
23
- LeagueReference.middle_teams && position.to_i <= LeagueReference.middle_teams
24
- end
25
-
26
- def bottom?
27
- position.to_i >= (Team.teams_count - LeagueReference.bottom_teams + 1)
28
- end
29
-
30
- def self.teams
31
- @@teams
32
- end
33
-
34
- def self.teams_count
35
- @@teams.count
36
- end
37
-
38
- def self.get_longest_team_name_length
39
- @longest_team_name_length ||= teams.sort_by {|t| t.name.length }.last.name.length
40
- end
41
- end