BestFriendFinder 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 18a6e178ab485b0c6720b8ca012571a8b1bbddcf
4
+ data.tar.gz: 6262bc78087585dd39b3117083ea0189c35f7b79
5
+ SHA512:
6
+ metadata.gz: db9a2da43692a1b48eaa6a2e57d00974614f520bd561251968e330866f64ebbd37bec37f210f604c23313a67d11b3444676172088ed2d81485a2bede52c9e120
7
+ data.tar.gz: c3e2b6927d19c9a8eddd9648fddcdc71f60cbc8032216bf1a76c17531d0bae015883bb2970eddb41d5fd8604e16d73f4699a3351de890e0ba59221c33623cb62
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in furry_friend_finder.gemspec
4
+ gemspec
data/NOTES.md ADDED
@@ -0,0 +1,35 @@
1
+ -------- To Do ----------
2
+ [X] Download gem from bundler
3
+ [X] Set up GitHub Repo
4
+ [X] Copy spec.md from Learn repo
5
+ [X] Watch Resources videos on Learn page
6
+
7
+ [X] Figure out how the 'require' and environment settings need to work
8
+ [X] Plan out the project structure using test data
9
+ [X] Start with building the executable file
10
+ [X] Begin replacing test data with real data from BFAS site
11
+ [X] List the objects that we can create & start making objects
12
+ [X] Record myself coding for 30 mins.
13
+ --5/13/17--
14
+ [X] Clean up code in CLI #call method
15
+ [X] Break out code into separate methods where necessary
16
+ [X] Remove #find_details_url method from Scraper
17
+ [X] Think through how we can use same methods for cats/birds/etc.
18
+ [X] Write something that does not add the dog object to the list of @@all if the dog already exists
19
+ --5/14/17--
20
+ [X] What if user enters number outside of acceptable range?
21
+ [X] Can we use already-created species variable from AnimalFactory class instead of having them in each animal class?
22
+ [X] Environment file - requiring all files in lib?
23
+ [X] check_attributes_for_nil method - how to make that cleaner?
24
+ -----------
25
+ [X] Update the README file
26
+ [X] Update the specifications of the .gemspec file
27
+ [X] Update the spec.md file
28
+ [X] Write a blog
29
+ [X] Publish blog
30
+ [X] Prepare a video demo on how to use the gem
31
+ [ ] Get permission from BFAS to scrape their site -pending-
32
+ [ ] Publish gem to RubyGems.org
33
+
34
+ ------ Notes -------
35
+ Data to scrape: http://bestfriends.org/adopt/adopt-our-sanctuary
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # BestFriendFinder
2
+
3
+ BestFriendFinder helps you find your new best friend by displaying animals that are available for adoption
4
+ at the [Best Friend Animals Society](http://bestfriends.org/adopt/adopt-our-sanctuary)'s sanctuary in Kanab, UT. Help millions of homeless animals by choosing to
5
+ '#AdoptDontShop'.
6
+
7
+ ![](http://dingo.care2.com/pictures/greenliving/1012/1011871.large.jpg)
8
+
9
+ BestFriendFinder lists available dogs, cats, rabbits, birds, horses, pigs, barnyard and small & furry animals.
10
+ You can learn more about the animal right here in the BestFriendFinder app, or copy/paste the link in your browser
11
+ to find out how to adopt!
12
+
13
+ All content published by Best Friends is the property of Best Friends and is protected by copyright, trademark, and other intellectual property laws.
14
+
15
+ For more information on how to use the app, see my [video walkthrough](https://www.youtube.com/watch?v=nJbM3NQelmk&feature=youtu.be)!
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```
22
+ ruby
23
+ gem 'bestfriendfinder'
24
+ ```
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install bestfriendfinder
33
+
34
+ ## Usage
35
+
36
+ Type `bestfriendfinder` in the command line.
37
+
38
+ ## Development
39
+
40
+ After checking out the repo, run `bin/setup` to install dependencies.
41
+
42
+ 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).
43
+
44
+ ## Contributing
45
+
46
+ Bug reports and pull requests are welcome on GitHub at https://github.com/alexisadorn/BestFriendFinder-cli-app.
47
+
48
+ ## License
49
+
50
+ 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,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "BestFriendFinder"
8
+ spec.version = BestFriendFinder::VERSION
9
+ spec.authors = ["'Alexis Dorn'"]
10
+ spec.email = ["'alexisadorn@gmail.com'"]
11
+
12
+ spec.summary = %q{A list of animals available for adoption.}
13
+ spec.description = %q{CLI app that scrapes information and returns a list of animals available for adoption
14
+ and their details from the Best Friends Animal Society sanctuary in Utah. http://bestfriends.org/}
15
+ spec.homepage = "https://github.com/alexisadorn/BestFriendFinder-cli-app"
16
+ spec.licenses = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = "bin"
22
+ spec.executables = ["bestfriendfinder"]
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.14"
26
+ spec.add_development_dependency "rake", "~> 10.0"
27
+ spec.add_development_dependency "rspec", ">= 0"
28
+ spec.add_development_dependency "nokogiri", ">= 0"
29
+ spec.add_development_dependency "pry", ">= 0"
30
+ spec.add_development_dependency "colorize", "~> 0.8.1"
31
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../config/environment'
4
+
5
+ CLI.new.call
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,7 @@
1
+ require 'pry'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'require_all'
5
+ require 'colorize'
6
+
7
+ require_all 'lib'
@@ -0,0 +1,25 @@
1
+ class AnimalFactory
2
+
3
+ def initialize(species, object)
4
+ if species == "Small"
5
+ @species = "small-furry"
6
+ else
7
+ @species = species.downcase
8
+ end
9
+ @animal_object = object
10
+
11
+ scrape_and_create_animals
12
+ end
13
+
14
+ def scrape_and_create_animals # Scrapes page ending with /@species and creates new objects based on the previously defined species object
15
+ hash_of_pets = Scraper.scrape_adoptable_pets(@species)
16
+ @animal_object.create_new(hash_of_pets)
17
+ end
18
+
19
+ def self.add_attributes_to_animals(number, animal_object)
20
+ pet = animal_object.all[number]
21
+ attributes = Scraper.scrape_pet_profile(pet.url)
22
+ pet.add_attributes(attributes)
23
+ end
24
+
25
+ end
data/lib/animals.rb ADDED
@@ -0,0 +1,33 @@
1
+ class Animals
2
+ attr_accessor :species, :name, :breed, :age, :url, :size, :color, :sex, :description
3
+
4
+ def initialize(attributes)
5
+ attributes.each {|k, v| self.send(("#{k}="), v)}
6
+ self.class.all << self unless self.class.all.any? {|pet| pet.url == self.url}
7
+ end
8
+
9
+ def self.create_new(pet_array)
10
+ pet_array.each do |pet_hash|
11
+ self.new(pet_hash)
12
+ end
13
+ end
14
+
15
+ def add_attributes(details_hash)
16
+ details_hash.each do |k, v|
17
+ self.send(("#{k}="), v)
18
+ end
19
+ check_attributes_for_nil
20
+ self
21
+ end
22
+
23
+ def check_attributes_for_nil
24
+ attributes = ["species", "name", "breed", "age", "url", "size", "color", "sex", "description"]
25
+ empty = [" ", "", nil]
26
+ attributes.each do |var|
27
+ if empty.any? { |e| self.send("#{var}") == e}
28
+ self.send(("#{var}="), "N/A")
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,8 @@
1
+ class Barnyard < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Birds < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Cats < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Dogs < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Equine < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Pigs < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,8 @@
1
+ class Rabbits < Animals
2
+ @@all = []
3
+
4
+ def self.all
5
+ @@all
6
+ end
7
+
8
+ end
@@ -0,0 +1,9 @@
1
+ class Small < Animals
2
+
3
+ @@all = []
4
+
5
+ def self.all
6
+ @@all
7
+ end
8
+
9
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,100 @@
1
+ class CLI
2
+ PETS = ["Dogs", "Cats", "Rabbits", "Birds", "Equine", "Pigs", "Barnyard", "Small"]
3
+
4
+ def call
5
+ puts "\nWELCOME TO BEST FRIEND FINDER!".light_blue
6
+ puts "--------------------------------"
7
+ start
8
+ end
9
+
10
+ def start
11
+ puts "What kind of friends would you like to find today? (Please enter a number)\n".cyan
12
+
13
+ PETS.each.with_index(1) do |animal, number|
14
+ puts "#{number}. #{animal}"
15
+ end
16
+
17
+ user_input = number_to_index(gets.chomp)
18
+
19
+ if !user_input.between?(0, PETS.size-1)
20
+ puts "\nI'm sorry, that was an incorrect entry. Please try again.\n".red
21
+ start
22
+ end
23
+
24
+ @animal_object = define_animal_object(user_input)
25
+ AnimalFactory.new(PETS[user_input], @animal_object)
26
+
27
+ display_all_animals
28
+ end
29
+
30
+ def display_all_animals
31
+ if @animal_object == Small
32
+ puts "\n\nAVAILABLE SMALL & FURRY ANIMALS FOR ADOPTION:".light_blue
33
+ else
34
+ puts "\n\nAVAILABLE #{@animal_object.to_s.upcase} FOR ADOPTION:".light_blue
35
+ end
36
+ puts "Name - Breed - Age".cyan
37
+ puts "-----------------------------"
38
+
39
+ all_pets = @animal_object.all
40
+ all_pets.each.with_index(1) {|pet, num| puts "#{num}. #{pet.name} - #{pet.breed} - #{pet.age}"}
41
+
42
+ puts "\nWhich pet would you like more information on? (Please enter a number)".cyan
43
+
44
+ animal_number = number_to_index(gets.chomp)
45
+
46
+ if animal_number < 0 || animal_number >= all_pets.size
47
+ puts "I'm sorry, that was an incorrect entry. Please try again.".red
48
+ display_all_animals
49
+ end
50
+
51
+ AnimalFactory.add_attributes_to_animals(animal_number, @animal_object)
52
+ display_details(animal_number)
53
+ end
54
+
55
+ def display_details(num)
56
+ pet = @animal_object.all[num]
57
+ if pet.species == "small-furry"
58
+ puts "\n#{pet.name.upcase} - Small & Furry".light_blue
59
+ else
60
+ puts "\n#{pet.name.upcase} - #{pet.species.capitalize}".light_blue
61
+ end
62
+ puts "------------------------------".cyan
63
+ puts "Breed:".green + " #{pet.breed}"
64
+ puts "Age:".green + " #{pet.age}"
65
+ puts "Size:".green + " #{pet.size}"
66
+ puts "Color:".green + " #{pet.color}"
67
+ puts "Sex:".green + " #{pet.sex}\n\n"
68
+ puts "#{pet.description}\n\n"
69
+ puts "For more info on how to adopt #{pet.name}, visit www.bestfriends.org#{pet.url}"
70
+
71
+ repeat?
72
+ end
73
+
74
+ def repeat?
75
+ puts "\n\nWould you like to search more adoptable pets? (Please enter a number)\n".cyan
76
+ puts "1. Yes, take me back to the list of available #{@animal_object.to_s.downcase}."
77
+ puts "2. Yes, take me back to the main menu."
78
+ puts "3. No, I'm done.\n\n"
79
+ user_input = gets.chomp
80
+
81
+ if user_input == "1"
82
+ display_all_animals
83
+ elsif user_input == "2"
84
+ start
85
+ elsif user_input == "3"
86
+ exit
87
+ else
88
+ puts "I'm sorry, I didn't understand that answer.".red
89
+ repeat?
90
+ end
91
+ end
92
+
93
+ def number_to_index(user_input)
94
+ user_input.to_i - 1
95
+ end
96
+
97
+ def define_animal_object(user_input)
98
+ Object.const_get("#{PETS[user_input]}")
99
+ end
100
+ end
data/lib/scraper.rb ADDED
@@ -0,0 +1,38 @@
1
+ class Scraper
2
+
3
+ def self.scrape_adoptable_pets(animal)
4
+ pets = []
5
+ doc = Nokogiri::HTML(open("http://bestfriends.org/adopt/adopt-our-sanctuary/#{animal}"))
6
+ doc.css("div.rg-animal").each do |pet|
7
+ pet_details = {}
8
+ pet_details[:species] = animal
9
+ pet_details[:name] = pet.css("span.animalName").text
10
+ pet_details[:breed] = pet.css("span.animalBreed").text
11
+ pet_details[:age] = pet.css("span.animalAge").text
12
+ pet_details[:url] = pet.css("a").attribute("href").value
13
+ pets << pet_details
14
+ end
15
+ pets
16
+ end
17
+
18
+ def self.scrape_pet_profile(url)
19
+ pet_profile_details = {}
20
+
21
+ pet_profile = "http://bestfriends.org" + url
22
+ doc = Nokogiri::HTML(open(pet_profile))
23
+
24
+ pet_items = doc.css("div.rescue-groups-pet-info-item")
25
+
26
+ pet_items.each do |attribute|
27
+ if attribute.css("span.gray").text == "Size:"
28
+ pet_profile_details[:size] = attribute.css("span.bold.black").text
29
+ elsif attribute.css("span.gray").text == "Color:"
30
+ pet_profile_details[:color] = attribute.css("span.bold.black").text
31
+ elsif attribute.css("span.gray").text == "Sex:"
32
+ pet_profile_details[:sex] = attribute.css("span.bold.black").text
33
+ end
34
+ end
35
+ pet_profile_details[:description] = doc.css("section.rescue-groups-pet-info-section p").text.gsub("\n ", "")
36
+ pet_profile_details
37
+ end
38
+ end
data/lib/version.rb ADDED
@@ -0,0 +1,3 @@
1
+ module BestFriendFinder
2
+ VERSION = "0.1.0"
3
+ end
data/spec.md ADDED
@@ -0,0 +1,17 @@
1
+ # Specifications for the CLI Assessment
2
+
3
+ Specs:
4
+ - [X] Have a CLI for interfacing with the application
5
+ --> My CLI successfully welcomes the user, allows the user to make decisions by entering in numbers (and informs the user
6
+ if that number is incorrect), view details requested by the user, and allows the user to return to the beginning of the
7
+ application, to the middle of the application, or exit the application.
8
+
9
+ - [X] Pull data from an external source
10
+ --> Data is being pulled from the Best Friends Animal Society website, specifically under their adoption page. It is scraping
11
+ both the data from the list of animals available for adoption, as well as each individual animal's page.
12
+
13
+ - [X] Implement both list and detail views
14
+ --> The user is first presented with a list of all available animals based on the type of animal that the user specifies
15
+ (dogs, cats, etc.) This first-level list presents all animals and their name, breed and age. The user can then drill-down
16
+ into more details of each animal by choosing the animal they are interested in. They are presented with a more detailed views
17
+ which includes the initial informationa about the animal, as well as attributes such as size, sex, color and description.
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: BestFriendFinder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - "'Alexis Dorn'"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: colorize
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.8.1
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.8.1
97
+ description: |-
98
+ CLI app that scrapes information and returns a list of animals available for adoption
99
+ and their details from the Best Friends Animal Society sanctuary in Utah. http://bestfriends.org/
100
+ email:
101
+ - "'alexisadorn@gmail.com'"
102
+ executables:
103
+ - bestfriendfinder
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - ".gitignore"
108
+ - Gemfile
109
+ - NOTES.md
110
+ - README.md
111
+ - Rakefile
112
+ - bestfriendfinder.gemspec
113
+ - bin/bestfriendfinder
114
+ - bin/setup
115
+ - config/environment.rb
116
+ - lib/animalfactory.rb
117
+ - lib/animals.rb
118
+ - lib/animals/barnyard.rb
119
+ - lib/animals/birds.rb
120
+ - lib/animals/cats.rb
121
+ - lib/animals/dogs.rb
122
+ - lib/animals/equine.rb
123
+ - lib/animals/pigs.rb
124
+ - lib/animals/rabbits.rb
125
+ - lib/animals/small.rb
126
+ - lib/cli.rb
127
+ - lib/scraper.rb
128
+ - lib/version.rb
129
+ - spec.md
130
+ homepage: https://github.com/alexisadorn/BestFriendFinder-cli-app
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.6.11
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: A list of animals available for adoption.
154
+ test_files: []