beer_list 0.0.2 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- beer_list (0.0.1)
4
+ beer_list (0.1.2)
5
5
  mechanize (= 2.6.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -10,6 +10,7 @@ or in your gemfile:
10
10
 
11
11
  `gem 'beer_list'`
12
12
 
13
+ then require the gem:
13
14
 
14
15
  `require 'beer_list'`
15
16
 
@@ -41,7 +42,8 @@ BeerList.add_establishments(three_squares, muddy_waters)
41
42
  # See your registered establishments
42
43
  BeerList.establishments
43
44
 
44
- # Array of BeerList::List objects
45
+ # Get the beer lists at your registered establishments.
46
+ # as an array of BeerList::List objects
45
47
  BeerList.lists
46
48
 
47
49
  # As a hash
@@ -56,21 +58,27 @@ The establishments don't have to be re-scraped each time the list is requested.
56
58
 
57
59
  ### Extending BeerList with More Establishments
58
60
 
59
- BeerList ships with a limited number of establishments, but it's easy to write your own.
60
- Your establishment class must inherit from BeerList::Establishments::Establishment,
61
- and provide two instance methods: `get_list` and `url`. `url` should be the url of the beer list on your establishment's website. `get_list` should handle parsing and
62
- manipulating a Mechanize::Page object in order to scrape the contents of your beer list.
61
+ BeerList ships with a limited number of establishments, but also includes an executable
62
+ to easily create your own.
63
63
 
64
64
  For example:
65
65
 
66
+ `beer_list establish Applebirds -u http://applebirds.com/beers -d path/to/establishments`
67
+
68
+ will create the following code in path/to/establishments/applebirds.rb
69
+
66
70
  ```
67
71
  module BeerList
68
72
  module Establishments
69
- class Applebirds
73
+ class Applebirds < Establishment
70
74
  URL = 'http://applebirds.com/beers'
71
75
 
76
+ # Handles parsing and manipulating a Mechanize::Page object
77
+ # in order to scrape the contents of your beer list.
78
+ #
79
+ # Uncomment and implement to your liking.
72
80
  def get_list
73
- page.search('p.beer').map(&:text)
81
+ # page.search('.selector').map(&:text)
74
82
  end
75
83
 
76
84
  def url
@@ -79,6 +87,38 @@ module BeerList
79
87
  end
80
88
  end
81
89
  end
90
+
91
+ ```
92
+
93
+ For all options you can pass to beer_list establish, run:
94
+
95
+ `beer_list --help`
96
+
97
+ ### Using Your Generated Establishments
98
+
99
+ So you've written some pretty bad-ass scrapers now, and you're ready to actually
100
+ use the fruit of your labor in a real application. You'll need to tell BeerList
101
+ about the generated files so that it can require them. If you're using Rails, add
102
+ the following code in an initializer:
103
+
104
+ `BeerList.establishments_dir = File.join(Rails.root, 'path/to/establishments')`
105
+
106
+ When using Rails, you'll need to register your establishments with BeerList.
107
+ Unfortunately, you can't call them directly (I'm working on it):
108
+
82
109
  ```
110
+ BeerList.add_establishment(BeerList::Establishments::Applebirds.new)
111
+
112
+ # fetch all your lists, including the one at Applebirds
113
+ BeerList.lists
114
+
115
+ # Unsupported in Rails (for now)
116
+ BeerList.applebirds
117
+
118
+ ```
119
+
120
+ See [Getting A List](https://github.com/DanOlson/beer_list#getting-a-list) for more details.
121
+
122
+ AND...
83
123
 
84
124
  Checkout [This link](http://mechanize.rubyforge.org/) for more on Mechanize
data/beer_list.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = 'beer_list'
3
- spec.version = '0.0.2'
3
+ spec.version = '0.1.2'
4
4
  spec.authors = ['Dan Olson']
5
5
  spec.email = ['olson_dan@yahoo.com']
6
6
  spec.description = 'A utility for retrieving the beer list from various establishments'
data/bin/beer_list ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ bin_file = File.realpath(__FILE__)
4
+ $:.unshift File.expand_path('../../lib', bin_file)
5
+
6
+ require 'beer_list'
7
+
8
+ BeerList::CLI.start ARGV
@@ -0,0 +1,65 @@
1
+ require 'optparse'
2
+
3
+ module BeerList
4
+ class CLI
5
+ COMMANDS = %w(establish)
6
+
7
+ class << self
8
+ def start(args)
9
+ options = parse ARGV
10
+
11
+ msg = ARGV[0]
12
+ abort unsupported_command unless COMMANDS.include? msg
13
+
14
+ new(options).public_send msg
15
+ end
16
+
17
+ def parse(args)
18
+ options = {}
19
+
20
+ opts = OptionParser.new do |opts|
21
+ opts.banner = "Usage: beer_list establish [options]"
22
+
23
+ opts.on("-u", "--url [URL]", "url of your establishment's beer list") do |url|
24
+ options[:url] = url
25
+ end
26
+
27
+ opts.on("-s", "--selector [SELECTOR]", "selector to use for scraping") do |s|
28
+ options[:selector] = s
29
+ end
30
+
31
+ opts.on("-d", "--directory DIR", "the directory in which BeerList will put your establishments") do |dir|
32
+ options[:dir] = dir
33
+ end
34
+ end
35
+
36
+ opts.parse! args
37
+ options
38
+ end
39
+
40
+ def unsupported_command
41
+ <<-WARN
42
+ Command: not supported. Must be one of the following:
43
+ #{COMMANDS.join(', ')}
44
+ WARN
45
+ end
46
+
47
+ def no_establishments_dir
48
+ <<-WARN
49
+ You must supply an establishments directory with -d or --directory
50
+ WARN
51
+ end
52
+ end
53
+
54
+ def initialize(args)
55
+ @args = args
56
+ end
57
+
58
+ def establish(klass=ARGV[1])
59
+ abort self.class.no_establishments_dir unless @args[:dir]
60
+ # Support underscore and camelcase
61
+ klass = klass.split('_').map(&:capitalize).join if klass.match(/_/)
62
+ BeerList::EstablishmentGenerator.new(klass, @args)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,15 @@
1
+ module BeerList
2
+ module Establishments
3
+ class BulldogLowertown < Establishment
4
+ URL = 'http://www.thebulldoglowertown.com/beer/'
5
+
6
+ def get_list
7
+ page.search('ul.beerlist li').map(&:text)
8
+ end
9
+
10
+ def url
11
+ URL
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module BeerList
2
+ module Establishments
3
+ class BulldogNortheast < Establishment
4
+ URL = 'http://www.thebulldognortheast.com/beer/'
5
+
6
+ def get_list
7
+ list = page.search('p.copy_menu_item_desc').map(&:text)
8
+ list.shift 2 # shift off Rotating Cask and Beer Flights
9
+ list
10
+ end
11
+
12
+ def url
13
+ URL
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module BeerList
2
+ module Establishments
3
+ class BulldogUptown < Establishment
4
+ URL = 'http://www.thebulldoguptown.com/beer/'
5
+
6
+ def get_list
7
+ list = page.search('span.menuTitle').map(&:text)
8
+ list = process_list list
9
+ end
10
+
11
+ def process_list(list)
12
+ list.pop 5
13
+ list.map{ |e| e.split(' (').first }
14
+ end
15
+
16
+ def url
17
+ URL
18
+ end
19
+ end
20
+ end
21
+ end
@@ -3,10 +3,15 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  module BeerList
4
4
  module Establishments
5
5
  require 'establishments/establishment'
6
- require 'establishments/three_squares'
7
- require 'establishments/groveland_tap'
8
- require 'establishments/edina_grill'
9
- require 'establishments/longfellow_grill'
10
- require 'establishments/muddy_waters'
6
+
7
+ Dir[File.dirname(__FILE__) + '/establishments/*.rb'].each do |f|
8
+ require f.split('.rb').first
9
+ end
10
+
11
+ if BeerList.establishments_dir
12
+ Dir[File.dirname(BeerList.establishments_dir) + '/*.rb'].each do |f|
13
+ require f.split('.rb').first
14
+ end
15
+ end
11
16
  end
12
17
  end
@@ -4,7 +4,7 @@ module BeerList
4
4
 
5
5
  def initialize(ary, establishment)
6
6
  @establishment = establishment
7
- super ary
7
+ super ary.sort
8
8
  end
9
9
 
10
10
  def to_hash
data/lib/beer_list.rb CHANGED
@@ -3,12 +3,23 @@ require 'json'
3
3
 
4
4
  module BeerList
5
5
  require 'beer_list/scraper'
6
- require 'beer_list/establishments'
7
6
  require 'beer_list/list'
8
7
  require 'beer_list/exceptions'
8
+ require 'beer_list/cli'
9
+ require 'generators/establishment_generator'
10
+ require 'ext/string'
11
+ autoload :Establishments, 'beer_list/establishments'
9
12
 
10
13
  class << self
11
14
 
15
+ def establishments_dir
16
+ @establishments_dir
17
+ end
18
+
19
+ def establishments_dir=(directory)
20
+ @establishments_dir = directory
21
+ end
22
+
12
23
  def establishments
13
24
  return [] if @establishments.nil?
14
25
  @establishments.dup
@@ -64,6 +75,7 @@ module BeerList
64
75
  end
65
76
 
66
77
  def method_missing(method, *args, &block)
78
+ super if defined? Rails
67
79
  class_name = method.to_s.split('_').map(&:capitalize).join
68
80
  begin
69
81
  klass = ['BeerList', 'Establishments', class_name].compact.inject(Object){ |o, name| o.const_get(name) }
data/lib/ext/string.rb ADDED
@@ -0,0 +1,9 @@
1
+ class String
2
+ def underscore
3
+ self.gsub(/::/, '/').
4
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
5
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
6
+ tr("-", "_").
7
+ downcase
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ require 'erb'
2
+
3
+ module BeerList
4
+ class EstablishmentGenerator
5
+
6
+ DEFAULT_URL = 'http://yourestablishment.com/path/to/the/beer_list'
7
+ TEMPLATE_FILE = File.expand_path('../templates/establishment.erb', __FILE__)
8
+ ESTABLISHMENTS_DIR = File.expand_path('../../beer_list/establishments', __FILE__)
9
+
10
+ def initialize(klass, args={})
11
+ @klass = klass
12
+ @url = args[:url] || DEFAULT_URL
13
+ @selector = args[:selector] || '.selector'
14
+ @directory = args[:dir] || ESTABLISHMENTS_DIR
15
+ write_file
16
+ end
17
+
18
+ private
19
+
20
+ def write_file
21
+ File.open(filepath, 'w+') do |f|
22
+ f << template.result(binding)
23
+ end
24
+ end
25
+
26
+ def template
27
+ ERB.new File.open(TEMPLATE_FILE).read, nil, '-'
28
+ end
29
+
30
+ def filepath
31
+ File.join @directory, "#{@klass.underscore}.rb"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module BeerList
2
+ module Establishments
3
+ class <%= @klass %> < Establishment
4
+ URL = '<%= @url %>'
5
+
6
+ # Handles parsing and manipulating a Mechanize::Page object
7
+ # in order to scrape the contents of your beer list.
8
+ #
9
+ # Uncomment and implement to your liking.
10
+ def get_list
11
+ # page.search('<%= @selector %>').map(&:text)
12
+ end
13
+
14
+ def url
15
+ URL
16
+ end
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beer_list
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-06 00:00:00.000000000 Z
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
@@ -62,7 +62,8 @@ dependencies:
62
62
  description: A utility for retrieving the beer list from various establishments
63
63
  email:
64
64
  - olson_dan@yahoo.com
65
- executables: []
65
+ executables:
66
+ - beer_list
66
67
  extensions: []
67
68
  extra_rdoc_files: []
68
69
  files:
@@ -73,8 +74,13 @@ files:
73
74
  - LICENSE.txt
74
75
  - README.md
75
76
  - beer_list.gemspec
77
+ - bin/beer_list
76
78
  - lib/beer_list.rb
79
+ - lib/beer_list/cli.rb
77
80
  - lib/beer_list/establishments.rb
81
+ - lib/beer_list/establishments/bulldog_lowertown.rb
82
+ - lib/beer_list/establishments/bulldog_northeast.rb
83
+ - lib/beer_list/establishments/bulldog_uptown.rb
78
84
  - lib/beer_list/establishments/edina_grill.rb
79
85
  - lib/beer_list/establishments/establishment.rb
80
86
  - lib/beer_list/establishments/groveland_tap.rb
@@ -84,6 +90,9 @@ files:
84
90
  - lib/beer_list/exceptions.rb
85
91
  - lib/beer_list/list.rb
86
92
  - lib/beer_list/scraper.rb
93
+ - lib/ext/string.rb
94
+ - lib/generators/establishment_generator.rb
95
+ - lib/generators/templates/establishment.erb
87
96
  - spec/lib/beer_list/establishments/establishment_spec.rb
88
97
  - spec/lib/beer_list/list_spec.rb
89
98
  - spec/lib/beer_list_spec.rb