dietary_dsl 0.1.2 → 0.2.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.
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