beerdb-models 0.10.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.
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+
3
+ module BeerDb
4
+
5
+ ## todo: "old" classic reader - rename to FileReader ?? why? why not?
6
+
7
+ class Reader < ReaderBase
8
+
9
+ def initialize( include_path, opts = {} )
10
+ @include_path = include_path
11
+ end
12
+
13
+ def create_fixture_reader( name )
14
+ path = "#{@include_path}/#{name}.txt"
15
+
16
+ logger.info "parsing data (setup) '#{name}' (#{path})..."
17
+
18
+ FixtureReader.from_file( path )
19
+ end
20
+
21
+ def create_beers_reader( name, more_attribs={} )
22
+ real_name = name_to_real_name( name )
23
+
24
+ path = "#{@include_path}/#{real_name}.txt"
25
+
26
+ logger.info "parsing data (beers) '#{name}' (#{path})..."
27
+
28
+ ValuesReader.from_file( path, more_attribs )
29
+ ## ValuesReaderV2.new( name, @include_path, more_attribs )
30
+ end
31
+
32
+ def create_breweries_reader( name, more_attribs={} )
33
+ real_name = name_to_real_name( name )
34
+
35
+ path = "#{@include_path}/#{real_name}.txt"
36
+
37
+ logger.info "parsing data (breweries) '#{name}' (#{path})..."
38
+
39
+ ValuesReader.from_file( path, more_attribs )
40
+ ## ValuesReaderV2.new( name, @include_path, more_attribs )
41
+ end
42
+
43
+ private
44
+
45
+ def name_to_real_name( name )
46
+ # map name to real_name path
47
+ # name might include !/ for virtual path (gets cut off)
48
+ # e.g. at-austria!/w-wien/beers becomse w-wien/beers
49
+ pos = name.index( '!/')
50
+ if pos.nil?
51
+ name # not found; real path is the same as name
52
+ else
53
+ # cut off everything until !/ e.g.
54
+ # at-austria!/w-wien/beers becomes
55
+ # w-wien/beers
56
+ name[ (pos+2)..-1 ]
57
+ end
58
+ end
59
+
60
+ end # class Reader
61
+ end # module BeerDb
62
+
@@ -0,0 +1,112 @@
1
+ # encoding: UTF-8
2
+
3
+ module BeerDb
4
+
5
+
6
+ class ZipReader < ReaderBase
7
+
8
+ def initialize( name, include_path, opts = {} )
9
+
10
+ ## todo/fix: make include_path an opts (included in opts?) - why? why not??
11
+
12
+ path = "#{include_path}/#{name}.zip"
13
+ ## todo: check if zip exists
14
+
15
+ @zip_file = Zip::File.open( path ) ## NOTE: do NOT create if file is missing; let it crash
16
+
17
+ ### allow prefix (path) in name
18
+ ### e.g. assume all files relative to setup manifest
19
+ ## e.g. at-austria-master/setups/all.txt or
20
+ ## be-belgium-master/setups/all.txt
21
+ ## for
22
+ ## setups/all.txt
23
+ ###
24
+ ## will get (re)set w/ fixture/setup reader
25
+ ##
26
+ ## todo/fix: change/rename to @relative_path ?? - why? why not?
27
+ @zip_prefix = ''
28
+ end
29
+
30
+
31
+ def close
32
+ ## todo/check: add a close method - why? why not ???
33
+ @zip_file.close
34
+ end
35
+
36
+
37
+ def create_fixture_reader( name )
38
+ ## e.g. pass in => setups/all or setups/test etc. e.g. w/o .txt extension
39
+ query = "**/#{name}.txt"
40
+
41
+ ## note: returns an array of Zip::Entry
42
+ candidates = @zip_file.glob( query )
43
+ pp candidates
44
+
45
+ ## use first candidates entry as match
46
+ ## todo/fix: issue warning if more than one entries/matches!!
47
+
48
+ ## get fullpath e.g. at-austria-master/setups/all.txt
49
+ path = candidates[0].name
50
+ logger.debug " zip entry path >>#{path}<<"
51
+
52
+ ## cut-off at-austria-master/ NOTE: includes trailing slash (if present)
53
+ ## logger.debug " path.size #{path.size} >>#{path}<<"
54
+ ## logger.debug " name.size #{name.size+4} >>#{name}<<"
55
+
56
+ ## note: add +4 for extension (.txt)
57
+ @zip_prefix = path[ 0...(path.size-(name.size+4)) ]
58
+ logger.debug " zip entry prefix >>#{@zip_prefix}<<"
59
+
60
+ logger.info "parsing data in zip '#{name}' (#{path})..."
61
+
62
+ FixtureReader.from_zip( @zip_file, path )
63
+ end
64
+
65
+
66
+ def create_beers_reader( name, more_attribs={} )
67
+ path = name_to_zip_entry_path( name )
68
+
69
+ logger.debug "parsing data (beers) in zip '#{name}' (#{path})..."
70
+
71
+ ValuesReader.from_zip( @zip_file, path, more_attribs )
72
+ end
73
+
74
+ def create_breweries_reader( name, more_attribs={} )
75
+ path = name_to_zip_entry_path( name )
76
+
77
+ logger.debug "parsing data (breweries) in zip '#{name}' (#{path})..."
78
+
79
+ ValuesReader.from_zip( @zip_file, path, more_attribs )
80
+ end
81
+
82
+ private
83
+
84
+ def path_to_real_path( path )
85
+ # map name to name_real_path
86
+ # name might include !/ for virtual path (gets cut off)
87
+ # e.g. at-austria!/w-wien/beers becomse w-wien/beers
88
+ pos = path.index( '!/')
89
+ if pos.nil?
90
+ path # not found; real path is the same as name
91
+ else
92
+ # cut off everything until !/ e.g.
93
+ # at-austria!/w-wien/beers becomes
94
+ # w-wien/beers
95
+ path[ (pos+2)..-1 ]
96
+ end
97
+ end
98
+
99
+ def name_to_zip_entry_path( name )
100
+ path = "#{name}.txt"
101
+
102
+ real_path = path_to_real_path( path )
103
+
104
+ # NOTE: add possible zip entry prefix path
105
+ # (if present includes trailing slash e.g. /)
106
+ entry_path = "#{@zip_prefix}#{real_path}"
107
+ entry_path
108
+ end
109
+
110
+
111
+ end # class ZipReader
112
+ end # module BeerDb
@@ -0,0 +1,195 @@
1
+ # encoding: UTF-8
2
+
3
+ module BeerDb
4
+
5
+
6
+ class CreateDb < ActiveRecord::Migration
7
+
8
+ def up
9
+
10
+ create_table :beers do |t|
11
+ t.string :key, :null => false # import/export key
12
+ t.string :title, :null => false
13
+ t.string :synonyms # comma separated list of synonyms
14
+
15
+ t.string :web # optional url link (e.g. )
16
+ t.integer :since # optional year (e.g. 1896)
17
+
18
+ # t.boolean :bottle, :null => false, :default => false # Flaschenbier
19
+ # t.boolean :draft, :null => false, :default => false # Fassbier
20
+ ## todo: check seasonal is it proper english?
21
+ t.boolean :seasonal, :null => false, :default => false # all year or just eg. Festbier/Oktoberfest Special
22
+ t.boolean :limited, :null => false, :default => false # one year or season only
23
+ ## todo: add microbrew/brewpub flag?
24
+ #### t.boolean :brewpub, :null => false, :default => false
25
+
26
+ ## add t.boolean :lite flag ??
27
+ t.decimal :kcal # kcal/100ml e.g. 45.0 kcal/100ml
28
+
29
+ ## check: why decimal and not float?
30
+ t.decimal :abv # Alcohol by volume (abbreviated as ABV, abv, or alc/vol) e.g. 4.9 %
31
+ t.decimal :og # malt extract (original gravity) in plato
32
+ t.integer :srm # color in srm
33
+ t.integer :ibu # bitterness in ibu
34
+
35
+ ### fix/todo: add bitterness field
36
+
37
+ # renamed - old field names
38
+ ## t.decimal :plato # stammwuerze / gravity in plato scale (e.g. °P) e.g. 12.6° - todo: use a different field name e.g. just p or gravity?
39
+ ## t.integer :color # beer color in Standard Reference Method (SRM)
40
+
41
+ # see en.wikipedia.org/wiki/Plato_scale#Colour
42
+
43
+ # SRM/Lovibond | Example | Beer color | EBC
44
+ # ---------------------------------------------------------------
45
+ # 2 | Pale lager, Witbier, Pilsener, Berliner Weisse | #F8F753 | 4
46
+ # 3 | Maibock, Blonde Ale | #F6F513 | 6
47
+ # 4 | Weissbier | #ECE61A | 8
48
+ # 6 | American Pale Ale, India Pale Ale | #D5BC26 | 12
49
+ # 8 | Weissbier, Saison | #BF923B | 16
50
+ # 10 | English Bitter, ESB | #BF813A | 20
51
+ # 13 | Biere de Garde, Double IPA | #BC6733 | 26
52
+ # 17 | Dark lager, Vienna lager, Marzen, Amber Ale | #8D4C32 | 33
53
+ # 20 | Brown Ale, Bock, Dunkel, Dunkelweizen | #5D341A | 39
54
+ # 24 | Irish Dry Stout, Doppelbock, Porter | #261716 | 47
55
+ # 29 | Stout | #0F0B0A | 57
56
+ # 35 | Foreign Stout, Baltic Porter | #080707 | 69
57
+ # 40+ | Imperial Stout | #030403 | 79
58
+
59
+ t.references :brewery # optional (for now)
60
+ t.references :brand # optional (for now)
61
+
62
+
63
+ ## todo: add categories e.g. (A/B/C, 1/2/3, main/major/minor ??)
64
+ # - A-grade /1st class/ tier1 / main beer brand/bestseller/flagship ?
65
+ # - B-grade /2nd class/ tier2 / regular, major, - todo: find better names?
66
+ # - C-grade /3nd class/ tier3/ / speciality, minor ?
67
+
68
+ # use stars in .txt e.g. # ***/**/*/- => 1/2/3/4
69
+ t.integer :grade, :null => false, :default => 4
70
+
71
+ t.string :txt # source ref
72
+ t.boolean :txt_auto, :null => false, :default => false # inline? got auto-added?
73
+
74
+
75
+ t.references :country, :null => false
76
+ t.references :region # optional
77
+ t.references :city # optional
78
+
79
+ t.timestamps
80
+ end
81
+
82
+
83
+ create_table :brands do |t| # beer families (sharing same name e.g. brand)
84
+ t.string :key, :null => false # import/export key
85
+ t.string :title, :null => false
86
+ t.string :synonyms # comma separated list of synonyms
87
+ t.string :web # optional web page (e.g. www.ottakringer.at)
88
+ t.string :wiki # optional wiki(pedia page)
89
+ t.integer :since
90
+
91
+ ## scope of brand (global/intern'l/national/regional/local) ??
92
+ t.boolean :global, :null => false, :default => false
93
+ t.boolean :internl, :null => false, :default => false
94
+ t.boolean :national, :null => false, :default => false
95
+ t.boolean :regional, :null => false, :default => false
96
+ t.boolean :local, :null => false, :default => false
97
+
98
+ # t.integer :brand_grade # 1/2/3/4/5 (global/intern'l/national/regional/local)
99
+
100
+ # use stars in .txt e.g. # ***/**/*/- => 1/2/3/4
101
+ t.integer :grade, :null => false, :default => 4
102
+ # -- todo: add plus 1 for brewery w/ *** ??
103
+
104
+ t.string :txt # source ref
105
+ t.boolean :txt_auto, :null => false, :default => false # inline? got auto-added?
106
+
107
+
108
+ t.references :brewery # optional (for now)
109
+
110
+ t.references :country, :null => false
111
+ t.references :region # optional
112
+ t.references :city # optional
113
+
114
+ t.timestamps
115
+ end
116
+
117
+ create_table :breweries do |t|
118
+ t.string :key, :null => false # import/export key
119
+ t.string :title, :null => false
120
+ t.string :synonyms # comma separated list of synonyms
121
+ t.string :address
122
+ t.integer :since
123
+ ### fix: rename back to founded or use opened/closed
124
+ ## fix: add flag for ca./about boolean opened_guess / opened_est / opened_??
125
+ ## ca. / about 1010 marker e.g t.boolean : opened_est (for estimate) or similar!!!
126
+ ## renamed to founded to since
127
+ ## t.integer :founded # year founded/established - todo/fix: rename to since?
128
+ t.integer :closed # optional; year brewery closed
129
+
130
+ ## todo: add optional parent brewery (owned_by) ???
131
+
132
+ t.boolean :brewpub, :null => false, :default => false
133
+ t.boolean :prod_m, :null => false, :default => false # prod medium (mid-size/regional brewery)
134
+ # e.g. > 15_000 barrels (us)
135
+ t.boolean :prod_l, :null => false, :default => false # prod large
136
+ # e.g. > 500_000 hl (at), > 6_000_000 barrels (us)
137
+
138
+ t.integer :prod # (estimated) annual production/capacity in hl (1hl=100l) e.g. megabrewery 2_000_000, microbrewery 1_000 hl; brewbup 500 hl etc.
139
+ t.integer :prod_grade # 1/2/3/4/5/6/7/8/9/10/11
140
+
141
+ # grade - classified using annual production (capacity) in hl
142
+ # < 1_000 hl => 11
143
+ # < 3_000 hl => 10
144
+ # < 5_000 hl => 9
145
+ # < 10_000 hl => 8
146
+ # < 50_000 hl => 7
147
+ # < 100_000 hl => 6
148
+ # < 200_000 hl => 5
149
+ # < 500_000 hl => 4
150
+ # < 1_000_000 hl => 3
151
+ # < 2_000_000 hl => 2
152
+ # > 2_000_000 hl => 1
153
+
154
+
155
+ # use stars in .txt e.g. # ***/**/*/- => 1/2/3/4
156
+ t.integer :grade, :null => false, :default => 4
157
+
158
+
159
+ t.string :txt # source ref
160
+ t.boolean :txt_auto, :null => false, :default => false # inline? got auto-added?
161
+
162
+ t.string :web # optional web page (e.g. www.ottakringer.at)
163
+ t.string :wikipedia # optional wiki(pedia page)
164
+
165
+ t.boolean :indie # independent brewery (flag)
166
+
167
+ # for convenience (easy queries) use flags for top beer multinationals (-- later use just tags? more flexible)
168
+ t.boolean :abinbev # owned by AB InBev / Anheuser-Busch InBev (and Grupo Modelo)
169
+ t.boolean :sabmiller # owned by SAB Miller (in US cooperates w/ Molson Coors using MillerCoors venture)
170
+ t.boolean :heineken # owned by Heineken
171
+ t.boolean :carlsberg # owned by Carlsberg
172
+ t.boolean :molsoncoors # owned by Molson Coors
173
+ t.boolean :diageo # owned by Diageo (e.g. Guiness, Kilkenny,...)
174
+
175
+
176
+ # todo: add t.references :parent # for parent brewery
177
+ # (or better use has many parents w/ percentage of ownership; might not be 100%)
178
+
179
+ t.references :country, :null => false
180
+ t.references :region # optional
181
+ t.references :city # optional
182
+
183
+ t.timestamps
184
+ end
185
+
186
+ end # method up
187
+
188
+ def down
189
+ raise ActiveRecord::IrreversibleMigration
190
+ end
191
+
192
+
193
+ end # class CreateDb
194
+
195
+ end # module BeerDb
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+
3
+ module BeerDb::Model
4
+
5
+ class BeerSerializer
6
+
7
+ def initialize( beer )
8
+ @beer = beer
9
+ end
10
+
11
+ attr_reader :beer
12
+
13
+ def as_json
14
+ brewery = {}
15
+ if beer.brewery.present?
16
+ brewery = { key: beer.brewery.key,
17
+ title: beer.brewery.title }
18
+ end
19
+
20
+ tags = []
21
+ if beer.tags.present?
22
+ beer.tags.each { |tag| tags << tag.key }
23
+ end
24
+
25
+ country = {
26
+ key: beer.country.key,
27
+ title: beer.country.title
28
+ }
29
+
30
+ data = { key: beer.key,
31
+ title: beer.title,
32
+ synonyms: beer.synonyms,
33
+ abv: beer.abv,
34
+ srm: beer.srm,
35
+ og: beer.og,
36
+ tags: tags,
37
+ brewery: brewery,
38
+ country: country }
39
+
40
+ data.to_json
41
+ end
42
+
43
+ end # class BeerSerializer
44
+
45
+ end # module BeerDb::Model
@@ -0,0 +1,46 @@
1
+ # encoding: UTF-8
2
+
3
+ module BeerDb::Model
4
+
5
+ class BrewerySerializer
6
+
7
+ def initialize( brewery )
8
+ @brewery = brewery
9
+ end
10
+
11
+ attr_reader :brewery
12
+
13
+ def as_json
14
+
15
+ beers = []
16
+ brewery.beers.each do |b|
17
+ beers << { key: b.key, title: b.title }
18
+ end
19
+
20
+ tags = []
21
+ if brewery.tags.present?
22
+ brewery.tags.each { |tag| tags << tag.key }
23
+ end
24
+
25
+ country = {
26
+ key: brewery.country.key,
27
+ title: brewery.country.title
28
+ }
29
+
30
+ data = { key: brewery.key,
31
+ title: brewery.title,
32
+ synonyms: brewery.synonyms,
33
+ since: brewery.since,
34
+ address: brewery.address,
35
+ web: brewery.web,
36
+ prod: brewery.prod, # (estimated) annual production in hl e.g. 2_000 hl
37
+ tags: tags,
38
+ beers: beers,
39
+ country: country }
40
+
41
+ data.to_json
42
+ end
43
+
44
+ end # class BrewerySerializer
45
+
46
+ end # module BeerDb::Model