dietary_dsl 0.1.2 → 0.2.0

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
2
  SHA1:
3
- metadata.gz: 651b234879ecc76f0c70595a4afdf213395a9f98
4
- data.tar.gz: 9c81ff86c69d62073a0b7740b7b779fdbd405e56
3
+ metadata.gz: beddb338f7ac88922780c7d5733a7abe12e50e32
4
+ data.tar.gz: af2be559f92b65796ea233b75815568e59278b7d
5
5
  SHA512:
6
- metadata.gz: bf6269b03deab7b95b91de36d253452c0b245765deedd2c40e2a0c7c5ed58beaf6470e7030f6f4f1c5bdeb6ad7eef4d6c89671445dc11f4dab0a9e59398a0230
7
- data.tar.gz: 14866e3d9c0eea790d71c4d2a20165e2c3e01a14607d50e70a26fe99df1c5ffc836c5bb2b1a21a04ceb6017785ed4b7ff9bae285b4afcabf67d54300fcd7b51f
6
+ metadata.gz: e062e6cb85ff878a37ce18948f6b65fed04f7fc303dba6bb5bdbe975e98632e1451d57d8b300758ab58e6130c4b1357a205d178cfc21334f1a505e4aecb4fb36
7
+ data.tar.gz: dbf188edc36dd412824a74f46f60b64a0bc5befdb41306db94bcfa69c3fa6746a29a65529fd56f227f32de8d0642f0b8d93d5944bd35d81f5fd67fdac92d5fd6
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # DietaryDsl
2
2
 
3
+ [![Gem](https://img.shields.io/gem/v/dietary_dsl.svg)](https://rubygems.org/gems/dietary_dsl)
3
4
  [![Build status](https://gitlab.com/DanielRamosAcosta/dietary_dsl/badges/master/build.svg)](httpshttps://gitlab.com/DanielRamosAcosta/dietary_dsl/pipelines)
4
5
  [![Overall test coverage](https://gitlab.com/DanielRamosAcosta/dietary_dsl/badges/master/coverage.svg)](http://danielramosacosta.gitlab.io/dietary_dsl/coverage)
5
6
 
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'builder'
6
+ require 'active_support/all'
7
+ require 'dietary_dsl/bedca_api/constants'
8
+ require 'dietary_dsl/bedca_api/food_value'
9
+ require 'dietary_dsl/bedca_api/food_values'
10
+ require 'pp'
11
+
12
+ module DietaryDsl
13
+ # Parte de la clase que interactúa con la base de datos
14
+ class Food
15
+ attr_reader :raw, :nombre, :name, :values
16
+
17
+ include BEDCA
18
+
19
+ @http = Net::HTTP.new(URL.host, URL.port)
20
+
21
+ class << self
22
+ attr_accessor :http
23
+ end
24
+
25
+ def self.request(xml)
26
+ response = @http.request_post URL, XML_HEADER + xml, 'Content-Type' => 'text/xml'
27
+ body = response.read_body
28
+ return Hash.from_xml body
29
+ rescue
30
+ raise 'Hay un problema con la conexión'
31
+ end
32
+
33
+ def self.sanitize_response(response)
34
+ response.dig 'foodresponse', 'food'
35
+ end
36
+
37
+ def self.build_attributes(b, attributes)
38
+ attributes
39
+ .reject { |(key)| key == 'foodvalue' }
40
+ .each do |(key)|
41
+ b.atribute name: key
42
+ end
43
+ end
44
+
45
+ def self.query(attributes = ATTRIBUTES)
46
+ Builder::XmlMarkup.new.foodquery do |b|
47
+ b.type level: 2
48
+ b.selection do
49
+ build_attributes(b, attributes)
50
+ end
51
+ yield b
52
+ end
53
+ end
54
+
55
+ def self.where(b, field, relation, value)
56
+ b.condition do
57
+ b.cond1 do
58
+ b.atribute1(name: ATTRIBUTES.key(field))
59
+ end
60
+ b.relation(type: relation)
61
+ b.cond3(value)
62
+ end
63
+ end
64
+
65
+ def self.find_by_and_relation(data, relation)
66
+ xml = query do |b|
67
+ data.each do |(key), value|
68
+ where(b, key, relation, value)
69
+ end
70
+ end
71
+
72
+ data = sanitize_response request xml
73
+ return nil if data.nil?
74
+
75
+ Food.new(data)
76
+ end
77
+
78
+ def self.find(id)
79
+ find_by(id: id)
80
+ end
81
+
82
+ def self.find_by(data)
83
+ find_by_and_relation(data, RELATIONS[:equal])
84
+ end
85
+
86
+ def self.find_by_like(data)
87
+ find_by_and_relation(data, RELATIONS[:like])
88
+ end
89
+
90
+ def initialize(values)
91
+ @data = rehash(values)
92
+ @groups = @data[:foodvalue]
93
+ .group_by { |value| value['cg_descripcion'] }
94
+ .each_with_object({}) do |(key, vals), hash|
95
+ hash[CATEGORIES[key]] = FoodValues.new(vals.first['cg_descripcion'], vals)
96
+ end
97
+
98
+ @data.delete(:foodvalue)
99
+ @data[:groups] = @groups
100
+
101
+ @general_values = download_general_values
102
+ end
103
+
104
+ def [](key)
105
+ @data[key]
106
+ end
107
+
108
+ def download_general_values
109
+ body = (Food.http.request_get "http://www.bedca.net/cocoon/svg/response#{self[:id]}langes.svg").read_body
110
+ parse_svg body
111
+ end
112
+
113
+ def parse_svg(svg)
114
+ (svg.scan SVG_REGEX).each_with_object({}) do |value, hash|
115
+ hash[COMPONENTS[value.last]] = value.first.delete(' ')
116
+ hash
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require 'net/http'
5
+ require 'builder'
6
+ require 'active_support/all'
7
+ require 'dietary_dsl/bedca_api/constants'
8
+ require 'dietary_dsl/bedca_api/food_value'
9
+ require 'dietary_dsl/bedca_api/food_values'
10
+ require 'pp'
11
+
12
+ module DietaryDsl
13
+ # Parte de la clase que presenta sus datos
14
+ class Food
15
+ def kcal
16
+ @data[:groups][:proximales][:energia_total][:cantidad]
17
+ .gsub(/.+kJ/, '')
18
+ .to_f * 0.238846
19
+ end
20
+
21
+ def to_s
22
+ tables = @data[:groups]
23
+ .map do |(_key, group)|
24
+ group.to_table
25
+ end
26
+ .join("\n")
27
+
28
+ <<~TO_MARKDOWN
29
+ # #{self[:nombre]}
30
+
31
+ > #{self[:scientific_name]}
32
+
33
+ ## Distribución de la Energía total
34
+
35
+ Proteínas: #{@general_values[:proteina_total]}
36
+ Grasas: #{@general_values[:grasa_total]}
37
+ Carbohidratos: #{@general_values[:carbohidratos]}
38
+ Alcohol: #{@general_values[:alcohol]}
39
+
40
+ ## Información de composición (por 100 g de porción comestible)
41
+
42
+ #{tables}
43
+ TO_MARKDOWN
44
+ end
45
+ end
46
+ end
@@ -1,145 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'uri'
4
- require 'net/http'
5
- require 'builder'
6
- require 'active_support/all'
7
- require 'dietary_dsl/bedca_api/constants'
8
- require 'dietary_dsl/bedca_api/food_value'
9
- require 'dietary_dsl/bedca_api/food_values'
10
- require 'pp'
11
-
12
- module DietaryDsl
13
- # Class that wraps Bedca database API
14
- class Food
15
- attr_reader :raw, :nombre, :name, :values
16
-
17
- include BEDCA
18
-
19
- @http = Net::HTTP.new(URL.host, URL.port)
20
-
21
- class << self
22
- attr_accessor :http
23
- end
24
-
25
- def self.request(xml)
26
- response = @http.request_post URL, XML_HEADER + xml, 'Content-Type' => 'text/xml'
27
- body = response.read_body
28
- return Hash.from_xml body
29
- rescue
30
- raise 'Hay un problema con la conexión'
31
- end
32
-
33
- def self.sanitize_response(response)
34
- response.dig 'foodresponse', 'food'
35
- end
36
-
37
- def self.build_attributes(b, attributes)
38
- attributes
39
- .reject { |(key)| key == 'foodvalue' }
40
- .each do |(key)|
41
- b.atribute name: key
42
- end
43
- end
44
-
45
- def self.query(attributes = ATTRIBUTES)
46
- Builder::XmlMarkup.new.foodquery do |b|
47
- b.type level: 2
48
- b.selection do
49
- build_attributes(b, attributes)
50
- end
51
- yield b
52
- end
53
- end
54
-
55
- def self.where(b, field, relation, value)
56
- b.condition do
57
- b.cond1 do
58
- b.atribute1(name: ATTRIBUTES.key(field))
59
- end
60
- b.relation(type: relation)
61
- b.cond3(value)
62
- end
63
- end
64
-
65
- def self.find_by_and_relation(data, relation)
66
- xml = query do |b|
67
- data.each do |(key), value|
68
- where(b, key, relation, value)
69
- end
70
- end
71
-
72
- data = sanitize_response request xml
73
- return nil if data.nil?
74
-
75
- Food.new(data)
76
- end
77
-
78
- def self.find(id)
79
- find_by(id: id)
80
- end
81
-
82
- def self.find_by(data)
83
- find_by_and_relation(data, RELATIONS[:equal])
84
- end
85
-
86
- def self.find_by_like(data)
87
- find_by_and_relation(data, RELATIONS[:like])
88
- end
89
-
90
- def initialize(values)
91
- @data = rehash(values)
92
- @groups = @data[:foodvalue]
93
- .group_by { |value| value['cg_descripcion'] }
94
- .each_with_object({}) do |(key, vals), hash|
95
- hash[CATEGORIES[key]] = FoodValues.new(vals.first['cg_descripcion'], vals)
96
- end
97
-
98
- @data.delete(:foodvalue)
99
- @data[:groups] = @groups
100
-
101
- @general_values = download_general_values
102
- end
103
-
104
- def [](key)
105
- @data[key]
106
- end
107
-
108
- def download_general_values
109
- body = (Food.http.request_get "http://www.bedca.net/cocoon/svg/response#{self[:id]}langes.svg").read_body
110
- parse_svg body
111
- end
112
-
113
- def parse_svg(svg)
114
- (svg.scan SVG_REGEX).each_with_object({}) do |value, hash|
115
- hash[COMPONENTS[value.last]] = value.first.delete(' ')
116
- hash
117
- end
118
- end
119
-
120
- def to_s
121
- tables = @data[:groups]
122
- .map do |(_key, group)|
123
- group.to_table
124
- end
125
- .join("\n")
126
-
127
- <<~TO_MARKDOWN
128
- # #{self[:nombre]}
129
-
130
- > #{self[:scientific_name]}
131
-
132
- ## Distribución de la Energía total
133
-
134
- Proteínas: #{@general_values[:proteina_total]}
135
- Grasas: #{@general_values[:grasa_total]}
136
- Carbohidratos: #{@general_values[:carbohidratos]}
137
- Alcohol: #{@general_values[:alcohol]}
138
-
139
- ## Información de composición (por 100 g de porción comestible)
140
-
141
- #{tables}
142
- TO_MARKDOWN
143
- end
144
- end
145
- end
3
+ require 'dietary_dsl/bedca_api/food/orm'
4
+ require 'dietary_dsl/bedca_api/food/others'
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dietary_dsl/bedca_api/food'
4
+
5
+ module DietaryDsl
6
+ # Clase que representa un menú. Un menú se compone de distintos platos (entrantes, primeros platos, postres...)
7
+ class Alimento
8
+ def initialize(nombre, options = {})
9
+ @alimento = DietaryDsl::Food.find_by(nombre: nombre) unless options[:exact].nil?
10
+ @alimento = DietaryDsl::Food.find_by_like(nombre: nombre) if options[:exact].nil?
11
+ raise "El alimento #{nombre} no existe" if @alimento.nil?
12
+ end
13
+
14
+ def [](key)
15
+ @alimento[key]
16
+ end
17
+
18
+ def kcal
19
+ @alimento.kcal
20
+ end
21
+
22
+ def masa
23
+ @alimento.masa
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DietaryDsl
4
+ # Clase que representa un día completo, con los menús correspondientes para cada comida
5
+ class Dia
6
+ include Enumerable
7
+
8
+ def initialize(title = nil, &block)
9
+ @title = title
10
+ @menus = {}
11
+ instance_eval(&block)
12
+ end
13
+
14
+ def [](key)
15
+ @menus[key]
16
+ end
17
+
18
+ def kcal
19
+ @menus.inject(0) do |sum, (_, menu)|
20
+ sum + menu.kcal
21
+ end
22
+ end
23
+
24
+ def each
25
+ @menus.each { |i| yield i }
26
+ end
27
+
28
+ def desayuno(menu)
29
+ @menus[:desayuno] = menu
30
+ end
31
+
32
+ def media_maniana(menu)
33
+ @menus[:media_mañana] = menu
34
+ end
35
+
36
+ def almuerzo(menu)
37
+ @menus[:almuerzo] = menu
38
+ end
39
+
40
+ def merienda(menu)
41
+ @menus[:merienda] = menu
42
+ end
43
+
44
+ def cena(menu)
45
+ @menus[:menu] = menu
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dietary_dsl/bedca_api/food'
3
+ require 'dietary_dsl/dsl/alimento'
4
4
 
5
5
  module DietaryDsl
6
6
  # Clase que representa un menú. Un menú se compone de distintos platos (entrantes, primeros platos, postres...)
@@ -16,7 +16,18 @@ module DietaryDsl
16
16
  end
17
17
 
18
18
  def plato(datos)
19
+ return plato_single(datos) if datos.is_a?(Hash)
19
20
  @platos = @platos.push datos
20
21
  end
22
+
23
+ def plato_single(datos)
24
+ @platos = @platos.push(DietaryDsl::Plato.new(datos[:food]) { alimento(datos) })
25
+ end
26
+
27
+ def kcal
28
+ @platos.inject(0) do |sum, plato|
29
+ sum + plato.kcal
30
+ end
31
+ end
21
32
  end
22
33
  end
@@ -5,6 +5,10 @@ require 'dietary_dsl/bedca_api/food'
5
5
  module DietaryDsl
6
6
  # Clase que representa un plato. Un plato es una comida específica, como pulpo a la gallega, o un potaje
7
7
  class Plato
8
+ include Enumerable
9
+
10
+ attr_reader :title
11
+
8
12
  def initialize(title, &block)
9
13
  @title = title
10
14
  @alimentos = []
@@ -15,13 +19,44 @@ module DietaryDsl
15
19
  @alimentos[key]
16
20
  end
17
21
 
22
+ def each
23
+ @alimentos.each { |i| yield i }
24
+ end
25
+
18
26
  def alimento(datos)
19
- alimento = DietaryDsl::Food.find_by_like(nombre: datos[:food])
20
- raise "El alimento #{datos[:food]} no existe" if alimento.nil?
27
+ alimento = DietaryDsl::Alimento.new(datos[:food], datos)
21
28
  cantidad = datos[:cantidad]
22
29
  @alimentos = @alimentos.push food: alimento, cantidad: cantidad
23
30
  end
24
31
 
32
+ def kcal
33
+ @alimentos.inject(0) do |sum, item|
34
+ cantidad = item[:cantidad]
35
+ kilocalorias = item[:food].kcal
36
+
37
+ is_mass = cantidad.instance_of? DietaryDsl::Masa
38
+ gramos = cantidad.to.g if is_mass
39
+ gramos = cantidad.to.cm3 unless is_mass
40
+ kcal_totales = ((gramos * kilocalorias) / 100)
41
+ sum + kcal_totales
42
+ end
43
+ end
44
+
45
+ def kcal_por_cada(cantidad)
46
+ (kcal * cantidad.to.g) / masa.to.g
47
+ end
48
+
49
+ def masa
50
+ gr = @alimentos.inject(0) do |sum, item|
51
+ is_mass = item[:cantidad].instance_of? DietaryDsl::Masa
52
+ gramos = item[:cantidad].to.g if is_mass
53
+ gramos = item[:cantidad].to.cm3 unless is_mass
54
+ sum + gramos
55
+ end
56
+
57
+ DietaryDsl::Masa.new(gr)
58
+ end
59
+
25
60
  def to_s
26
61
  alimentos = @alimentos
27
62
  .map { |data| "* #{data[:food][:nombre]}" }
@@ -46,6 +46,10 @@ module DietaryDsl
46
46
  def *(other)
47
47
  Masa.new(@cantidad * other.cantidad)
48
48
  end
49
+
50
+ def +(other)
51
+ Masa.new(@cantidad + other.cantidad)
52
+ end
49
53
  end
50
54
  end
51
55
 
@@ -14,16 +14,20 @@ module DietaryDsl
14
14
  Volumen.new(number)
15
15
  end
16
16
 
17
+ def self.ml(number)
18
+ Volumen.new(number / 1000.0)
19
+ end
20
+
17
21
  def self.cm3(number)
18
- Volumen.new(number / 1000)
22
+ Volumen.new(number / 1000.0)
19
23
  end
20
24
 
21
25
  def self.cucharada(number)
22
- Volumen.new(number / 50.0)
26
+ Volumen.new((number * 3.0) / 200.0)
23
27
  end
24
28
 
25
29
  def self.vaso(number)
26
- Volumen.new(number / 4.0)
30
+ Volumen.new(number / 5.0)
27
31
  end
28
32
 
29
33
  def self.chorrito(number)
@@ -74,6 +78,18 @@ class Numeric
74
78
  l
75
79
  end
76
80
 
81
+ def ml
82
+ DietaryDsl::Volumen.ml(self)
83
+ end
84
+
85
+ def mililitro
86
+ ml
87
+ end
88
+
89
+ def mililitros
90
+ ml
91
+ end
92
+
77
93
  def cucharada
78
94
  DietaryDsl::Volumen.cucharada(self)
79
95
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DietaryDsl
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/dietary_dsl.rb CHANGED
@@ -2,8 +2,10 @@
2
2
 
3
3
  require 'dietary_dsl/version'
4
4
  require 'dietary_dsl/bedca_api/food'
5
+ require 'dietary_dsl/dsl/alimento'
5
6
  require 'dietary_dsl/dsl/plato'
6
7
  require 'dietary_dsl/dsl/menu'
8
+ require 'dietary_dsl/dsl/dia'
7
9
  require 'dietary_dsl/measures'
8
10
 
9
11
  # Module that encolses the gem
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dietary_dsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Ramos
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-21 00:00:00.000000000 Z
11
+ date: 2017-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -211,8 +211,12 @@ files:
211
211
  - lib/dietary_dsl/bedca_api/constants/relations.rb
212
212
  - lib/dietary_dsl/bedca_api/constants/utils.rb
213
213
  - lib/dietary_dsl/bedca_api/food.rb
214
+ - lib/dietary_dsl/bedca_api/food/orm.rb
215
+ - lib/dietary_dsl/bedca_api/food/others.rb
214
216
  - lib/dietary_dsl/bedca_api/food_value.rb
215
217
  - lib/dietary_dsl/bedca_api/food_values.rb
218
+ - lib/dietary_dsl/dsl/alimento.rb
219
+ - lib/dietary_dsl/dsl/dia.rb
216
220
  - lib/dietary_dsl/dsl/menu.rb
217
221
  - lib/dietary_dsl/dsl/plato.rb
218
222
  - lib/dietary_dsl/measures.rb