adventures 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 042f4df94ca439e1ac993be3e2dee062adf55aa1
4
+ data.tar.gz: 74d152f0021cf89d687ed8af39c96eb66609c0bf
5
+ SHA512:
6
+ metadata.gz: 79d24b374f542e033a4c04e63ae6c7b311402068a62fd601e27663d0c625c47ddd57a40a1474bd55113dd55955329e13d2d01276dfebf8f8db957489ffd0903d
7
+ data.tar.gz: 176b887d2072097c5ef2db446cb34a97df9a6bf2ff6f8422d7e6ed0b0fd9e15caa963dcdbe8fa1fd8680380744160ec040d55a8e8b041df612ff856b3f1a7ce3
Binary file
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in adventure.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Aellon
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # adventures
2
+
3
+ This Ruby gem provides a CLI to find outdoor adventures in any state based on an activity, using The Outbound Collective website.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'Adventures'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install adventures
20
+
21
+ ## Usage
22
+
23
+ After installing the gem, type `adventures` and follow the prompts.
24
+
25
+ ## Development
26
+
27
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. 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/aellonk/adventures.
34
+
35
+
36
+ ## License
37
+
38
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
39
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'adventures/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "adventures"
8
+ spec.version = Adventures::VERSION
9
+ spec.authors = ["Aellon Krider"]
10
+ spec.email = ["aellonkrider@gmail.com"]
11
+
12
+ spec.summary = %q{"CLI gem project to find outdoor adventures nearby"}
13
+ spec.homepage = "https://github.com/aellonk/adventures"
14
+ spec.license = "MIT"
15
+
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "bin"
21
+ spec.executables = ['adventures']
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.13"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "pry"
28
+ spec.add_dependency "nokogiri"
29
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/adventures'
4
+
5
+ Adventures::CLI.new.call
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "adventures"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
12
+
13
+ # require "irb"
14
+ # IRB.start
@@ -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,10 @@
1
+ require 'open-uri'
2
+ require 'pry'
3
+ require 'nokogiri'
4
+
5
+ require_relative "./adventures/version"
6
+ require_relative "./adventures/scraper"
7
+ require_relative "./adventures/adventure"
8
+ require_relative "./adventures/cli"
9
+
10
+
Binary file
@@ -0,0 +1,68 @@
1
+ class Adventures::Adventure
2
+
3
+ attr_accessor :title, :location, :url, :suggested_activities, :skill_level, :season, :trail_type, :rt_distance, :elevation_gain, :summary, :description
4
+
5
+ @@all = []
6
+
7
+ def self.new_from_scrape(a)
8
+ self.new(
9
+ a.css("div.info h3.title").text,
10
+ a.css("div.info p.location").text.strip,
11
+ "https://www.theoutbound.com/#{a.css("a").attribute("href").text}"
12
+ )
13
+ end
14
+
15
+ def initialize(title = nil, location = nil, url = nil)
16
+ @title = title
17
+ @location = location
18
+ @url = url
19
+ @@all << self
20
+ end
21
+
22
+ def self.all
23
+ @@all
24
+ end
25
+
26
+ def self.find(id)
27
+ self.all[id -1]
28
+ end
29
+
30
+ def doc
31
+ @doc ||= Nokogiri::HTML(open(self.url))
32
+ end
33
+
34
+ def suggested_activities
35
+ @suggested_activities ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[1]/p[2]").text
36
+ end
37
+
38
+ def skill_level
39
+ @skill_level ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[2]/p[2]").text
40
+ end
41
+
42
+ def season
43
+ @season ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[3]/p[2]").text
44
+ end
45
+
46
+ def trail_type
47
+ @trail_type ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[4]/p[2]").text
48
+ end
49
+
50
+ def rt_distance
51
+ @rt_distance ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[5]/p[2]").text
52
+ end
53
+
54
+ def elevation_gain
55
+ @elevation_gain ||= doc.xpath("//div[@class='keylineb m2y']/ul/li[6]/p[2]").text
56
+ end
57
+
58
+ def summary
59
+ @summary ||= doc.xpath("//div[@class='section summary blurb pad2b']/p").text
60
+ end
61
+
62
+ def description
63
+ @description ||= doc.xpath("//span[@class='adventure-description']/p").collect { |para|
64
+ para.text
65
+ }.join("\n\n")
66
+ end
67
+
68
+ end
@@ -0,0 +1,116 @@
1
+ class Adventures::CLI
2
+
3
+ @@ACTIVITIES = [["Backpacking", "Bodysurfing", "Camping", "Canoeing"], ["Cycling", "Diving", "Fishing", "Fitness"], ["Hiking", "Kayaking", "Kiteboarding", "Mountain Biking"], ["Photography", "Rafting", "Rock Climbing", "Running"], ["Skiing", "Snowboarding", "Snowshoeing", "Stand Up Paddle"], ["Surfing", "Swimming", "Yoga"]]
4
+
5
+ def call
6
+ puts "Welcome, let's find your next adventure!"
7
+ puts "Type 'exit' to quit at any time."
8
+ puts "Which state would you like to see adventures for? Enter the full name."
9
+ state = gets.strip.downcase.gsub(' ', '-')
10
+ puts "\n"
11
+ if state == "exit"
12
+ exit
13
+ end
14
+ start(state)
15
+ end
16
+
17
+ def start(state)
18
+ puts "What kind of activity are you in the mood for? Enter the number."
19
+ puts "\n"
20
+ list_activities
21
+ puts "\n"
22
+ input = gets.strip.to_i
23
+ puts "\n"
24
+ if input == "exit"
25
+ exit
26
+ elsif input.between?(1, 23)
27
+ activity = @@ACTIVITIES.flatten[input - 1].downcase
28
+ Adventures::Scraper.new.gather_adventures(activity, state)
29
+ if Adventures::Adventure.all.empty?
30
+ puts "There are no adventures for that activity. Please try another activity."
31
+ start(state)
32
+ end
33
+ puts "The following adventures are recommended for #{activity}:"
34
+ puts "\n"
35
+ list_adventures
36
+ puts "\n"
37
+ continue
38
+ end
39
+
40
+ end
41
+
42
+ def continue
43
+ puts "Which adventure would you like to learn more about? Enter the number."
44
+ choice = gets.strip.to_i
45
+ puts "\n"
46
+ count = Adventures::Adventure.all.size
47
+ case choice
48
+ when 1..count
49
+ puts "Here are the details:"
50
+ puts "\n"
51
+ adventure = Adventures::Adventure.find(choice)
52
+ list_details(adventure)
53
+ puts "\n"
54
+ puts "Would you like to see another adventure? Enter Y or N"
55
+ input = gets.strip.downcase
56
+ if input == "y"
57
+ puts "\n"
58
+ list_adventures
59
+ puts "\n"
60
+ continue
61
+ else
62
+ puts "\n"
63
+ puts "Thanks, and have a good adventure!"
64
+ exit
65
+ end
66
+ else
67
+ puts "Please enter a valid number."
68
+ continue
69
+ end
70
+ end
71
+
72
+
73
+ def list_activities
74
+ activities = @@ACTIVITIES[0].collect.with_index {|activity, index|
75
+ "#{index +1}. #{activity} " }
76
+ puts activities.join
77
+
78
+ activities = @@ACTIVITIES[1].collect.with_index(4) {|activity, index|
79
+ "#{index +1}. #{activity} " }
80
+ puts activities.join
81
+
82
+ activities = @@ACTIVITIES[2].collect.with_index(8) {|activity, index|
83
+ "#{index +1}. #{activity} " }
84
+ puts activities.join
85
+
86
+ activities = @@ACTIVITIES[3].collect.with_index(12) {|activity, index|
87
+ "#{index +1}. #{activity} " }
88
+ puts activities.join
89
+
90
+ activities = @@ACTIVITIES[4].collect.with_index(16) {|activity, index|
91
+ "#{index +1}. #{activity} " }
92
+
93
+ activities = @@ACTIVITIES[5].collect.with_index(20) {|activity, index|
94
+ "#{index +1}. #{activity} " }
95
+ puts activities.join
96
+ end
97
+
98
+ def list_adventures
99
+ Adventures::Adventure.all.each_with_index do |a, index|
100
+ puts "#{index + 1}. #{a.title} (#{a.location})"
101
+ end
102
+ end
103
+
104
+ def list_details(adventure)
105
+ puts <<~DOC
106
+ Activities: #{adventure.suggested_activities}
107
+ Skill Level: #{adventure.skill_level}
108
+ Season: #{adventure.season}
109
+ Trail Type: #{adventure.trail_type}
110
+ RT Distance:#{adventure.rt_distance}
111
+ Elevation Gain: #{adventure.elevation_gain}
112
+ \n #{adventure.summary}
113
+ \n #{adventure.description}
114
+ DOC
115
+ end
116
+ end
@@ -0,0 +1,21 @@
1
+ class Adventures::Scraper
2
+ def get_page(activity, state)
3
+ doc = Nokogiri::HTML(open("https://www.theoutbound.com/#{state}/#{activity_url_creator(activity)}"))
4
+ end
5
+
6
+ def activity_url_creator(activity)
7
+ activity.gsub(' ', '-')
8
+ end
9
+
10
+ def scrape_adventure(activity, state)
11
+ self.get_page(activity, state).css("div.adventure-card--image")
12
+ end
13
+
14
+ def gather_adventures(activity, state)
15
+ scrape_adventure(activity, state).each do |a|
16
+ Adventures::Adventure.new_from_scrape(a)
17
+ end
18
+ end
19
+
20
+
21
+ end
@@ -0,0 +1,3 @@
1
+ module Adventures
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,63 @@
1
+ A command line interface for finding adventures nearby
2
+
3
+ user types adventures
4
+
5
+ Prompt:
6
+ Which state would you like to see adventures for?
7
+
8
+ get input, modify input to include dashes as spaces
9
+
10
+ What kind of adventure are you in the mood for?
11
+
12
+ (List activities)
13
+
14
+ 1. Backpacking 2. Bodysurfing 3. Camping Canoeing Cycling Diving Fishing Fitness Hiking Kayaking Kiteboarding Mountain Biking Photography Rafting Rock Climbing Running Skiing Snowboarding Snowshoeing Stand Up Paddle Surfing Swimming Volunteering Yoga
15
+
16
+ show a list of 10 adventures with selected activities nearby
17
+
18
+ 1. Hike the Devil's Path
19
+ 2. Hike to Sugarloaf Mountain
20
+ 3. Hike to Chittenango Falls
21
+ 4. Hike Storm King Mountain
22
+ etc.
23
+
24
+ Prompt user: Which adventure would you like to learn more about? Enter the number.
25
+
26
+ 4
27
+
28
+ Activities:
29
+ Photography, Hiking
30
+ Skill Level:
31
+ Beginner
32
+ Season:
33
+ Year Round
34
+ RT Distance:
35
+ 2.7 Miles
36
+ Elevation Gain:
37
+ 900 Feet
38
+
39
+ Hike to multiple ledges where you'll have 360 degree views of the Hudson Valley.
40
+ This is an easy, yet very rewarding hike with a lot of viewpoints on the way up. Technically you scale up two mountains, Butter Hill and Storm King, but most people just describe it as Storm King Mountain. This is a great hike for families with younger kids, those who don't have much time but want to get a hike in, and those looking for great foliage shots of the Hudson Valley.
41
+
42
+ The parking lot is right off of Rt. 9w and I mean right off it. After parking, locate the historical sign and then proceed to the left of it finding the Orange Trail (starts right by the far side of the parking lot). The trail start moderately steep but provides some fun small scrambling sections. Once up, you will see the ruins of a small building with only the stone pillars left. Walk through the pillars and then you will proceed downward, still on the Orange Trail. Now you will scale up Butter Hill, which in my opinion has the better views on this hike.
43
+
44
+ After the steep upward section you are immediately rewarded with ledges to walk out onto for photos. I also encourage you to explore off the trail, there are some great areas where the angles are better for those photographers out there (watch your footing around the ledges). Be on the look out for some hawks that like to float through the valley.
45
+
46
+ Once ready, pick up the Orange Trail again and proceed on until the trail ends at a junction. VERY IMPORTANT at the end of the Orange Trail turn right (the trail to the right is narrow and doesn't look like it is a trail) taking the Yellow Trail from now on. Continue on this trail, following it all the way to the top of Storm King. There will be trails that intersect on the way up but just follow the Yellow/Light Blue markers.
47
+
48
+ At the main overlook of Storm King you get a great view to the north and on clear days you can see the Catskill Mountains. As you begin back down the Yellow/Light Blue Trail there are more ledges to your left you can shoot off the trail to. There are some great spots to set up a hammock and look out over the valley. On your way down look out for the White Trail. You will be jumping on this and taking it all the way back to the parking lot.
49
+
50
+ Trail Markers Breakdown: Orange to Yellow to Yellow/Light Blue to White
51
+
52
+ PACK LIST
53
+
54
+ Hiking boots or trail shoes
55
+ Backpack with 10 essentials
56
+ Water and snacks (or lunch)
57
+ Camera
58
+ Hammock
59
+
60
+ Would you like to see the Google map of the starting point? (y/n)
61
+
62
+ If yes launch browser with map
63
+ If no, would you like to pick another adventure? Type 'list' to show the list of adventures you selected from, or 'start' to start over with a new activity
data/spec.md ADDED
@@ -0,0 +1,11 @@
1
+ # Specifications for the CLI Assessment
2
+
3
+ Specs:
4
+ - [x] Have a CLI for interfacing with the application
5
+ - The bin/adventures file calls upon the CLI in lib/adventures/cli.rb
6
+ - [x] Pull data from an external source
7
+ - Scrapes adventures from outbound.com with nokogiri in lib/adventures/scraper.rb and adventure.rb
8
+ - [x] Implement both list and detail views
9
+ - List views include the methods list_activities and list_adventures in cli.rb
10
+ - Detail view is in the list_details method in cli.rb
11
+
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: adventures
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Aellon Krider
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-12 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.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
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: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
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: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - aellonkrider@gmail.com
86
+ executables:
87
+ - adventures
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".DS_Store"
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - Rakefile
96
+ - adventures.gemspec
97
+ - bin/adventures
98
+ - bin/console
99
+ - bin/setup
100
+ - lib/adventures.rb
101
+ - lib/adventures/.DS_Store
102
+ - lib/adventures/adventure.rb
103
+ - lib/adventures/cli.rb
104
+ - lib/adventures/scraper.rb
105
+ - lib/adventures/version.rb
106
+ - notes.md
107
+ - spec.md
108
+ homepage: https://github.com/aellonk/adventures
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.5.1
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: '"CLI gem project to find outdoor adventures nearby"'
132
+ test_files: []