events_nearby 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2c75f592a260fb0503a0145f323e688d9d954bf0
4
- data.tar.gz: ad8be8978d4d039f4348317149f704e8aab55b49
2
+ SHA256:
3
+ metadata.gz: 88852aa7f3a5d1fde260b076cd68223d642f9165d6a03352dae0cd26a653f459
4
+ data.tar.gz: b5e140a36cea1ed0f14ccc02535996a49f196d5df6ea3f77d919398245cab708
5
5
  SHA512:
6
- metadata.gz: a22619193d34593bbe2b0ef5a0078b1d4c2d115f4a907c10ba08818ae3b76c735f76d967437c2caacbbb525ca397699a2687d75f23fd676fbdc87b1644342a76
7
- data.tar.gz: e035f08703ad39d4e98de22c57b725ebf4ef2039b73e97eec580fa6b2e0dc9349b884bdb44cfe68f73e48f5c26e76e65ce43fafbd151421d3b97ef0cddb53773
6
+ metadata.gz: 1ddead6ae46f39a03981776c13ac30edcfe535f085e4c30ed76c1fe7e32318a05ad36e78914b125d5c8d05e3dc9eb029d783aeb098e6479fe0ae3bb0fb9a78d3
7
+ data.tar.gz: 966564917b92816e98b9127bf535b5fb25a1454cea2e16c1efd7b0cffa70b99ad7f67b21f1a624daec25f9723034fdea85f70c48c64b704591e285eec4e4ba5d
data/README.md CHANGED
@@ -2,7 +2,15 @@
2
2
 
3
3
  Welcome to 'Events Nearby'! In this directory, you'll find a CLI Ruby Gem. 'Events Nearby' lets you enter any location to retrieve a list of events that are near that location. Displayed will be the name of the events, when they are taking place, where exactly they are, and how much they cost. You can then choose one of the listed events to see details about that event and even open it in your browser.
4
4
 
5
- ## Installation
5
+ ## Installation/Running the application
6
+
7
+ ### Option 1: Cloning the repository and running it directly
8
+ * Clone this repository: `git clone https://github.com/amelieoller/events-nearby-cli-gem.git`
9
+ * `cd` into the cloned directory
10
+ * Run `bundle install` in your terminal
11
+ * Then run the application with `bin/events_nearby`
12
+
13
+ ### Option 2: Add the gem to your gemfile
6
14
 
7
15
  Add this line to your application's Gemfile:
8
16
 
@@ -10,13 +18,11 @@ Add this line to your application's Gemfile:
10
18
  gem 'events_nearby'
11
19
  ```
12
20
 
13
- And then execute:
14
-
15
- $ bundle
16
-
17
- Or install it yourself as:
21
+ And then run:
22
+ $ bundle
18
23
 
19
- $ gem install events_nearby
24
+ ### Option 3: Install it yourself
25
+ $ gem install events_nearby
20
26
 
21
27
  ## Usage
22
28
 
@@ -27,9 +33,9 @@ Or install it yourself as:
27
33
 
28
34
  ## Contributing
29
35
 
30
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/events_nearby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+ Bug reports and pull requests are welcome on GitHub at https://github.com/amelieoller/events-nearby-cli-gem. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
31
37
 
32
38
 
33
39
  ## License
34
40
 
35
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/bin/console CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # require "bundler/setup"
4
4
  # require "events_nearby"
5
- require_relative '../config/environment'
5
+ require_relative '../lib/environment'
6
6
 
7
7
 
8
8
  # You can add fixtures and/or initialization code here to make experimenting
data/bin/events_nearby CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # Load files
4
- require_relative '../config/environment'
3
+ # Load our environment
4
+ require_relative '../lib/environment'
5
5
 
6
- EventsNearby::CLI.new.call
6
+ # Create new CLI instance and call choose_city to start app
7
+ EventsNearby::CLI.new.choose_city
@@ -12,12 +12,20 @@ Gem::Specification.new do |spec|
12
12
  spec.summary = %q{Events Nearby will show you events nearby based on the location you enter.}
13
13
  spec.license = "MIT"
14
14
 
15
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
16
+ # delete this section to allow pushing this gem to any host.
17
+ # if spec.respond_to?(:metadata)
18
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
19
+ # else
20
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ # end
22
+
15
23
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
24
  spec.bindir = "exe"
17
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
26
  spec.require_paths = ["lib"]
19
27
 
20
- spec.add_development_dependency "bundler", "~> 1.11"
28
+ spec.add_development_dependency "bundler", "~> 2.0"
21
29
  spec.add_development_dependency "rake", "~> 10.0"
22
30
  spec.add_dependency "nokogiri", "~> 1.8"
23
31
  end
@@ -0,0 +1,14 @@
1
+ # Module EventsNearby
2
+ module EventsNearby
3
+ end
4
+
5
+ # Load gems
6
+ require 'require_all'
7
+ require 'nokogiri'
8
+ require 'open-uri'
9
+ require 'pry'
10
+ require 'launchy'
11
+ require 'colorize'
12
+
13
+ # Load local files
14
+ require_all './lib'
@@ -0,0 +1,44 @@
1
+ # City model
2
+ class EventsNearby::City
3
+ attr_accessor :name, :state, :events
4
+ @@all = []
5
+
6
+ def initialize(name, state)
7
+ @name = name
8
+ @state = state
9
+ @events = []
10
+ @@all << self
11
+ end
12
+
13
+ # Adds new event to city array
14
+ def add_event(event)
15
+ self.events << event unless self.events.include?(event)
16
+ end
17
+
18
+ def self.all
19
+ @@all
20
+ end
21
+
22
+ # Find city if city and state combination exist already
23
+ def self.find_by(name, state)
24
+ self.all.detect{|city| city.name == name && city.state == state}
25
+ end
26
+
27
+ # Parse user city input and return name of city and state
28
+ def self.parse_city_input(city_input)
29
+ data = city_input.split(/[\s,]+/)
30
+
31
+ if city_input.include?(",")
32
+ state = data.last.gsub(/[^0-9A-Za-z]/, '').upcase
33
+ city_array = data.first data.size - 1
34
+ else
35
+ city_array = data
36
+ end
37
+
38
+ name = city_array.collect do |item|
39
+ item.gsub(/[^0-9A-Za-z]/, '').capitalize
40
+ end.join(" ")
41
+
42
+ {name: name, state: state}
43
+ end
44
+ end
@@ -1,81 +1,83 @@
1
1
  # CLI Controller
2
-
3
2
  class EventsNearby::CLI
3
+ # Ask user for city input, find or create new city and set @city instance variable
4
+ def choose_city
5
+ puts "What city would you like to see events nearby? (e.g. 'San Francisco, CA')"
6
+
7
+ input = gets.strip.downcase
8
+ parsed_input = EventsNearby::City.parse_city_input(input)
9
+ name = parsed_input[:name]
10
+ state = parsed_input[:state]
11
+
12
+ if EventsNearby::City.find_by(name, state)
13
+ @city = EventsNearby::City.find_by(name, state)
14
+ list_events
15
+ else
16
+ @city = EventsNearby::Scraper.new.scrape_events(name, state)
17
+ @city == false ? choose_city : list_events
18
+ end
19
+ end
20
+
21
+ def list_events
22
+ separator
23
+ puts "These are the upcoming events for #{@city.name.bold}:".red
24
+ separator
4
25
 
5
- def call
6
- choose_city
7
- end
26
+ @city.events.each_with_index do |event, i|
27
+ puts "#{i+1}. #{event.format_event}"
28
+ end
8
29
 
9
- def choose_city
10
- puts "What city would you like to see events nearby? (e.g. 'San Francisco, CA')"
11
- input = gets.strip.downcase
12
- EventsNearby::Events.destroy_all
13
- EventsNearby::Events.today(input)
14
- input == "exit" ? goodbye : list_events(input)
15
- end
30
+ menu
31
+ end
16
32
 
17
- def list_events(city)
18
- puts "These are the upcoming events for #{city}:"
19
-
20
- EventsNearby::Events.all.each_with_index do |event, i|
21
- puts "#{i+1}. #{event.formatted_event}"
22
- end
23
- menu
24
- end
33
+ def menu
34
+ separator
35
+ puts "What would you like to do next?"
36
+ puts "- Pick an event by entering a number".bold
37
+ puts "- Type " + "'city'".bold + " to choose a new city"
38
+ puts "- Type " + "'list'".bold + " to list all events again"
39
+ puts "- Type " + "'exit'".bold + " to exit"
40
+ separator
25
41
 
26
- def menu
27
- puts "Which event would you like to know more about? Enter a number, 'start' to start over, or 'exit'."
28
- input = gets.strip
29
- if input.to_i.between?(1, EventsNearby::Events.all.size)
30
- event = EventsNearby::Events.all[input.to_i - 1]
31
- show_details(event)
32
- else
33
- decision(input)
34
- end
35
- end
42
+ input = gets.strip
36
43
 
37
- def show_details(event)
38
- puts ""
39
- puts "--- #{event.formatted_event} ---"
40
- if event.content != ""
41
- puts event.content
42
- puts ""
43
- puts "Would you like to open this event in your browser? Enter 'yes' to open, 'menu' to pick another event, 'start' to start over, or 'exit'."
44
- input = gets.strip
45
- open_in_browser_decision(input, event)
46
- else
47
- puts "There seems to be no description of this event. Would you like to open this event in your browser? Enter 'yes' to open, 'menu' to pick another event, 'start' to start over, or 'exit'."
48
- input = gets.strip
49
- open_in_browser_decision(input, event)
50
- end
51
- end
44
+ if input == "exit"
45
+ puts "See you later!"
46
+ elsif input == "list"
47
+ list_events
48
+ elsif input == "city"
49
+ choose_city
50
+ elsif input.to_i.between?(1, @city.events.size)
51
+ event = @city.events[input.to_i - 1]
52
+ EventsNearby::Scraper.new.scrape_event(event) unless event.content
53
+ show_details(event)
54
+ else
55
+ puts "Not sure what you mean..."
56
+ menu
57
+ end
58
+ end
52
59
 
53
- def open_in_browser_decision(input, event)
54
- if ['y', 'yes', 'open'].include?(input.downcase)
55
- event.open_in_browser
56
- puts ""
57
- menu
58
- else
59
- decision(input)
60
- end
61
- end
60
+ def show_details(event)
61
+ puts ""
62
+ puts "--- #{event.format_event} ---".green
63
+ puts event.content
64
+ puts ""
65
+ separator
66
+ puts "Would you like to open this event in your browser? #{'yes'.bold} or #{'no'.bold}?"
67
+ separator
62
68
 
63
- def decision(input)
64
- case input
65
- when "exit"
66
- goodbye
67
- when "menu"
68
- menu
69
- when "start"
70
- choose_city
71
- else
72
- puts "Not sure what you mean. Enter 'menu' to pick another event, 'start' to start over, or 'exit'."
73
- decision(gets.strip)
74
- end
75
- end
69
+ input = gets.strip.downcase
76
70
 
77
- def goodbye
78
- puts "See you later!"
79
- end
71
+ if ["y", "yes", "open"].include?(input)
72
+ event.open_in_browser
73
+ puts ""
74
+ menu
75
+ else
76
+ menu
77
+ end
78
+ end
80
79
 
81
- end
80
+ def separator
81
+ puts "--------------**********--------------".red
82
+ end
83
+ end
@@ -0,0 +1,26 @@
1
+ # Event model
2
+ class EventsNearby::Event
3
+ attr_accessor :name, :date, :price, :url, :city, :content
4
+ @@all = []
5
+
6
+ def initialize(name, date, price, url, city)
7
+ @name = name
8
+ @date = date
9
+ @price = price
10
+ @url = url
11
+ @city = city
12
+ @@all << self
13
+ end
14
+
15
+ def self.all
16
+ @@all
17
+ end
18
+
19
+ def format_event
20
+ "#{self.name} | #{self.date} | #{self.price}"
21
+ end
22
+
23
+ def open_in_browser
24
+ Launchy.open(url)
25
+ end
26
+ end
@@ -1,47 +1,57 @@
1
- require_relative '../../config/environment'
2
-
3
1
  class EventsNearby::Scraper
4
-
5
- def initialize(url = nil)
6
- @url = url
7
- end
8
-
9
- def scrape_event
10
- @doc = Nokogiri::HTML(open(@url))
11
- @doc.search(".js-xd-read-more-contents p").text.strip[0..300].gsub(/\s\w+\s*$/,'...')
12
- end
13
-
14
- def scrape_events(location)
15
- url = include_location_in_url(location)
16
- @doc = Nokogiri::HTML(open("#{url}"))
17
- @doc.search("div.js-event-list-container div.list-card-v2").each do |event_item|
18
- event = EventsNearby::Events.new
19
-
20
- event.name = event_item.search(".list-card__title").first.text.gsub("\n", "").strip
21
- event.date = event_item.search(".list-card__date").first.text.gsub("\n", "").strip.split.join(" ")
22
- event.price = event_item.search(".list-card__label").first.text.strip
23
- event.url = event_item.attr("data-share-url").strip
24
-
25
- event.save
26
- end
27
- end
28
-
29
- def include_location_in_url(location)
30
- data = location.split(/[\s,]+/)
31
-
32
- if location.include?(",")
33
- state = data.last.gsub(/[^0-9A-Za-z]/, '')
34
- city_array = data.first data.size - 1
35
- else
36
- city_array = data
37
- end
38
-
39
- city = city_array.collect do |item|
40
- item.gsub(/[^0-9A-Za-z]/, '')
41
- end.join("-")
42
-
43
- url = "https://www.eventbrite.com/d/#{state}--#{city}/events/"
44
- url
45
- end
46
-
47
- end
2
+ def scrape_events(name, state)
3
+ url = "https://www.eventbrite.com/d/#{state}--#{name.split(/[\s,]+/).join("-")}/all-events/"
4
+
5
+ # Check if url is valid or returns error. If valid, scrape city, if not return false
6
+ doc = nokogiri_error_handling(url)
7
+ return false if doc == false
8
+
9
+ city = EventsNearby::City.new(name, state)
10
+
11
+ doc.search(".search-event-card-wrapper").each do |event_data|
12
+ name = event_data.search(".card-text--truncated__three").text.strip
13
+ url = event_data.search(".eds-media-card-content__action-link").attr('href').value
14
+ date = event_data.search(".eds-text-bs--fixed")[0].text
15
+ price = event_data.search(".eds-text-bs--fixed")[2].text
16
+
17
+ event = EventsNearby::Event.new(name, date, price, url, city)
18
+ city.add_event(event)
19
+ end
20
+
21
+ city
22
+ end
23
+
24
+ def scrape_event(event)
25
+ doc = nokogiri_error_handling(event.url)
26
+ event.content = doc.search(".js-xd-read-more-contents p").text.strip[0..300].gsub(/\s\w+\s*$/,'...')
27
+ end
28
+
29
+ def nokogiri_error_handling(url)
30
+ openuri_params = {
31
+ # set timeout durations for HTTP connection
32
+ # default values for open_timeout and read_timeout is 60 seconds
33
+ :open_timeout => 1,
34
+ :read_timeout => 1,
35
+ }
36
+
37
+ attempt_count = 0
38
+ max_attempts = 3
39
+
40
+ begin
41
+ attempt_count += 1
42
+ content = open(url, openuri_params).read
43
+ rescue OpenURI::HTTPError => e
44
+ # it's 404, etc. - puts out error & do nothing
45
+ puts "We encountered a 404 error, please try again."
46
+ false
47
+ rescue SocketError, Net::ReadTimeout => e
48
+ # server can't be reached or doesn't send any respones
49
+ puts "error: #{e}"
50
+ sleep 3
51
+ retry if attempt_count < max_attempts
52
+ else
53
+ # connection successful, content is fetched, parse content with Nokogiri
54
+ Nokogiri::HTML(content)
55
+ end
56
+ end
57
+ end
@@ -1,3 +1,3 @@
1
1
  module EventsNearby
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: events_nearby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - amelieoller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-09-04 00:00:00.000000000 Z
11
+ date: 2019-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
19
+ version: '2.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.11'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -68,11 +68,11 @@ files:
68
68
  - bin/console
69
69
  - bin/events_nearby
70
70
  - bin/setup
71
- - config/environment.rb
72
71
  - events_nearby.gemspec
73
- - lib/events_nearby.rb
72
+ - lib/environment.rb
73
+ - lib/events_nearby/city.rb
74
74
  - lib/events_nearby/cli.rb
75
- - lib/events_nearby/events.rb
75
+ - lib/events_nearby/event.rb
76
76
  - lib/events_nearby/scraper.rb
77
77
  - lib/events_nearby/version.rb
78
78
  - spec.md
@@ -95,8 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubyforge_project:
99
- rubygems_version: 2.5.1
98
+ rubygems_version: 3.0.2
100
99
  signing_key:
101
100
  specification_version: 4
102
101
  summary: Events Nearby will show you events nearby based on the location you enter.
@@ -1,8 +0,0 @@
1
- # Load gems and modules
2
- require 'require_all'
3
- require 'nokogiri'
4
- require 'open-uri'
5
- # require 'pry'
6
-
7
- # Load files
8
- require_all './lib'
data/lib/events_nearby.rb DELETED
@@ -1,4 +0,0 @@
1
- require_relative '../config/environment'
2
-
3
- module EventsNearby
4
- end
@@ -1,35 +0,0 @@
1
- class EventsNearby::Events
2
-
3
- attr_accessor :name, :date, :price, :url, :content
4
-
5
- @@all = []
6
-
7
- def save
8
- @@all << self
9
- end
10
-
11
- def self.all
12
- @@all
13
- end
14
-
15
- def self.destroy_all
16
- self.all.clear
17
- end
18
-
19
- def self.today(input)
20
- EventsNearby::Scraper.new.scrape_events(input)
21
- end
22
-
23
- def content
24
- @content ||= EventsNearby::Scraper.new(url).scrape_event
25
- end
26
-
27
- def formatted_event
28
- "#{self.name} | #{self.date} | #{self.price}"
29
- end
30
-
31
- def open_in_browser
32
- system("xdg-open '#{url}'")
33
- end
34
-
35
- end