barbershop_contestants 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +91 -0
- data/LICENSE.txt +21 -0
- data/README.md +37 -0
- data/Rakefile +2 -0
- data/barbershop_contestants.gemspec +49 -0
- data/bin/barbershop_contestants +15 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/barbershop_contestants/cli.rb +214 -0
- data/lib/barbershop_contestants/competitor.rb +90 -0
- data/lib/barbershop_contestants/contest.rb +33 -0
- data/lib/barbershop_contestants/performance.rb +83 -0
- data/lib/barbershop_contestants/scraper.rb +177 -0
- data/lib/barbershop_contestants/version.rb +3 -0
- data/lib/barbershop_contestants.rb +22 -0
- data/pkg/barbershop-contestants-0.2.0.gem +0 -0
- data/pkg/barbershop_contestants-0.1.0.gem +0 -0
- data/pkg/barbershop_contestants-0.2.0.gem +0 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project.htm +972 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/300px-2018_After_Hours.jpg +0 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/After Hours (BHS) - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project.html +883 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS International Chorus Champions - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project.html +973 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS International Quartet Champions - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project.html +496 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS Intl Chorus Contest 2018 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project.htm +454 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS Intl Quartet Contest 1940 - Barbershop Wiki Project_files/tpc-check.html +3 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project.htm +633 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS Intl Quartet Contest 1987 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project.htm +591 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project.html +590 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/BHS Intl Quartet Contest 2018 - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project.htm +303 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/1940Pic.jpg +0 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/Flat Foot Four - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project.htm +302 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/1987Pic.jpg +0 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/cc-by-nc-sa.png +0 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(1).php +21 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(2).php +1 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/load(3).php +178 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/load.php +1 -0
- data/sites/Interstate Rivals - Barbershop Wiki Project_files/poweredby_mediawiki_88x31.png +0 -0
- 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
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,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,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
|