barbershop_contestants 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +1 -0
  3. data/CHANGELOG.md +1 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +91 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +37 -0
  8. data/Rakefile +2 -0
  9. data/barbershop_contestants.gemspec +49 -0
  10. data/bin/barbershop_contestants +15 -0
  11. data/bin/console +16 -0
  12. data/bin/setup +8 -0
  13. data/lib/barbershop_contestants/cli.rb +214 -0
  14. data/lib/barbershop_contestants/competitor.rb +90 -0
  15. data/lib/barbershop_contestants/contest.rb +33 -0
  16. data/lib/barbershop_contestants/performance.rb +83 -0
  17. data/lib/barbershop_contestants/scraper.rb +177 -0
  18. data/lib/barbershop_contestants/version.rb +3 -0
  19. data/lib/barbershop_contestants.rb +22 -0
  20. data/pkg/barbershop-contestants-0.2.0.gem +0 -0
  21. data/pkg/barbershop_contestants-0.1.0.gem +0 -0
  22. data/pkg/barbershop_contestants-0.2.0.gem +0 -0
  23. data/sites/After Hours (BHS) - Barbershop Wiki Project.htm +972 -0
  24. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/300px-2018_After_Hours.jpg +0 -0
  25. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  26. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(1).php +21 -0
  27. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(2).php +1 -0
  28. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(3).php +178 -0
  29. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load.php +1 -0
  30. data/sites/After Hours (BHS) - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  31. data/sites/BHS International Chorus Champions - Barbershop Wiki Project.html +883 -0
  32. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  33. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(1).php +21 -0
  34. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(2).php +1 -0
  35. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(3).php +178 -0
  36. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load.php +1 -0
  37. data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  38. data/sites/BHS International Quartet Champions - Barbershop Wiki Project.html +973 -0
  39. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  40. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(1).php +21 -0
  41. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(2).php +1 -0
  42. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(3).php +178 -0
  43. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load.php +1 -0
  44. data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  45. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project.html +496 -0
  46. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  47. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(1).php +21 -0
  48. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(2).php +1 -0
  49. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(3).php +178 -0
  50. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load.php +1 -0
  51. data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  52. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project.htm +454 -0
  53. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  54. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(1).php +21 -0
  55. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(2).php +1 -0
  56. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(3).php +178 -0
  57. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load.php +1 -0
  58. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  59. data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/tpc-check.html +3 -0
  60. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project.htm +633 -0
  61. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  62. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(1).php +21 -0
  63. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(2).php +1 -0
  64. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(3).php +178 -0
  65. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load.php +1 -0
  66. data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  67. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project.htm +591 -0
  68. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project.html +590 -0
  69. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  70. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(1).php +21 -0
  71. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(2).php +1 -0
  72. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(3).php +178 -0
  73. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load.php +1 -0
  74. data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  75. data/sites/Flat Foot Four - Barbershop Wiki Project.htm +303 -0
  76. data/sites/Flat Foot Four - Barbershop Wiki Project_files/1940Pic.jpg +0 -0
  77. data/sites/Flat Foot Four - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  78. data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(1).php +21 -0
  79. data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(2).php +1 -0
  80. data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(3).php +178 -0
  81. data/sites/Flat Foot Four - Barbershop Wiki Project_files/load.php +1 -0
  82. data/sites/Flat Foot Four - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  83. data/sites/Interstate Rivals - Barbershop Wiki Project.htm +302 -0
  84. data/sites/Interstate Rivals - Barbershop Wiki Project_files/1987Pic.jpg +0 -0
  85. data/sites/Interstate Rivals - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
  86. data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(1).php +21 -0
  87. data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(2).php +1 -0
  88. data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(3).php +178 -0
  89. data/sites/Interstate Rivals - Barbershop Wiki Project_files/load.php +1 -0
  90. data/sites/Interstate Rivals - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
  91. metadata +235 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4b0fba353b50e988a9b343dccc67139af2197fbc
4
+ data.tar.gz: ad01c1da9472974c40ded8ce4bcf96a511bbd020
5
+ SHA512:
6
+ metadata.gz: 7504de419f48b6d9ed65657a8a140d10f40eba760868b6e34dba509f43a4cc9c00f3f85fefb5f3d6ce224d41f6d99508a2d1ded85c3aac547913aa9c97e46c28
7
+ data.tar.gz: d6a4654f69a851a8e186553db4cd80b5a71b7986828cd1706d967565b0196b2bafd3be1402f54989a470a6b813e809f916f494829183ff588525703db282ea5c
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/CHANGELOG.md ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in barbershop_contestants.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ barbershop_contestants (0.2.0)
5
+ nokogiri (~> 1.8.5)
6
+ require_all (~> 2.0.0)
7
+ tty-table (~> 0.10.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (5.2.2)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 0.7, < 2)
15
+ minitest (~> 5.1)
16
+ tzinfo (~> 1.1)
17
+ addressable (2.5.2)
18
+ public_suffix (>= 2.0.2, < 4.0)
19
+ coderay (1.1.2)
20
+ concurrent-ruby (1.1.4)
21
+ equatable (0.5.0)
22
+ faraday (0.15.4)
23
+ multipart-post (>= 1.2, < 3)
24
+ faraday-http-cache (2.0.0)
25
+ faraday (~> 0.8)
26
+ github_changelog_generator (1.14.3)
27
+ activesupport
28
+ faraday-http-cache
29
+ multi_json
30
+ octokit (~> 4.6)
31
+ rainbow (>= 2.1)
32
+ rake (>= 10.0)
33
+ retriable (~> 2.1)
34
+ i18n (1.3.0)
35
+ concurrent-ruby (~> 1.0)
36
+ method_source (0.9.2)
37
+ mini_portile2 (2.3.0)
38
+ minitest (5.11.3)
39
+ multi_json (1.13.1)
40
+ multipart-post (2.0.0)
41
+ necromancer (0.4.0)
42
+ nokogiri (1.8.5-x64-mingw32)
43
+ mini_portile2 (~> 2.3.0)
44
+ octokit (4.13.0)
45
+ sawyer (~> 0.8.0, >= 0.5.3)
46
+ pastel (0.7.2)
47
+ equatable (~> 0.5.0)
48
+ tty-color (~> 0.4.0)
49
+ pry (0.12.2)
50
+ coderay (~> 1.1.0)
51
+ method_source (~> 0.9.0)
52
+ public_suffix (3.0.3)
53
+ rainbow (3.0.0)
54
+ rake (10.5.0)
55
+ require_all (2.0.0)
56
+ retriable (2.1.0)
57
+ sawyer (0.8.1)
58
+ addressable (>= 2.3.5, < 2.6)
59
+ faraday (~> 0.8, < 1.0)
60
+ strings (0.1.4)
61
+ strings-ansi (~> 0.1.0)
62
+ unicode-display_width (~> 1.4.0)
63
+ unicode_utils (~> 1.4.0)
64
+ strings-ansi (0.1.0)
65
+ thread_safe (0.3.6)
66
+ tty-color (0.4.3)
67
+ tty-screen (0.6.5)
68
+ tty-table (0.10.0)
69
+ equatable (~> 0.5.0)
70
+ necromancer (~> 0.4.0)
71
+ pastel (~> 0.7.2)
72
+ strings (~> 0.1.0)
73
+ tty-screen (~> 0.6.4)
74
+ tzinfo (1.2.5)
75
+ thread_safe (~> 0.1)
76
+ unicode-display_width (1.4.1)
77
+ unicode_utils (1.4.0)
78
+
79
+ PLATFORMS
80
+ ruby
81
+ x64-mingw32
82
+
83
+ DEPENDENCIES
84
+ barbershop_contestants!
85
+ bundler (~> 1.17)
86
+ github_changelog_generator (~> 1.14.3)
87
+ pry (~> 0.12.2)
88
+ rake (~> 10.0)
89
+
90
+ BUNDLED WITH
91
+ 1.17.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # BarbershopContestants
2
+
3
+ A ruby gem that scrapes [the Barbershop Harmony wiki](https://www.barbershopwiki.com/wiki/Barbershop_Wiki_Project) and provides info on contestants in the Barbershop Harmony Society International Competition. This gem is my Ruby CLI project for the [Learn.co](https://learn.co) web development track section one. Shout out to the other members of the "A Bug's Life" cohort!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'barbershop_contestants'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install barbershop_contestants
20
+
21
+ ## Usage
22
+
23
+ Follow the prompts to drill down into the various participants in the BHS International Competition
24
+
25
+ ## Development
26
+
27
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
28
+
29
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
+
31
+ ## Contributing
32
+
33
+ Bug reports and pull requests are welcome on GitHub at https://github.com/artrexdenthur/barbershop_contestants.
34
+
35
+ ## License
36
+
37
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,49 @@
1
+
2
+ lib = File.expand_path("lib", __dir__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "barbershop_contestants/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "barbershop_contestants"
8
+ spec.version = BarbershopContestants::VERSION
9
+ spec.authors = ["Paul Ashour"]
10
+ spec.email = ["paul.ashour@gmail.com"]
11
+
12
+ spec.summary = "A quick Ruby Gem that scrapes barbershopwiki.com for the Learn.co Ruby CLI project."
13
+ spec.description = "This Gem scrapes barbershopwiki.com and organizes the data for perusal via a simple CLI. Created for the Ruby CLI project in section one of Learn.co's Full Stack Web Development program."
14
+ spec.homepage = "https://github.com/artrexdenthur/Ruby-Gem-Project-Barbershop-Contestants"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
+ #
22
+ # spec.metadata["homepage_uri"] = spec.homepage
23
+ # spec.metadata["source_code_uri"] = "https://github.com/artrexdenthur/oo-student-scraper-online-web-pt-102218.git"
24
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
25
+ # else
26
+ # raise "RubyGems 2.0 or newer is required to protect against " \
27
+ # "public gem pushes."
28
+ # end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = "bin"
36
+ spec.executables = ["barbershop_contestants"]
37
+ spec.require_paths = ["lib"]
38
+
39
+ spec.add_development_dependency "bundler", "~> 1.17"
40
+ spec.add_development_dependency "github_changelog_generator", "~> 1.14.3"
41
+ spec.add_development_dependency "pry", "~> 0.12.2"
42
+ spec.add_development_dependency "rake", "~> 10.0"
43
+
44
+ spec.add_runtime_dependency "nokogiri", "~> 1.8.5"
45
+ spec.add_runtime_dependency "require_all", "~> 2.0.0"
46
+ spec.add_runtime_dependency "tty-table", "~> 0.10.0"
47
+
48
+
49
+ end
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "nokogiri"
5
+ require "open-uri"
6
+ require "require_all"
7
+ require "tty-table"
8
+
9
+ require "pry"
10
+ require "irb"
11
+
12
+ require "barbershop_contestants"
13
+
14
+ # hello from Sue
15
+ # and hello from Dozuki
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "nokogiri"
5
+ require "open-uri"
6
+ require "require_all"
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+
16
+ require "barbershop_contestants"
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,214 @@
1
+ # command line interface
2
+ # responsible for starting the scraping/org process
3
+ # and providing the user with an interface
4
+ class CLI
5
+ # Contest::Quartets.scrape_contests
6
+
7
+ @welcome_message = "Welcome to the Barbershop Contestants CLI!"
8
+
9
+ @command_verb_hash = {
10
+ "quar" => [:display, "quartet"],
11
+ "chor" => [:display, "chorus"],
12
+ "help" => [:help, ""],
13
+ "quit" => [:quit, ""],
14
+ "load" => [:load, ""]
15
+ }
16
+
17
+ @type_years_hash = {
18
+ "quartet" => (1939..2018),
19
+ "chorus" => (1953..2018)
20
+ }
21
+
22
+ def self.start
23
+ # welcome the user and show command list
24
+ # have the bin file call this method
25
+ # scrape data from here, logic primarily in scraper
26
+ system "clear" or system "cls"
27
+ puts @welcome_message
28
+ @source = choose_source
29
+ Scraper.scrape_and_create_quartet_champs(@source)
30
+ Scraper.scrape_and_create_chorus_champs(@source)
31
+ Scraper.scrape_and_create_year(@source, 2018, "quartet") # remove in final
32
+ Scraper.scrape_and_create_year(@source, 2018, "chorus") # remove in final
33
+ request_command
34
+ input_loop
35
+ end
36
+
37
+ def self.choose_source
38
+ return :web
39
+ # loop do
40
+ # puts "Enter web or local:"
41
+ # entry = gets.chomp
42
+ # return entry.to_sym if %w[web local].include?(entry)
43
+ # end
44
+ ### Reverse the comments in this method to be offered a choice at launch
45
+ ### between web scraping and local scraping.
46
+ end
47
+
48
+ def self.input_loop
49
+ # binding.pry
50
+ loop do
51
+ puts "\nEnter a command:"
52
+ process_command(gets.chomp.downcase)
53
+ end
54
+ end
55
+
56
+ def self.request_command
57
+ puts "Please enter a command."
58
+ puts "To see all entries in a contest, enter the type of contest " \
59
+ "(quartet or chorus) and the year (1939-2018 for quartets, " \
60
+ "1953-2018 for choruses)"
61
+ puts "To see all performances currently in cache by a particular group, " \
62
+ "enter the name of the group"
63
+ puts "To see a list of all champions for a contest type, enter " \
64
+ "'quartet champions' or 'chorus champions'"
65
+ puts "To load all contests, or all contests of one type, " \
66
+ "enter 'load all', 'load quartets', or 'load choruses'"
67
+ puts "To quit, enter 'quit'"
68
+ puts "To see this info again, enter 'help'"
69
+ end
70
+
71
+ def self.process_command(command)
72
+ # parses the given input between command types.
73
+ # full "quartet" and "chorus" parsing is in other methods.
74
+ system "clear" or system "cls"
75
+ command_arr = command.split
76
+ if command_arr[0] # the user typed something
77
+ parse_command_verb(command_arr) || show_competitor(command) || no_command
78
+ else
79
+ no_command
80
+ end
81
+ end
82
+
83
+ def self.parse_command_verb(commands)
84
+ verb = @command_verb_hash.find { |k, _| commands[0].start_with?(k) }
85
+ # binding.pry
86
+ verb ? send(verb[1][0], verb[1][1], commands.drop(1)) : false
87
+ end
88
+
89
+ def self.display(type, commands)
90
+ # type contains competitor type string (chorus or quartet)
91
+ # commands contains remainder of user input as string array
92
+ if commands.any? { |c| c.start_with?("cham") } # check for champs command
93
+ display_champs(type)
94
+ true
95
+ elsif (year = commands.find { |c| @type_years_hash[type].include? c.to_i })
96
+ display_year(year.to_i, type)
97
+ true
98
+ else
99
+ false
100
+ end
101
+ end
102
+
103
+ def self.display_champs(type)
104
+ champs_arr = Performance.filter_all(place: 1, type: type)
105
+ title = "BHS International #{type.capitalize} Champions"
106
+ headers = ["Year", type.capitalize, "District", "Score"]
107
+ rows = champs_arr.map do |p|
108
+ disp_arr = []
109
+ disp_arr.push(p.year, p.competitor.name, p.competitor.district, p.score)
110
+ end
111
+ print_tty_table(title: title, headers: headers, rows: rows)
112
+ true
113
+ end
114
+
115
+ def self.display_year(year, type)
116
+ Scraper.scrape_and_create_year(@source, year, type)
117
+ year_arr = Performance.filter_all(year: year, type: type)
118
+ title = "BHS International #{type.capitalize} Competition #{year}"
119
+ headers = ["Place", type.capitalize, "District", "Score"]
120
+ rows = year_arr.map do |p|
121
+ disp_arr = []
122
+ disp_arr.push(p.place, p.competitor.name, p.competitor.district, p.score)
123
+ end
124
+ print_tty_table(title: title, headers: headers, rows: rows)
125
+ end
126
+
127
+ def self.load(_, commands)
128
+ case commands
129
+ when commands.any? { |c| c.start_with?("quar") }
130
+ type = "quartet"
131
+ when commands.any? { |c| c.start_with?("chor") }
132
+ type = "chorus"
133
+ else
134
+ type = nil
135
+ end
136
+ load_all(type)
137
+ true
138
+ end
139
+
140
+ def self.load_all(type)
141
+ if type
142
+ @type_years_hash[type].each do |y|
143
+ Scraper.scrape_and_create_year(@source, y, type)
144
+ end
145
+ else
146
+ @type_years_hash.each do |type, year_range|
147
+ year_range.each do |year|
148
+ Scraper.scrape_and_create_year(@source, year, type)
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ def self.help(*_)
155
+ request_command
156
+ end
157
+
158
+ def self.quit(*_)
159
+ puts "Goodbye!"
160
+ IRB.start(__FILE__)
161
+ exit
162
+ end
163
+
164
+ def self.show_competitor(name)
165
+ comp = Competitor.all.find{ |c| c.name.downcase == name }
166
+ # binding.pry
167
+ if comp
168
+ puts comp.name, comp.type.capitalize, "District: #{comp.district}"
169
+ if comp.type == "quartet"
170
+ comp.comments && (puts "Comments: #{comp.comments}")
171
+ comp.members && (puts "Members: #{comp.members}")
172
+ else
173
+ comp.director && (puts "Director: #{comp.director}")
174
+ comp.hometown && (puts "Hometown: #{comp.hometown}")
175
+ end
176
+ show_competitor_performances(comp)
177
+ else
178
+ false
179
+ end
180
+ true
181
+ end
182
+
183
+ def self.show_competitor_performances(com)
184
+ title = "Performances"
185
+ headers = ["Year", "Place", "Score"]
186
+ headers << "# On Stage" if com.type == "chorus"
187
+ perf_arr = com.performances.sort_by { |p| p.year }.reverse
188
+ # binding.pry
189
+ rows = perf_arr.map do |p|
190
+ disp_arr = []
191
+ disp_arr.push(p.number_on_stage) if com.type == "chorus"
192
+ disp_arr.unshift(p.year, p.place, p.score)
193
+ end
194
+ # binding.pry
195
+ print_tty_table(title: title, headers: headers, rows: rows)
196
+ end
197
+
198
+ def self.print_tty_table(title: nil, headers: nil, rows:)
199
+ puts title if title
200
+ # binding.pry
201
+ if headers
202
+ table = TTY::Table.new headers, rows
203
+ else
204
+ table = TTY::Table.new rows
205
+ end
206
+ puts table.render(:ascii, padding: [0,1,0,1])
207
+ end
208
+
209
+ def self.no_command
210
+ puts "Sorry, that command was not recognized\n"
211
+ request_command
212
+ end
213
+
214
+ end
@@ -0,0 +1,90 @@
1
+ # comprises two types: quartet and chorus
2
+ # each has an m-to-m relationship with Contest::Quartet
3
+ # and Contest::Chorus, respectively
4
+ class Competitor
5
+ attr_accessor :performances, :district, :name, :type
6
+
7
+ @@all = []
8
+
9
+ def save
10
+ Competitor.all << self
11
+ end
12
+
13
+ def self.find_or_create(arg_hash)
14
+ self.all.find { |x| x.name == arg_hash[:name] } || self.create(arg_hash)
15
+ end
16
+
17
+ def self.fill_find_or_create(arg_hash)
18
+ if self.all.find { |c| c.name == arg_hash[:name] }
19
+ self.fill(arg_hash)
20
+ else
21
+ self.create(arg_hash)
22
+ end
23
+ end
24
+
25
+ def self.create(arg_hash)
26
+ competitor = self.new(arg_hash)
27
+ competitor.save
28
+ competitor
29
+ end
30
+
31
+ def self.all
32
+ @@all
33
+ end
34
+
35
+ end
36
+
37
+ class Quartet < Competitor
38
+
39
+ attr_accessor :tenor, :lead, :baritone, :bass, :comments, :members
40
+
41
+ def initialize(arg_hash)
42
+ self.name = arg_hash[:name]
43
+ self.type = 'quartet'
44
+ self.district = arg_hash[:district]
45
+ self.performances = (arg_hash[:performances] || [])
46
+ self.comments = arg_hash[:comments]
47
+ self.members = self.format_members(arg_hash[:members])
48
+ end
49
+
50
+ def format_members(member_string)
51
+ self.members = member_string
52
+ # TODO: modify to pull out the members and put them in their own hashes
53
+ end
54
+
55
+ def self.all
56
+ @@all.find_all { |c| c.type == "quartet" }
57
+ end
58
+ end
59
+
60
+ class Chorus < Competitor
61
+
62
+ attr_accessor :hometown, :director
63
+
64
+ def initialize(arg_hash)
65
+ self.name = arg_hash[:name]
66
+ self.type = 'chorus'
67
+ self.district = arg_hash[:district]
68
+ format_hometown_and_district(arg_hash[:hometown_and_district])
69
+ self.performances = (arg_hash[:performances] || [])
70
+ self.director = arg_hash[:director]
71
+ end
72
+
73
+ def current_director
74
+ performances.max { |p| p.year.to_i }.director
75
+ end
76
+
77
+ def format_hometown_and_district(hometown_and_district)
78
+ # TODO: plug this logic in
79
+ if hometown_and_district
80
+ h_d_match = /(?<h>.*) \((?<d>.*)\)/.match(hometown_and_district)
81
+ self.hometown = h_d_match[:h]
82
+ self.district = h_d_match[:d]
83
+ end
84
+ end
85
+
86
+ def self.all
87
+ @@all.find_all { |c| c.type == "chorus" }
88
+ end
89
+
90
+ end
@@ -0,0 +1,33 @@
1
+ # holds the data specific to each contest
2
+ class Contest
3
+ # now there's text again
4
+ attr_accessor :performances, :year, :city, :type
5
+
6
+ @@all = []
7
+
8
+ def initialize(arg_hash)
9
+ self.performances = (arg_hash[:performances] || [])
10
+ self.year = arg_hash[:year]
11
+ self.city = arg_hash[:city]
12
+ self.type = arg_hash[:type]
13
+ end
14
+
15
+ def save
16
+ Contest.all << self
17
+ end
18
+
19
+ def self.find_or_create(arg_hash)
20
+ self.all.find { |x| x.year == arg_hash[:year] && x.type == arg_hash[:type] } || self.create(arg_hash)
21
+ end
22
+
23
+ def self.create(arg_hash)
24
+ contest = self.new(arg_hash)
25
+ contest.save
26
+ contest
27
+ end
28
+
29
+ def self.all
30
+ @@all
31
+ end
32
+
33
+ end
@@ -0,0 +1,83 @@
1
+ # competitors have many contests through performances and vice versa
2
+ class Performance
3
+ attr_accessor :contest, :competitor, :score, :place, :year, :number_on_stage, :director
4
+
5
+ @@all = []
6
+
7
+ def initialize(arg_hash)
8
+ self.year = arg_hash[:year]
9
+ self.score = arg_hash[:score]
10
+ self.place = arg_hash[:place]
11
+ # the following will generally be nil at this point
12
+ self.contest = arg_hash[:contest]
13
+ self.competitor = arg_hash[:competitor]
14
+ self.number_on_stage = arg_hash[:number_on_stage]
15
+ self.director = arg_hash[:director]
16
+ end
17
+
18
+ def save
19
+ @@all << self
20
+ end
21
+
22
+ def self.create(arg_hash)
23
+ performance = new(arg_hash)
24
+ performance.save
25
+ performance
26
+ end
27
+
28
+ def self.create_q_performance(q_champs_hash)
29
+ performance = create(q_champs_hash)
30
+ performance.competitor = Quartet.find_or_create(q_champs_hash)
31
+ performance.competitor.performances << performance
32
+ performance.contest = Contest.find_or_create(q_champs_hash)
33
+ performance.contest.performances << performance
34
+ performance
35
+ end
36
+
37
+ def self.create_c_performance(c_champs_hash)
38
+ performance = create(c_champs_hash)
39
+ performance.competitor = Chorus.find_or_create(c_champs_hash)
40
+ performance.competitor.performances << performance
41
+ performance.contest = Contest.find_or_create(c_champs_hash)
42
+ performance.contest.performances << performance
43
+ performance
44
+ end
45
+
46
+ def self.create_performance(arg_hash, type)
47
+ performance = create(arg_hash)
48
+ performance.competitor = \
49
+ (type == "chorus" ? Chorus : Quartet).send :find_or_create, arg_hash
50
+ performance.competitor.performances << performance
51
+ performance.contest = Contest.find_or_create(arg_hash)
52
+ performance.contest.performances << performance
53
+ performance
54
+ end
55
+
56
+ def self.find_or_create(arg_hash, type)
57
+ found = self.all.find do |p|
58
+ p.year == arg_hash[:year] && p.competitor.name == arg_hash[:name]
59
+ end
60
+ found || create_performance(arg_hash, type)
61
+ end
62
+
63
+ def self.champs_type_by_year(type)
64
+ all.select { |p| p.place == 1 && p.contest.type = type }.sort_by { |p| p.year }
65
+ end
66
+
67
+ def self.filter_all(place: nil, year: nil, type: nil, comp_name: nil)
68
+ filter = self.all
69
+ place && filter = filter.select { |p| p.place == place }.sort_by { |p| p.year.to_i }
70
+ year && filter = filter.select { |p| p.year == year }.sort_by { |p| p.place.to_i }
71
+ type && filter = filter.select { |p| p.competitor.type == type }
72
+ comp_name && filter = filter.select { |p| p.competitor.name == name }
73
+ filter
74
+ end
75
+
76
+ def self.all
77
+ @@all
78
+ end
79
+
80
+ def self.clear
81
+ @@all.clear
82
+ end
83
+ end