beer_list 1.1.0 → 2.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +7 -2
- data/beer_list.gemspec +1 -1
- data/lib/beer_list/cli.rb +6 -3
- data/lib/beer_list/establishments/acadia_cafe.rb +6 -1
- data/lib/beer_list/establishments/blue_door_pub.rb +6 -1
- data/lib/beer_list/establishments/blue_nile.rb +6 -1
- data/lib/beer_list/establishments/bulldog_lowertown.rb +6 -1
- data/lib/beer_list/establishments/bulldog_northeast.rb +6 -1
- data/lib/beer_list/establishments/bulldog_uptown.rb +6 -1
- data/lib/beer_list/establishments/busters_on28th.rb +6 -1
- data/lib/beer_list/establishments/edina_grill.rb +6 -1
- data/lib/beer_list/establishments/establishment.rb +3 -10
- data/lib/beer_list/establishments/ginger_hop.rb +6 -1
- data/lib/beer_list/establishments/groveland_tap.rb +6 -1
- data/lib/beer_list/establishments/happy_gnome.rb +5 -0
- data/lib/beer_list/establishments/icehouse.rb +43 -0
- data/lib/beer_list/establishments/longfellow_grill.rb +6 -1
- data/lib/beer_list/establishments/lowry_uptown.rb +6 -1
- data/lib/beer_list/establishments/mackenzie_pub.rb +6 -1
- data/lib/beer_list/establishments/macs_industrial.rb +6 -1
- data/lib/beer_list/establishments/mc_coys_mn.rb +5 -0
- data/lib/beer_list/establishments/muddy_pig.rb +6 -1
- data/lib/beer_list/establishments/muddy_waters.rb +6 -1
- data/lib/beer_list/establishments/new_bohemia.rb +6 -1
- data/lib/beer_list/establishments/red_cow.rb +31 -0
- data/lib/beer_list/establishments/stanleys_bar_room.rb +5 -0
- data/lib/beer_list/establishments/three_squares.rb +6 -1
- data/lib/beer_list/establishments/washington_square.rb +6 -1
- data/lib/beer_list/list.rb +8 -4
- data/lib/beer_list/listable.rb +8 -9
- data/lib/beer_list/scraper.rb +1 -1
- data/lib/beer_list.rb +15 -16
- data/lib/generators/establishment_generator.rb +1 -0
- data/lib/generators/templates/establishment.erb +6 -1
- data/spec/lib/beer_list/establishments/establishment_spec.rb +17 -7
- data/spec/lib/beer_list/list_spec.rb +8 -8
- data/spec/lib/beer_list_spec.rb +14 -22
- metadata +7 -5
data/README.md
CHANGED
@@ -88,7 +88,8 @@ will create the following code in path/to/establishments/applebirds.rb
|
|
88
88
|
module BeerList
|
89
89
|
module Establishments
|
90
90
|
class Applebirds < Establishment
|
91
|
-
URL
|
91
|
+
URL = 'http://applebirds.com/beers'
|
92
|
+
ADDRESS = nil
|
92
93
|
|
93
94
|
# Handles parsing and manipulating a Mechanize::Page object
|
94
95
|
# in order to scrape the contents of your beer list.
|
@@ -101,6 +102,10 @@ module BeerList
|
|
101
102
|
def url
|
102
103
|
URL
|
103
104
|
end
|
105
|
+
|
106
|
+
def address
|
107
|
+
ADDRESS
|
108
|
+
end
|
104
109
|
end
|
105
110
|
end
|
106
111
|
end
|
@@ -175,7 +180,7 @@ BeerList.send_lists
|
|
175
180
|
```
|
176
181
|
|
177
182
|
Both .send_list and .send_lists accept an optional URL as the last argument. If you don't pass one,
|
178
|
-
it will use the default in your configuration. If neither
|
183
|
+
it will use the default in your configuration. If neither exist, it will raise an error.
|
179
184
|
|
180
185
|
### Leads
|
181
186
|
|
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 = '
|
3
|
+
spec.version = '2.0.0.rc1'
|
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/lib/beer_list/cli.rb
CHANGED
@@ -12,6 +12,9 @@ module BeerList
|
|
12
12
|
option :selector,
|
13
13
|
aliases: '-s',
|
14
14
|
banner: 'Optional selector to use for scraping'
|
15
|
+
option :address,
|
16
|
+
aliases: '-a',
|
17
|
+
banner: 'The physical address of your establishment'
|
15
18
|
|
16
19
|
desc 'establish ESTABLISHMENT', 'Generate a subclass of BeerList::Establishments::Establishment in the given directory'
|
17
20
|
def establish(klass)
|
@@ -36,9 +39,9 @@ module BeerList
|
|
36
39
|
puts BeerList.lists_as_json
|
37
40
|
else
|
38
41
|
BeerList.lists.each do |list|
|
39
|
-
puts '*' * (list.
|
40
|
-
puts "**** #{list.
|
41
|
-
puts '*' * (list.
|
42
|
+
puts '*' * (list.listable_name.size + 10)
|
43
|
+
puts "**** #{list.listable_name} ****"
|
44
|
+
puts '*' * (list.listable_name.size + 10)
|
42
45
|
puts
|
43
46
|
puts list
|
44
47
|
puts
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class AcadiaCafe < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://acadiacafe.com/as_beer-menu-and-happy-hour-specials'
|
5
|
+
ADDRESS = '329 Cedar Ave, Minneapolis, MN 55454'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -13,6 +14,10 @@ module BeerList
|
|
13
14
|
URL
|
14
15
|
end
|
15
16
|
|
17
|
+
def address
|
18
|
+
ADDRESS
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
18
23
|
def base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class BlueDoorPub < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://thebdp.com/?page_id=159'
|
5
|
+
ADDRESS = '1811 Selby Ave, St Paul, MN 55104'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('div.two-columns li a').map(&:text)
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -2,7 +2,8 @@ module BeerList
|
|
2
2
|
module Establishments
|
3
3
|
class BlueNile < Establishment
|
4
4
|
RESTAURANT_NAME = 'Blue Nile'
|
5
|
-
URL
|
5
|
+
URL = 'http://www.bluenilempls.com/bar-b.html'
|
6
|
+
ADDRESS = '2027 E Franklin Ave, Minneapolis, MN 55404'
|
6
7
|
|
7
8
|
def get_list
|
8
9
|
base_list
|
@@ -13,6 +14,10 @@ module BeerList
|
|
13
14
|
URL
|
14
15
|
end
|
15
16
|
|
17
|
+
def address
|
18
|
+
ADDRESS
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
18
23
|
def headers
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class BulldogLowertown < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.thebulldoglowertown.com/beer/'
|
5
|
+
ADDRESS = '237 E 6th St, St Paul, MN 55101'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('ul.beerlist li').map(&:text)
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class BulldogNortheast < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.thebulldognortheast.com/beer/'
|
5
|
+
ADDRESS = '401 E Hennepin Ave, Minneapolis, MN 55414'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
list = page.search('p.copy_menu_item_desc').map(&:text)
|
@@ -12,6 +13,10 @@ module BeerList
|
|
12
13
|
def url
|
13
14
|
URL
|
14
15
|
end
|
16
|
+
|
17
|
+
def address
|
18
|
+
ADDRESS
|
19
|
+
end
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class BulldogUptown < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.thebulldoguptown.com/beer/'
|
5
|
+
ADDRESS = '2549 Lyndale Ave S, Minneapolis, MN 55405'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
list = page.search('span.menuTitle').map(&:text)
|
@@ -16,6 +17,10 @@ module BeerList
|
|
16
17
|
def url
|
17
18
|
URL
|
18
19
|
end
|
20
|
+
|
21
|
+
def address
|
22
|
+
ADDRESS
|
23
|
+
end
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class BustersOn28th < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://busterson28th.com/bottles/'
|
5
|
+
ADDRESS = '4204 S 28th Ave, Minneapolis, Minnesota 55406'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -15,6 +16,10 @@ module BeerList
|
|
15
16
|
URL
|
16
17
|
end
|
17
18
|
|
19
|
+
def address
|
20
|
+
ADDRESS
|
21
|
+
end
|
22
|
+
|
18
23
|
private
|
19
24
|
|
20
25
|
def base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class EdinaGrill < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.edinagrill.com/beer_taps.php'
|
5
|
+
ADDRESS = '5028 France Ave S, Edina, MN 55424'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('li span').map(&:text)
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -3,16 +3,9 @@ module BeerList
|
|
3
3
|
class Establishment
|
4
4
|
include BeerList::Listable
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def url
|
11
|
-
raise "#{__method__} is not implemented in #{self.class.name}"
|
12
|
-
end
|
13
|
-
|
14
|
-
def short_class_name
|
15
|
-
self.class.name.split('::').last
|
6
|
+
def name
|
7
|
+
class_name = self.class.name.split('::').last
|
8
|
+
class_name.split(/([A-Z]{1}[a-z]+)/).reject(&:empty?).join(' ')
|
16
9
|
end
|
17
10
|
end
|
18
11
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class GingerHop < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.gingerhop.com/beer'
|
5
|
+
ADDRESS = '201 E Hennepin Ave, Minneapolis, MN 55414'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('div.left-col h5').map(&:text)
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class GrovelandTap < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.grovelandtap.com/beer_taps.php'
|
5
|
+
ADDRESS = '1834 St Clair Ave, St Paul, MN 55105'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('p.MsoNormal').map(&:text)
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -3,6 +3,7 @@ module BeerList
|
|
3
3
|
class HappyGnome < Establishment
|
4
4
|
attr_accessor :url
|
5
5
|
|
6
|
+
ADDRESS = '498 Selby Ave, St Paul, MN 55102'
|
6
7
|
DRAFTS = 'http://thehappygnome.com/menus/drafts/'
|
7
8
|
BOTTLES = 'http://thehappygnome.com/menus/bottled-beers/'
|
8
9
|
|
@@ -15,6 +16,10 @@ module BeerList
|
|
15
16
|
get_bottle_list
|
16
17
|
end
|
17
18
|
|
19
|
+
def address
|
20
|
+
ADDRESS
|
21
|
+
end
|
22
|
+
|
18
23
|
private
|
19
24
|
|
20
25
|
def get_the_list
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module BeerList
|
2
|
+
module Establishments
|
3
|
+
class Icehouse < Establishment
|
4
|
+
URL = 'http://www.icehousempls.com/drinks/beer/'
|
5
|
+
ADDRESS = "2528 Nicollet Ave, Minneapolis, MN 55404"
|
6
|
+
|
7
|
+
def get_list
|
8
|
+
base_list
|
9
|
+
only_caps
|
10
|
+
reject_empty
|
11
|
+
capitalize
|
12
|
+
end
|
13
|
+
|
14
|
+
def url
|
15
|
+
URL
|
16
|
+
end
|
17
|
+
|
18
|
+
def address
|
19
|
+
ADDRESS
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def base_list
|
25
|
+
@icehouse = page.search('article#menu dd').map(&:text)
|
26
|
+
end
|
27
|
+
|
28
|
+
def only_caps
|
29
|
+
@icehouse = @icehouse.map { |b| b.match(/\A([0-9]+)?\s?([A-Z]+\s?)+/).to_s }
|
30
|
+
end
|
31
|
+
|
32
|
+
def reject_empty
|
33
|
+
@icehouse = @icehouse.reject { |b| b.empty? }
|
34
|
+
end
|
35
|
+
|
36
|
+
def capitalize
|
37
|
+
@icehouse.map do |b|
|
38
|
+
b.split(' ').map(&:capitalize).join(' ')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class LongfellowGrill < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.longfellowgrill.com/beer_taps.php'
|
5
|
+
ADDRESS = '2990 W River Pkwy, Minneapolis, MN 55406'
|
5
6
|
STATE_AND_PRICE_REGEX = /\s*(?:\([A-Z]*\))*\s*\**\s*\d+\.\d{2}$/
|
6
7
|
|
7
8
|
def get_list
|
@@ -14,6 +15,10 @@ module BeerList
|
|
14
15
|
URL
|
15
16
|
end
|
16
17
|
|
18
|
+
def address
|
19
|
+
ADDRESS
|
20
|
+
end
|
21
|
+
|
17
22
|
private
|
18
23
|
|
19
24
|
def get_base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class LowryUptown < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.thelowryuptown.com/drink'
|
5
|
+
ADDRESS = '2112 Hennepin Ave, Minneapolis, MN 55405'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -13,6 +14,10 @@ module BeerList
|
|
13
14
|
URL
|
14
15
|
end
|
15
16
|
|
17
|
+
def address
|
18
|
+
ADDRESS
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
18
23
|
def base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class MackenziePub < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://mackenziepub.com/drink/beer/'
|
5
|
+
ADDRESS = '918 Hennepin Ave, Minneapolis, MN 55403'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -12,6 +13,10 @@ module BeerList
|
|
12
13
|
URL
|
13
14
|
end
|
14
15
|
|
16
|
+
def address
|
17
|
+
ADDRESS
|
18
|
+
end
|
19
|
+
|
15
20
|
private
|
16
21
|
|
17
22
|
def base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class MacsIndustrial < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.macsindustrial.com/tap_page.php'
|
5
|
+
ADDRESS = '312 Central Ave SE, Minneapolis, MN 55414'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
build_list
|
@@ -11,6 +12,10 @@ module BeerList
|
|
11
12
|
URL
|
12
13
|
end
|
13
14
|
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
18
|
+
|
14
19
|
private
|
15
20
|
|
16
21
|
def build_list
|
@@ -3,6 +3,7 @@ module BeerList
|
|
3
3
|
class McCoysMN < Establishment
|
4
4
|
attr_accessor :url
|
5
5
|
|
6
|
+
ADDRESS = '3801 Grand Way, St Louis Park, MN 55416'
|
6
7
|
DRAFTS = 'http://mccoysmn.com/beer/'
|
7
8
|
BOTTLES = 'http://mccoysmn.com/beer/bottles'
|
8
9
|
|
@@ -16,6 +17,10 @@ module BeerList
|
|
16
17
|
get_bottle_list
|
17
18
|
end
|
18
19
|
|
20
|
+
def address
|
21
|
+
ADDRESS
|
22
|
+
end
|
23
|
+
|
19
24
|
private
|
20
25
|
|
21
26
|
def get_draft_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class MuddyPig < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://muddypig.com/beer/'
|
5
|
+
ADDRESS = '162 Dale St N, St Paul, MN 55102'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.search('p').last.text.split("\n")
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class MuddyWaters < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://muddywatersmpls.com/booze.html'
|
5
|
+
ADDRESS = '2933 Lyndale Ave S, Minneapolis, MN 55408'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
get_processed_list
|
@@ -11,6 +12,10 @@ module BeerList
|
|
11
12
|
URL
|
12
13
|
end
|
13
14
|
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
18
|
+
|
14
19
|
def get_processed_list
|
15
20
|
all = page.search('div.graphic_textbox_layout_style_default p').map(&:text)
|
16
21
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class NewBohemia < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.newbohemiausa.com/bier/'
|
5
|
+
ADDRESS = '233 E Hennepin Ave, Minneapolis, MN 55414'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -12,6 +13,10 @@ module BeerList
|
|
12
13
|
URL
|
13
14
|
end
|
14
15
|
|
16
|
+
def address
|
17
|
+
ADDRESS
|
18
|
+
end
|
19
|
+
|
15
20
|
private
|
16
21
|
|
17
22
|
def base_list
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module BeerList
|
2
|
+
module Establishments
|
3
|
+
class RedCow < Establishment
|
4
|
+
URL = 'http://redcowmn.com/beer'
|
5
|
+
ADDRESS = '3624 W 50th St, Minneapolis, MN 55410'
|
6
|
+
|
7
|
+
def get_list
|
8
|
+
base_list
|
9
|
+
match_before_paren
|
10
|
+
end
|
11
|
+
|
12
|
+
def url
|
13
|
+
URL
|
14
|
+
end
|
15
|
+
|
16
|
+
def address
|
17
|
+
ADDRESS
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def base_list
|
23
|
+
@red_cow = page.search('.sqs-block-content li').map(&:text)
|
24
|
+
end
|
25
|
+
|
26
|
+
def match_before_paren
|
27
|
+
@red_cow = @red_cow.map { |b| b.match(/\(/) ? $`.strip : b.strip }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,6 +2,7 @@ module BeerList
|
|
2
2
|
module Establishments
|
3
3
|
class StanleysBarRoom < Establishment
|
4
4
|
URL = 'http://www.stanleysbarroom.com/drinks/beer-list/'
|
5
|
+
ADDRESS = '2500 University Ave NE, Minneapolis, MN 55418'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -12,6 +13,10 @@ module BeerList
|
|
12
13
|
URL
|
13
14
|
end
|
14
15
|
|
16
|
+
def address
|
17
|
+
ADDRESS
|
18
|
+
end
|
19
|
+
|
15
20
|
private
|
16
21
|
|
17
22
|
def base_list
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class ThreeSquares < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.3squaresrestaurant.com/beer_taps.php'
|
5
|
+
ADDRESS = '12690 Arbor Lakes Pkwy N, Maple Grove, Minnesota 55369'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
page.at('ul').text.split("\r\n")
|
@@ -10,6 +11,10 @@ module BeerList
|
|
10
11
|
def url
|
11
12
|
URL
|
12
13
|
end
|
14
|
+
|
15
|
+
def address
|
16
|
+
ADDRESS
|
17
|
+
end
|
13
18
|
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class WashingtonSquare < Establishment
|
4
|
-
URL
|
4
|
+
URL = 'http://www.washingtonsquareonline.net/as_on-tap'
|
5
|
+
ADDRESS = '4736 Washington Ave, St Paul, MN 55110'
|
5
6
|
|
6
7
|
def get_list
|
7
8
|
base_list
|
@@ -13,6 +14,10 @@ module BeerList
|
|
13
14
|
URL
|
14
15
|
end
|
15
16
|
|
17
|
+
def address
|
18
|
+
ADDRESS
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
18
23
|
def base_list
|
data/lib/beer_list/list.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module BeerList
|
2
2
|
class List < Array
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :listable
|
4
4
|
|
5
5
|
def initialize(opts={})
|
6
|
-
ary
|
7
|
-
@
|
6
|
+
ary = opts[:array] || []
|
7
|
+
@listable = opts[:listable]
|
8
8
|
super ary.sort
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_hash
|
12
|
-
|
12
|
+
{ name: listable_name, address: listable.address, list: to_a }
|
13
13
|
end
|
14
14
|
|
15
15
|
alias :old_to_json :to_json
|
@@ -17,5 +17,9 @@ module BeerList
|
|
17
17
|
def to_json
|
18
18
|
to_hash.to_json
|
19
19
|
end
|
20
|
+
|
21
|
+
def listable_name
|
22
|
+
listable.name
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
data/lib/beer_list/listable.rb
CHANGED
@@ -2,17 +2,16 @@ module BeerList
|
|
2
2
|
module Listable
|
3
3
|
attr_accessor :page
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def short_class_name
|
11
|
-
raise NotImplementedError
|
5
|
+
# Templates
|
6
|
+
[:get_list, :url, :address, :name].each do |m|
|
7
|
+
define_method m do
|
8
|
+
nil
|
9
|
+
end
|
12
10
|
end
|
13
11
|
|
14
|
-
def
|
15
|
-
|
12
|
+
def list
|
13
|
+
visit_page unless page
|
14
|
+
@list ||= BeerList::List.new listable: self, array: get_list || []
|
16
15
|
end
|
17
16
|
|
18
17
|
private
|
data/lib/beer_list/scraper.rb
CHANGED
@@ -21,7 +21,7 @@ module BeerList
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def send_json(url, json)
|
24
|
-
url = "http://#{url}" unless url.start_with? 'http
|
24
|
+
url = "http://#{url}" unless url.start_with? 'http'
|
25
25
|
agent.post url, "{\"beer_list\": #{json}}", 'Content-Type' => 'application/json'
|
26
26
|
true
|
27
27
|
end
|
data/lib/beer_list.rb
CHANGED
@@ -32,15 +32,6 @@ module BeerList
|
|
32
32
|
settings.establishments_dir
|
33
33
|
end
|
34
34
|
|
35
|
-
### DEPRECATED ###
|
36
|
-
def establishments_dir=(directory)
|
37
|
-
puts <<-dep
|
38
|
-
BeerList.establishments_dir= is deprecated and will be removed.
|
39
|
-
Please use BeerList.configure instead
|
40
|
-
dep
|
41
|
-
settings.establishments_dir = directory
|
42
|
-
end
|
43
|
-
|
44
35
|
def establishments
|
45
36
|
return [] if @establishments.nil?
|
46
37
|
@establishments.dup
|
@@ -67,20 +58,18 @@ module BeerList
|
|
67
58
|
end
|
68
59
|
|
69
60
|
def lists_as_hash
|
70
|
-
lists.
|
71
|
-
hsh.merge! list.to_hash
|
72
|
-
end
|
61
|
+
lists.map &:to_hash
|
73
62
|
end
|
74
63
|
|
75
64
|
def lists_as_json
|
76
|
-
|
65
|
+
lists.map &:to_json
|
77
66
|
end
|
78
67
|
|
79
68
|
def send_list(list, url=nil)
|
80
69
|
url ||= default_url
|
81
70
|
raise NoUrlError unless url
|
82
71
|
raise NotAListError unless list.is_a? BeerList::List
|
83
|
-
scraper.send_json url, list.to_json
|
72
|
+
scraper.send_json url, [list.to_json]
|
84
73
|
end
|
85
74
|
|
86
75
|
def send_lists(url=nil)
|
@@ -104,8 +93,8 @@ module BeerList
|
|
104
93
|
end
|
105
94
|
|
106
95
|
def establishments_eq_lists?
|
107
|
-
list_names = @lists.map
|
108
|
-
establishments.map(&:
|
96
|
+
list_names = @lists.map { |list| list.listable_name }
|
97
|
+
establishments.map(&:name).all? { |name| list_names.include? name }
|
109
98
|
end
|
110
99
|
|
111
100
|
def method_missing(method, *args, &block)
|
@@ -117,6 +106,16 @@ module BeerList
|
|
117
106
|
end
|
118
107
|
end
|
119
108
|
|
109
|
+
def respond_to_missing?(method, include_private=false)
|
110
|
+
class_name = method.to_s.split('_').map(&:capitalize).join
|
111
|
+
!!get_class_with_namespace(class_name) || super
|
112
|
+
end if RUBY_VERSION >= '1.9'
|
113
|
+
|
114
|
+
def respond_to?(method, include_private=false)
|
115
|
+
class_name = method.to_s.split('_').map(&:capitalize).join
|
116
|
+
!!get_class_with_namespace(class_name) || super
|
117
|
+
end if RUBY_VERSION < '1.9'
|
118
|
+
|
120
119
|
def is_establishment?(class_name)
|
121
120
|
BeerList::Establishments.constants.include? class_name.to_sym
|
122
121
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module BeerList
|
2
2
|
module Establishments
|
3
3
|
class <%= @klass %> < Establishment
|
4
|
-
URL
|
4
|
+
URL = '<%= @url %>'
|
5
|
+
ADDRESS = <%= @address.inspect %>
|
5
6
|
|
6
7
|
# Handles parsing and manipulating a Mechanize::Page object
|
7
8
|
# in order to scrape the contents of your beer list.
|
@@ -14,6 +15,10 @@ module BeerList
|
|
14
15
|
def url
|
15
16
|
URL
|
16
17
|
end
|
18
|
+
|
19
|
+
def address
|
20
|
+
ADDRESS
|
21
|
+
end
|
17
22
|
end
|
18
23
|
end
|
19
24
|
end
|
@@ -4,7 +4,7 @@ module BeerList
|
|
4
4
|
module Establishments
|
5
5
|
|
6
6
|
describe Establishment do
|
7
|
-
let(:establishment){ BeerList::Establishments::
|
7
|
+
let(:establishment){ BeerList::Establishments::Establishment.new }
|
8
8
|
|
9
9
|
describe '#list' do
|
10
10
|
it 'returns a BeerList::List' do
|
@@ -16,21 +16,31 @@ module BeerList
|
|
16
16
|
|
17
17
|
describe '#get_list' do
|
18
18
|
context 'when it is not implemented in a subclass' do
|
19
|
-
it '
|
20
|
-
|
19
|
+
it 'returns nil' do
|
20
|
+
establishment.get_list.should be_nil
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe '#url' do
|
26
|
-
|
27
|
-
|
26
|
+
context 'when it is not implemented in a subclass' do
|
27
|
+
it 'returns nil' do
|
28
|
+
establishment.url.should be_nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#address' do
|
34
|
+
context 'when it is not implemented in a subclass' do
|
35
|
+
it 'returns nil' do
|
36
|
+
establishment.address.should be_nil
|
37
|
+
end
|
28
38
|
end
|
29
39
|
end
|
30
40
|
|
31
|
-
describe '#
|
41
|
+
describe '#name' do
|
32
42
|
it 'returns a usable name' do
|
33
|
-
establishment.
|
43
|
+
establishment.name.should == 'Establishment'
|
34
44
|
end
|
35
45
|
end
|
36
46
|
end
|
@@ -2,29 +2,29 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module BeerList
|
4
4
|
describe List do
|
5
|
-
let(:
|
6
|
-
let(:list){ List.new array: [],
|
5
|
+
let(:listable){ stub('listable', name: 'Applebirds', address: '123 Fake St') }
|
6
|
+
let(:list){ List.new array: ['item'], listable: listable }
|
7
7
|
|
8
|
-
it 'knows its
|
9
|
-
list.
|
8
|
+
it 'knows its listable' do
|
9
|
+
list.listable.should == listable
|
10
10
|
end
|
11
11
|
|
12
12
|
describe '#to_hash' do
|
13
|
-
it 'hashes its
|
14
|
-
expected = {
|
13
|
+
it 'hashes its listable info with its list' do
|
14
|
+
expected = { name: 'Applebirds', address: '123 Fake St', list: ['item']}
|
15
15
|
list.to_hash.should == expected
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe '#to_json' do
|
20
20
|
it 'returns the list as json' do
|
21
|
-
expected = "{\"
|
21
|
+
expected = "{\"name\":\"Applebirds\",\"address\":\"123 Fake St\",\"list\":[\"item\"]}"
|
22
22
|
list.to_json.should == expected
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
26
|
context 'when array is nil (the establishment has yet to implement #get_list)' do
|
27
|
-
let(:list){ List.new array: nil,
|
27
|
+
let(:list){ List.new array: nil, listable: listable }
|
28
28
|
|
29
29
|
it { list.should be_empty }
|
30
30
|
end
|
data/spec/lib/beer_list_spec.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe BeerList do
|
4
4
|
let(:establishment){ BeerList::Establishments::ThreeSquares.new }
|
5
|
+
let(:scraper){ stub }
|
5
6
|
|
6
7
|
describe '.configure' do
|
7
8
|
before do
|
@@ -21,11 +22,6 @@ describe BeerList do
|
|
21
22
|
end
|
22
23
|
|
23
24
|
describe '.establishments' do
|
24
|
-
|
25
|
-
after(:each) do
|
26
|
-
BeerList.clear_establishments!
|
27
|
-
end
|
28
|
-
|
29
25
|
it 'returns an array' do
|
30
26
|
BeerList.establishments.should be_an_instance_of Array
|
31
27
|
end
|
@@ -91,17 +87,13 @@ describe BeerList do
|
|
91
87
|
end
|
92
88
|
|
93
89
|
context 'when establishments are registered' do
|
94
|
-
|
95
|
-
BeerList.add_establishments establishment
|
96
|
-
end
|
97
|
-
|
98
|
-
after(:all) do
|
99
|
-
BeerList.clear_establishments!
|
100
|
-
end
|
90
|
+
let(:list){ BeerList::List.new listable: establishment, array: [] }
|
101
91
|
|
102
92
|
before do
|
103
|
-
|
104
|
-
|
93
|
+
BeerList.stub(:establishments){ [establishment] }
|
94
|
+
BeerList.stub(:update_necessary?){ true }
|
95
|
+
BeerList.stub(:scraper){ scraper }
|
96
|
+
scraper.should_receive(:beer_list).with(establishment){ list }
|
105
97
|
end
|
106
98
|
|
107
99
|
it 'returns an array of lists' do
|
@@ -109,28 +101,28 @@ describe BeerList do
|
|
109
101
|
end
|
110
102
|
|
111
103
|
it 'contains lists for the registered establishments' do
|
112
|
-
BeerList.lists.first.
|
104
|
+
BeerList.lists.first.listable.should == establishment
|
113
105
|
end
|
114
106
|
|
115
107
|
describe '.lists_as_hash' do
|
116
|
-
it 'returns
|
117
|
-
BeerList.lists_as_hash.
|
108
|
+
it 'returns an array of hashes' do
|
109
|
+
BeerList.lists_as_hash.all? { |l| l.is_a? Hash }.should be_true
|
118
110
|
end
|
119
111
|
end
|
120
112
|
|
121
113
|
describe '.lists_as_json' do
|
122
|
-
it 'returns JSON' do
|
123
|
-
expect { JSON.parse(
|
114
|
+
it 'returns an array of valid JSON' do
|
115
|
+
expect { BeerList.lists_as_json.each { |j| JSON.parse(j) } }.to_not raise_error
|
124
116
|
end
|
125
117
|
end
|
126
118
|
end
|
127
119
|
end
|
128
120
|
|
129
121
|
describe 'sending lists' do
|
130
|
-
let(:scraper){ stub }
|
131
122
|
let(:url){ 'http://omg.io' }
|
132
123
|
let(:json){ "{\"foo\":\"bar\"}" }
|
133
124
|
let(:list){ BeerList::List.new }
|
125
|
+
let(:expected){ [url, [json]] }
|
134
126
|
|
135
127
|
before do
|
136
128
|
BeerList.stub(:scraper).and_return scraper
|
@@ -139,7 +131,7 @@ describe BeerList do
|
|
139
131
|
|
140
132
|
describe '.send_list' do
|
141
133
|
it 'delegates to the scraper' do
|
142
|
-
scraper.should_receive(:send_json).with
|
134
|
+
scraper.should_receive(:send_json).with *expected
|
143
135
|
BeerList.send_list list, url
|
144
136
|
end
|
145
137
|
end
|
@@ -151,7 +143,7 @@ describe BeerList do
|
|
151
143
|
end
|
152
144
|
|
153
145
|
it 'delegates to the scraper' do
|
154
|
-
scraper.should_receive(:send_json).with
|
146
|
+
scraper.should_receive(:send_json).with *expected
|
155
147
|
BeerList.send_lists url
|
156
148
|
end
|
157
149
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beer_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Dan Olson
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mechanize
|
@@ -106,6 +106,7 @@ files:
|
|
106
106
|
- lib/beer_list/establishments/ginger_hop.rb
|
107
107
|
- lib/beer_list/establishments/groveland_tap.rb
|
108
108
|
- lib/beer_list/establishments/happy_gnome.rb
|
109
|
+
- lib/beer_list/establishments/icehouse.rb
|
109
110
|
- lib/beer_list/establishments/longfellow_grill.rb
|
110
111
|
- lib/beer_list/establishments/lowry_uptown.rb
|
111
112
|
- lib/beer_list/establishments/mackenzie_pub.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- lib/beer_list/establishments/muddy_pig.rb
|
115
116
|
- lib/beer_list/establishments/muddy_waters.rb
|
116
117
|
- lib/beer_list/establishments/new_bohemia.rb
|
118
|
+
- lib/beer_list/establishments/red_cow.rb
|
117
119
|
- lib/beer_list/establishments/stanleys_bar_room.rb
|
118
120
|
- lib/beer_list/establishments/three_squares.rb
|
119
121
|
- lib/beer_list/establishments/washington_square.rb
|
@@ -147,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
150
|
none: false
|
149
151
|
requirements:
|
150
|
-
- - ! '
|
152
|
+
- - ! '>'
|
151
153
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
154
|
+
version: 1.3.1
|
153
155
|
requirements: []
|
154
156
|
rubyforge_project:
|
155
157
|
rubygems_version: 1.8.24
|