brewer 0.0.97 → 0.0.98

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: 954f08b0f0f7a708b3408d27c0524c488efe9f22
4
- data.tar.gz: 0cd5a49e289ada705ed47c9041fde6464c762548
3
+ metadata.gz: ad359c3a32aaadf2c8c915016a25826a42be6a53
4
+ data.tar.gz: 9a7bf80ab7832cd3b7d54fcaf8268a7896f91167
5
5
  SHA512:
6
- metadata.gz: 0449cb3f51fd13ad2ccc6f29f1c579627ca4cf94bf2e66fc06c9a7ece1dd405830bb838453d850b80871b779cc2992cee95652b04621b9be929e859e2a81ca47
7
- data.tar.gz: 80e7455f3845e458e1d82f86e86b7c63f3c72cac58b7a98ddf982886153e64e866341c2956a4ef2b172399ab9e4cfb59870d1d9dc504b5177e98b6fefd379115
6
+ metadata.gz: 0cd35a5382e5d37df326473777e9a179009f0d8c8a91db6510ce071df40897f8645ede980201d4a9993360b6a0356c4f2651c59cc679ea87f05bcd277998325e
7
+ data.tar.gz: 139e62eaefece3c38a0acf40ec4981d7e378a37e3299fad82b2a976f07567e75b7af2591839eb514a0f6a245e6ea2664ed090fa0302899caf98c44371bfc62e5
data/README.md CHANGED
@@ -21,7 +21,7 @@ brewer
21
21
  ```
22
22
 
23
23
 
24
- You can now run the master procedure (the entire standard brewing process) with:
24
+ You can run the master procedure (the entire standard brewing process) with:
25
25
 
26
26
  ```ruby
27
27
  >> procedures.master
@@ -31,30 +31,10 @@ You can now run the master procedure (the entire standard brewing process) with:
31
31
  You will be prompted to enter a slack `webhook_url`, which you can get from the `incoming-webhooks` integration on your slack channel.
32
32
 
33
33
 
34
- The shell will ask you for recipe variables in the beginning, and will warn you when you need to intervene.
34
+ You will be asked to load a recipe, or create a new one. These recipes store information like mash time, mash temperature, etc.
35
35
 
36
36
  # Web Interface (in development)
37
- Run the `brewer-server` binary the same way you would run the `brewer` binary. This will start a `sinatra` server on your pi's ip address. The default port is `8080`, but you can specify a custom port with:
38
-
39
- ```shell
40
- sudo brewer-server -p YOUR_PORT
41
- ```
42
-
43
- Keep in mind that any port below 1024 will need root access. I like to specify port `80` (http default) so that I can leave the port off and it will default to 80.
44
-
45
- You can add a line to `/etc/hosts` on your workstation and redirect a url to your pi's ip. For instance, the relevant line in my `/etc/hosts` looks like this:
46
-
47
- ```shell
48
- 192.168.0.224 navasota.brew
49
- ```
50
-
51
- so I can visit `navasota.brew` and see the brewing homepage when `brewer-server` is running.
52
-
53
- # Starting the server on system startup
54
-
55
- You may want to start the `brewer-server` an system boot so that a workstation is not required to connect (ssh) to your pi.
56
-
57
- [See here for a StackOverflow solution](https://raspberrypi.stackexchange.com/a/8735) or read on below.
37
+ [See here](http://github.com/llamicron/brewer-server)
58
38
 
59
39
  # Installation
60
40
  This is a gem, published on [rubygems.org](http://rubygems.org). Install it the recommended way with:
@@ -68,7 +48,7 @@ gem 'brewer'
68
48
  ```
69
49
  or `.gemspec` file:
70
50
  ```ruby
71
- s.add_runtime_dependency 'brewer'
51
+ spec.add_runtime_dependency 'brewer'
72
52
  ```
73
53
 
74
54
  You may also download a .gem file from the [releases section on github](https://github.com/llamicron/brewer/releases) and install it that way, or further still build a new .gem file from the `brewer.gemspec` if you want the latest possible release. This is not recommended, as I do not regularly make releases on Github, just rubygems
@@ -84,5 +64,3 @@ to open an interactive shell to control your brew rig in realtime. Just like any
84
64
  Documentation is in `doc/` or on rubygems.org
85
65
 
86
66
  ---
87
-
88
- *This line is for Travis CI build triggers, please ignore*
data/Rakefile CHANGED
@@ -29,7 +29,7 @@ end
29
29
  # Generate or update documentation
30
30
  # Generates in `doc/`
31
31
  RDoc::Task.new do |rdoc|
32
- rm_rf "doc/"
32
+ # rm_rf "doc/"
33
33
  rdoc.rdoc_dir = 'doc/'
34
34
  rdoc.main = "README.md"
35
35
  # rdoc.rdoc_files.include("**/*.rb")
@@ -44,3 +44,16 @@ end
44
44
  task :clear_coverage do
45
45
  rm_rf('coverage/')
46
46
  end
47
+
48
+ task :console do
49
+ require 'pry'
50
+ require_relative 'lib/brewer'
51
+
52
+ def reload!
53
+ files = $LOADED_FEATURES.select { |feat| feat =~ /\/brewer\// }
54
+ files.each { |file| load file }
55
+ end
56
+
57
+ ARGV.clear
58
+ Pry.start
59
+ end
data/bin/brewer CHANGED
@@ -4,10 +4,10 @@ require_relative "../lib/brewer"
4
4
  adaptibrew = Brewer::Adaptibrew.new
5
5
  adaptibrew.refresh
6
6
 
7
+ kitchen = Brewer::Kitchen.new
7
8
  slack = Brewer::Slacker.new
8
9
  brewer = Brewer::Brewer.new
9
10
  procedures = Brewer::Procedures.new
10
11
 
11
-
12
12
  binding.pry(quiet: true)
13
13
  # 🍺🍺🍺
@@ -11,13 +11,9 @@ module Brewer
11
11
  @disable_network_operations = network? ? false : true
12
12
  @adaptibrew_url = 'https://github.com/llamicron/adaptibrew.git'
13
13
 
14
- if !Dir.exists?(brewer_dir)
14
+ unless Dir.exists?(brewer_dir)
15
15
  Dir.mkdir(brewer_dir)
16
16
  end
17
-
18
- if !Dir.exists?(adaptibrew_dir)
19
- Dir.mkdir(adaptibrew_dir)
20
- end
21
17
  end
22
18
 
23
19
  def clone
@@ -25,7 +21,7 @@ module Brewer
25
21
  return false
26
22
  end
27
23
 
28
- if !Dir.exists?(adaptibrew_dir)
24
+ if !present?
29
25
  Git.clone(@adaptibrew_url, 'adaptibrew', :path => brewer_dir)
30
26
  return true
31
27
  end
@@ -36,6 +32,7 @@ module Brewer
36
32
  if @disable_network_operations
37
33
  return false
38
34
  end
35
+
39
36
  if present?
40
37
  FileUtils.rm_rf(adaptibrew_dir)
41
38
  return true
@@ -51,7 +48,12 @@ module Brewer
51
48
  end
52
49
 
53
50
  def present?
54
- return Dir.exists?(adaptibrew_dir) ? true : false
51
+ if Dir.exists?(adaptibrew_dir)
52
+ if Dir.entries(adaptibrew_dir).length > 2
53
+ return true
54
+ end
55
+ end
56
+ false
55
57
  end
56
58
 
57
59
  end
@@ -21,12 +21,6 @@ module Brewer
21
21
 
22
22
  public
23
23
 
24
- # sleeps for a number of seconds
25
- def wait(time=30)
26
- sleep(time.to_f)
27
- self
28
- end
29
-
30
24
  # Runs an adaptibrew script (written in python)
31
25
  def script(script, params=nil)
32
26
  `python #{@base_path}/adaptibrew/#{script}.py #{params}`.chomp
@@ -9,6 +9,10 @@ module Helpers
9
9
  Time.now.strftime("%m/%d/%Y %H:%M")
10
10
  end
11
11
 
12
+ def wait(time=30)
13
+ sleep(time.to_f)
14
+ end
15
+
12
16
  # Returns true if there is a network connection
13
17
  # :nocov:
14
18
  def network?
@@ -54,8 +58,8 @@ module Helpers
54
58
  end
55
59
 
56
60
  # Returns the path of the recipe storage
57
- def recipe_dir(path="")
58
- brewer_dir + "recipes/#{path}"
61
+ def kitchen_dir(path="")
62
+ brewer_dir + "kitchen/#{path}"
59
63
  end
60
64
 
61
65
  # Captures standard output, mostly used for testing
@@ -0,0 +1,110 @@
1
+ require_relative "../brewer"
2
+
3
+ module Brewer
4
+ class Kitchen
5
+
6
+ attr_accessor :url, :recipe
7
+
8
+ def initialize
9
+ @url = "http://github.com/llamicron/kitchen.git"
10
+ @recipe = Recipe.new(blank: true)
11
+ end
12
+
13
+ def clear
14
+ if present?
15
+ FileUtils.rm_rf(kitchen_dir)
16
+ return true
17
+ end
18
+ false
19
+ end
20
+
21
+ def clone
22
+ if !present?
23
+ Git.clone(@url, "kitchen", :path => brewer_dir)
24
+ return true
25
+ end
26
+ false
27
+ end
28
+
29
+ def refresh
30
+ clear
31
+ clone
32
+ true
33
+ end
34
+
35
+ def present?
36
+ if Dir.exists?(kitchen_dir)
37
+ if Dir.entries(kitchen_dir).length > 2
38
+ return true
39
+ end
40
+ end
41
+ false
42
+ end
43
+
44
+ def load(recipe_name)
45
+ raise "Recipe name must be a string" unless recipe_name.is_a? String
46
+ raise "Recipe does not exist" unless recipe_exists?(recipe_name)
47
+ @recipe = Recipe.new(recipe_name)
48
+ true
49
+ end
50
+
51
+ def store
52
+ raise "Recipe not loaded. Load a recipe or create a new one" unless !@recipe.vars.empty?
53
+ store = YAML::Store.new kitchen_dir(@recipe.vars['name'] + ".yml")
54
+ store.transaction do
55
+ @recipe.vars.each do |k, v|
56
+ store[k] = v
57
+ end
58
+ store['created_on'] = Time.now
59
+ end
60
+ true
61
+ end
62
+
63
+ def new_recipe
64
+ @recipe = Recipe.new
65
+ end
66
+
67
+ def delete_recipe(recipe)
68
+ if recipe_exists?(recipe)
69
+ File.delete(kitchen_dir(recipe + ".yml"))
70
+ return true
71
+ end
72
+ false
73
+ end
74
+
75
+ def list_recipes
76
+ list = Dir.entries(kitchen_dir).select {|file| file.match(/\.yml/) }
77
+ list.each {|recipe_name| recipe_name.slice!(".yml") }
78
+ return list
79
+ end
80
+
81
+ def list_recipes_as_table
82
+ if list_recipes.empty?
83
+ return "No Saved Recipes"
84
+ else
85
+ recipes_table_rows = list_recipes.each_slice(5).to_a
86
+ recipes_table = Terminal::Table.new :title => "All Recipes", :rows => recipes_table_rows
87
+ puts recipes_table
88
+ return recipes_table
89
+ end
90
+ end
91
+
92
+ def recipe_exists?(recipe)
93
+ raise "Recipe name must be a string" unless recipe.is_a? String
94
+ if list_recipes.include?(recipe)
95
+ return true
96
+ end
97
+ false
98
+ end
99
+
100
+ def loaded_recipe?
101
+ if @recipe
102
+ if @recipe.name
103
+ return true
104
+ end
105
+ end
106
+ false
107
+ end
108
+
109
+ end
110
+ end
@@ -8,11 +8,19 @@ module Brewer
8
8
  def initialize
9
9
  @brewer = Brewer.new
10
10
  @com = Slacker.new
11
- @recipe = Recipe.new(@brewer)
11
+ @kitchen = Kitchen.new
12
12
  end
13
13
 
14
14
  def master
15
- @recipe.get_recipe_vars
15
+ puts "Enter a recipe name or nothing to make a new one."
16
+ @kitchen.list_recipes_as_table
17
+ print ">> "
18
+ choice = gets.chomp.strip
19
+ if choice.empty?
20
+ @kitchen.new_recipe
21
+ else
22
+ @kitchen.load(choice)
23
+ end
16
24
  boot
17
25
  heat_strike_water
18
26
  dough_in
@@ -25,22 +33,19 @@ module Brewer
25
33
  end
26
34
 
27
35
  def boot
28
- puts Rainbow("booting...").yellow
36
+ puts Rainbow("Booting...").yellow
29
37
  @brewer.relay_config({
30
38
  'pid' => 0,
31
39
  'pump' => 0,
32
40
  'rims_to' => 'mash',
33
41
  'hlt_to' => 'mash'
34
42
  })
35
- # puts @brewer.all_relays_status
36
- # puts @brewer.pid
37
43
 
38
44
  puts Rainbow("Boot finished!").green
39
45
  @com.ping("🍺 boot finished 🍺")
40
46
  true
41
47
  end
42
48
 
43
-
44
49
  def heat_strike_water
45
50
  puts Rainbow("About to heat strike water").green
46
51
 
@@ -65,7 +70,7 @@ module Brewer
65
70
  unless confirm
66
71
  puts "restarting pump"
67
72
  @brewer.pump(0)
68
- @brewer.wait(2)
73
+ wait(2)
69
74
  @brewer.pump(1)
70
75
  end
71
76
 
@@ -77,13 +82,13 @@ module Brewer
77
82
 
78
83
  # calculate strike temp & set PID to strike temp
79
84
  # this sets PID SV to calculated strike temp automagically
80
- @brewer.sv(@recipe.vars['strike_water_temp'])
85
+ @brewer.sv(@kitchen.recipe.vars['strike_water_temp'])
81
86
  puts "SV has been set to calculated strike water temp"
82
87
  # turn on RIMS heater
83
88
  @brewer.pid(1)
84
89
 
85
90
  # measure current strike water temp and save
86
- @recipe.vars['starting_strike_temp'] = @brewer.pv
91
+ @kitchen.recipe.vars['starting_strike_temp'] = @brewer.pv
87
92
  puts "current strike water temp is #{@brewer.pv}."
88
93
  puts "Heating to #{@brewer.sv}"
89
94
 
@@ -95,13 +100,12 @@ module Brewer
95
100
  true
96
101
  end
97
102
 
98
-
99
103
  def dough_in
100
104
  @brewer.relay_config({
101
105
  'pid' => 0,
102
106
  'pump' => 0
103
107
  })
104
- @brewer.wait(3)
108
+ wait(3)
105
109
  @com.ping("Ready to dough in")
106
110
  puts Rainbow("Ready to dough in").green
107
111
 
@@ -113,7 +117,7 @@ module Brewer
113
117
  end
114
118
 
115
119
  def mash
116
- @brewer.sv(@recipe.vars['mash_temp'])
120
+ @brewer.sv(@kitchen.recipe.vars['mash_temp'])
117
121
 
118
122
  puts Rainbow("Mash started. This will take a while.").green
119
123
  @com.ping("Mash started. This will take a while.")
@@ -125,8 +129,8 @@ module Brewer
125
129
  })
126
130
 
127
131
  @brewer.watch
128
- @com.ping("Starting timer for #{to_minutes(@recipe.vars['mash_time'])} minutes.")
129
- @brewer.wait(@recipe.vars['mash_time'])
132
+ @com.ping("Starting timer for #{to_minutes(@kitchen.recipe.vars['mash_time'])} minutes.")
133
+ wait(@kitchen.recipe.vars['mash_time'])
130
134
  @com.ping("🍺 Mash complete 🍺. Check for starch conversion.")
131
135
  puts Rainbow("Mash complete").green
132
136
  puts "Check for starch conversion"
@@ -137,7 +141,7 @@ module Brewer
137
141
  puts Rainbow("start heating sparge water").yellow
138
142
  puts Rainbow("Mashout started").green
139
143
 
140
- @brewer.sv(@recipe.vars['mashout_temp'])
144
+ @brewer.sv(@kitchen.recipe.vars['mashout_temp'])
141
145
 
142
146
  @brewer.relay_config({
143
147
  'pid' => 1,
@@ -163,7 +167,7 @@ module Brewer
163
167
 
164
168
  print "Waiting for 10 seconds. "
165
169
  puts Rainbow("Regulate sparge balance.").yellow
166
- @brewer.wait(10)
170
+ wait(10)
167
171
 
168
172
  @brewer.relay_config({
169
173
  'rims_to' => 'boil',
@@ -206,13 +210,13 @@ module Brewer
206
210
  def boil
207
211
  puts Rainbow("Timers started for 1 hour... You'll be notified when you need to add hops.").yellow
208
212
  @com.ping("starting boil procedure")
209
- @brewer.wait(to_seconds(5))
213
+ wait(to_seconds(5))
210
214
  @com.ping("Add boil hops")
211
- @brewer.wait(to_seconds(40))
215
+ wait(to_seconds(40))
212
216
  @com.ping("Add flovering hops")
213
- @brewer.wait(to_seconds(13))
217
+ wait(to_seconds(13))
214
218
  @com.ping("Add finishing hops")
215
- @brewer.wait(30)
219
+ wait(30)
216
220
  @com.ping("Done.")
217
221
  puts Rainbow("Done.").green
218
222
  true
@@ -5,154 +5,72 @@ module Brewer
5
5
 
6
6
  attr_accessor :vars
7
7
 
8
- def initialize(brewer)
9
- @brewer = brewer
10
- @vars = Hash.new(0)
11
- make_recipe_dir
12
- end
13
-
14
- def make_recipe_dir
15
- if !Dir.exists?(recipe_dir)
16
- Dir.mkdir(recipe_dir)
17
- end
18
- true
19
- end
20
-
21
- def new_dummy
22
- @vars = dummy_recipe_vars
23
- end
8
+ def initialize(name=nil, blank: false)
9
+ @brewer = Brewer.new
24
10
 
25
- # These methods require a lot of user input. Not going to test them.
26
- # :nocov:
27
- def get_recipe_vars(vars=false)
28
- if vars
29
- raise "Vars must be a hash" unless vars.is_a? Hash
30
- @vars = vars
11
+ @vars = {}
12
+ if blank
31
13
  return true
32
14
  end
33
15
 
34
- if !list_recipes.empty?
35
- clear_screen
36
- puts "Enter a recipe name to load an existing recipe, or nothing to start a new one."
37
- puts list_as_table
38
- print "> "
39
- name = gets.chomp.strip
40
- else
41
- puts Rainbow("No available recipes").yellow
42
- name = ""
43
- end
44
-
45
- unless name.empty?
16
+ if name
46
17
  load(name)
47
18
  return true
19
+ else
20
+ get_recipe_vars
21
+ typecast_vars
48
22
  end
23
+ end
49
24
 
50
- puts Rainbow("Creating a new recipe").green
25
+ def name
26
+ return @vars['name'] if @vars['name']
27
+ end
51
28
 
52
- get_strike_temp
29
+ def load(recipe)
30
+ @vars = YAML.load(File.open(kitchen_dir(recipe) + ".yml"))
31
+ end
53
32
 
54
- print Rainbow("Enter mash temperature: ").yellow
55
- @vars['mash_temp'] = gets.chomp.to_f
56
- print Rainbow("Enter mash time in minutes: ").yellow
57
- @vars['mash_time'] = to_seconds(gets.chomp.to_f)
33
+ # :nocov:
34
+ def get_recipe_vars
35
+ puts Rainbow("Creating a new recipe").green
58
36
 
59
- print Rainbow("Enter mashout temp: ").yellow
60
- @vars['mashout_temp'] = gets.chomp.to_f
37
+ using_message("Name this recipe: ").ask_for("name")
38
+ using_message("Amount of water in quarts: ").ask_for("water")
39
+ using_message("Amount of grain in lbs: ").ask_for("grain")
40
+ using_message("Current grain temp (#{@brewer.pv.to_s} F): ").ask_for("grain_temp", default: @brewer.pv)
41
+ using_message("Desired mash temp (150 F): ").ask_for("desired_mash_temp", default: 150)
42
+ using_message("Mash temperature: ").ask_for("mash_temp")
43
+ using_message("Mash time in minutes (60): ").ask_for("mash_time", default: 60)
44
+ using_message("Mashout temp: ").ask_for("mashout_temp")
61
45
 
46
+ @vars['mash_time'] = to_seconds(@vars['mash_time'])
62
47
  true
63
48
  end
64
49
  # :nocov:
65
50
 
66
51
  # :nocov:
67
- def get_strike_temp
68
- print Rainbow("Input amount of water in quarts: ").yellow
69
- @vars['water'] = gets.chomp.to_f
70
-
71
- print Rainbow("Input amount of grain in lbs: ").yellow
72
- @vars['grain'] = gets.chomp.to_f
73
-
74
- print Rainbow("Input current grain temp (#{@brewer.pv.to_s} F): ").yellow
75
- @vars['grain_temp'] = gets.chomp.to_f
76
- if @vars['grain_temp'] == ""
77
- @vars['grain_temp'] = @brewer.pv
78
- end
79
-
80
- print Rainbow("Input desired mash temp (150 F): ").yellow
81
- @vars['desired_mash_temp'] = gets.chomp
82
- if @vars['desired_mash_temp'] == ""
83
- @vars['desired_mash_temp'] = 150
84
- end
85
- @vars['desired_mash_temp']
86
-
52
+ def calculate_strike_temp
87
53
  @vars['strike_water_temp'] = @brewer.script('get_strike_temp', "#{@vars['water']} #{@vars['grain']} #{@vars['grain_temp']} #{@vars['desired_mash_temp']}").to_f
88
54
  end
89
55
  # :nocov:
90
56
 
91
- def store(name=false)
92
- raise "Nothing to store! Please run `.get_recipe_vars` to fill in the recipe variables before storing." unless !@vars.empty?
93
-
94
- # :nocov:
95
- if @vars['name'].empty?
96
- if !name
97
- print "Please enter a name for this recipe: "
98
- @vars['name'] = gets.chomp
99
- else
100
- @vars['name'] = name
101
- end
102
- end
103
- # :nocov:
104
-
105
- store = YAML::Store.new recipe_dir(@vars['name'] + ".yml")
106
- store.transaction {
107
- store["name"] = @vars['name']
108
- @vars.each do |k, v|
109
- store[k] = v
110
- end
111
- store["created_on"] = time
112
- }
113
- true
114
- end
115
-
116
- def load(recipe)
117
- raise "Recipe does not exist" unless File.exists?(recipe_dir(recipe) + ".yml")
118
- @vars = YAML.load(File.open(recipe_dir(recipe) + ".yml"))
119
- puts "Recipe Loaded"
120
- true
121
- end
122
-
123
- def list_recipes
124
- recipes = Dir.entries(recipe_dir)
125
- recipes.delete(".")
126
- recipes.delete("..")
127
- recipes.each do |recipe|
128
- recipe.slice! ".yml"
129
- end
130
- recipes
57
+ def using_message(message)
58
+ raise "Message needs to be a string" unless message.is_a? String
59
+ print message
60
+ self
131
61
  end
132
62
 
133
- def list_as_table
134
- if list_recipes.empty?
135
- return "No Saved Recipes."
136
- end
137
- recipes_table_rows = list_recipes.each_slice(5).to_a
138
- recipes_table = Terminal::Table.new :title => "All Recipes", :rows => recipes_table_rows
139
- return recipes_table
63
+ def ask_for(var, default: nil)
64
+ @vars[var] = default
65
+ input = gets.chomp.strip
66
+ @vars[var] = input if !input.empty?
140
67
  end
141
68
 
142
- def loaded_recipe?
143
- if File.exists?(recipe_dir(@vars['name']) + ".yml")
144
- return true
69
+ def typecast_vars
70
+ @vars.each do |key, value|
71
+ # All values in @vars should be floats
72
+ @vars[key] = value.to_f if key != "name"
145
73
  end
146
- false
147
- end
148
-
149
- def clear
150
- @vars = {}
151
- end
152
-
153
- def delete_recipe_file
154
- FileUtils.rm_rf(recipe_dir + @vars['name'] + ".yml")
155
- true
156
74
  end
157
75
 
158
76
  end
@@ -4,43 +4,22 @@ module Brewer
4
4
  class Settings
5
5
 
6
6
  attr_accessor :settings
7
- attr_reader :cache_file, :source
7
+ attr_reader :cache_file, :source_file
8
8
 
9
- def initialize(testing=false)
9
+ def initialize(source_file: false, cache_file: false)
10
10
 
11
- @source = adaptibrew_dir('print_settings.py')
12
- @cache_file = brewer_dir('settings.yml')
11
+ @settings = {}
12
+ @source_file = source_file ? adaptibrew_dir(source_file) : adaptibrew_dir("print_settings.py")
13
+ @cache_file = cache_file ? brewer_dir(cache_file) : brewer_dir("settings.yml")
13
14
 
14
- @settings = Hash.new
15
-
16
- if !testing
17
- Adaptibrew.new.clone
18
-
19
- if !cache?
20
- parse_and_cache
21
- else
22
- load_cached_settings
23
- end
24
-
25
- load_global
15
+ if !cache?
16
+ parse
17
+ cache
18
+ else
19
+ load_cached_settings
26
20
  end
27
- end
28
21
 
29
- # This will create the cache and populate
30
- # it with settings from settings.py
31
- def parse_and_cache
32
- parse
33
- cache
34
- end
35
-
36
- # Loads cached settings
37
- # If no cached settings, it returns false
38
- def load_cached_settings
39
- if cache?
40
- @settings = YAML.load(File.open(@cache_file))
41
- return true
42
- end
43
- false
22
+ load_global
44
23
  end
45
24
 
46
25
  # Checks if there are settings in the cache
@@ -51,11 +30,10 @@ module Brewer
51
30
  false
52
31
  end
53
32
 
54
- # Parse the settings from @source into @settings
33
+ # Parse the settings from @source_file into @settings
55
34
  def parse
56
- settings_file_output = `python #{@source}`.chomp
57
- settings_array = settings_file_output.split("\n")
58
- settings_array.each do |setting|
35
+ settings_file_output = `python #{@source_file}`.chomp
36
+ settings_file_output.split("\n").each do |setting|
59
37
  key, value = setting.match(/(.+)=(.+)/).captures
60
38
  @settings[key.strip.chomp] = value.strip.chomp
61
39
  end
@@ -64,12 +42,27 @@ module Brewer
64
42
 
65
43
  # Creates the cache if there isn't one already
66
44
  def create_cache
67
- unless File.exists?(@cache_file)
68
- File.open(@cache_file, 'w')
69
- end
45
+ File.open(@cache_file, 'w')
70
46
  true
71
47
  end
72
48
 
49
+ # Stores the currents @settings in settings.yml
50
+ def cache
51
+ raise "Settings cache could not be created. Check permissions on ~/.brewer/" unless create_cache
52
+ store(@settings)
53
+ true
54
+ end
55
+
56
+ # Loads cached settings
57
+ # If no cached settings, it returns false
58
+ def load_cached_settings
59
+ if cache?
60
+ @settings = YAML.load(File.open(@cache_file))
61
+ return true
62
+ end
63
+ false
64
+ end
65
+
73
66
  # This will add a new element to the @settings hash
74
67
  # AND re-cache the settings
75
68
  def add(setting)
@@ -77,18 +70,6 @@ module Brewer
77
70
  setting.each do |key, value|
78
71
  @settings[key] = value
79
72
  end
80
- cache
81
- end
82
-
83
- # Stores the currents @settings in settings.yml
84
- def cache
85
- create_cache
86
- store = YAML::Store.new @cache_file
87
- store.transaction {
88
- @settings.each do |k, v|
89
- store[k] = v
90
- end
91
- }
92
73
  true
93
74
  end
94
75
 
@@ -116,6 +97,8 @@ module Brewer
116
97
  return true
117
98
  end
118
99
 
100
+ private
101
+
119
102
  # This method is r/badcode, i know
120
103
  def type_cast
121
104
  # Super janky
@@ -132,5 +115,16 @@ module Brewer
132
115
  })
133
116
  end
134
117
 
118
+ # This writes directly to the @cache_file file
119
+ def store(settings={})
120
+ raise "You must provide a hash to store" if settings.empty?
121
+ store = YAML::Store.new @cache_file
122
+ store.transaction {
123
+ settings.each do |setting, value|
124
+ store[setting] = value
125
+ end
126
+ }
127
+ end
128
+
135
129
  end
136
130
  end
@@ -12,7 +12,6 @@ module Brewer
12
12
  @slack = configure_slack(webhook)
13
13
  end
14
14
 
15
- # This will look for a webhook in settings.yml and ask you for one if it doesn't find one
16
15
  def configure_slack(webhook)
17
16
  if webhook
18
17
  return Slack::Notifier.new webhook
@@ -33,21 +32,20 @@ module Brewer
33
32
  webhook_url
34
33
  end
35
34
 
36
- # This sends a message in slack.
37
- # If an array is passed in, it will send it as one message with
38
- # new lines between each array item
39
- def ping(message="ping at #{Time.now}")
40
- @slack.ping(message)
35
+ def ping(message="Ping as #{Time.now}")
36
+ if message.is_a? Array
37
+ @slack.ping(message.join("\n"))
38
+ else
39
+ @slack.ping(message)
40
+ end
41
41
  end
42
42
 
43
- # This does the same thing as Brewer#monitor, but it also sends a slack message
44
- # after a specified wait, normally 10 minutes
45
43
  def monitor(delay=10)
46
44
  while true do
47
45
  table = @brewer.status_table
48
46
 
49
47
  before_temp = @brewer.pv
50
- @brewer.wait(to_seconds(delay))
48
+ wait(to_seconds(delay))
51
49
  diff = @brewer.pv - before_temp
52
50
 
53
51
  clear_screen
@@ -58,7 +56,7 @@ module Brewer
58
56
  "Set Value Temperature: #{@brewer.pid['sv_temp']} F",
59
57
  "Current temperature has climed #{diff} F since #{delay} minute(s) ago",
60
58
  "Sent at #{Time.now.strftime("%H:%M")}"
61
- ].join("\n"))
59
+ ])
62
60
  end
63
61
  true
64
62
  end
@@ -6,7 +6,7 @@ describe Brewer::Adaptibrew do
6
6
 
7
7
  before :each do
8
8
  @adaptibrew = Adaptibrew.new
9
- @adaptibrew.refresh
9
+ @adaptibrew.clone
10
10
  end
11
11
 
12
12
  after :all do
@@ -17,20 +17,11 @@ describe Brewer::Adaptibrew do
17
17
  it "makes a new Adaptibrew object" do
18
18
  expect(Adaptibrew.new).to be_an_instance_of Adaptibrew
19
19
  end
20
-
21
- context "when the adaptibrew and brewer directories dont exist" do
22
- before { FileUtils.rm_rf(brewer_dir) }
23
- it "creates them" do
24
- a = Adaptibrew.new
25
- expect(Dir.exists?(brewer_dir)).to be true
26
- expect(Dir.exists?(adaptibrew_dir)).to be true
27
- end
28
- end
29
20
  end
30
21
 
31
22
  describe ".clear" do
32
23
  context "when the repo exists" do
33
- before { @adaptibrew.clone }
24
+ before { @adaptibrew.clone }
34
25
  specify { expect(@adaptibrew.present?).to be true }
35
26
  it "deletes the repo and returns true" do
36
27
  expect(@adaptibrew.clear).to be true
@@ -25,7 +25,7 @@ describe Brewer do
25
25
  # not using let(:current_time) etc. because
26
26
  # the var is created upon the first calling, which is in the expect()
27
27
  current_time = Time.now.to_i
28
- @brewer.wait(1)
28
+ wait(1)
29
29
  expect(current_time + 1).to eq(Time.now.to_i)
30
30
  end
31
31
  end
@@ -33,6 +33,12 @@ describe "Helpers" do
33
33
  end
34
34
  end
35
35
 
36
+ describe ".kitchen_dir" do
37
+ it "returns the path to the recipe storage dir" do
38
+ expect(kitchen_dir).to eq(Dir.home + "/.brewer/kitchen/")
39
+ end
40
+ end
41
+
36
42
  describe ".adaptibrew_dir" do
37
43
  it "returns the .adaptibrew directory" do
38
44
  expect(adaptibrew_dir).to eq(Dir.home + "/.brewer/adaptibrew/")
@@ -51,12 +57,6 @@ describe "Helpers" do
51
57
  end
52
58
  end
53
59
 
54
- describe ".recipe_dir" do
55
- it "returns the path to the recipe storage dir" do
56
- expect(recipe_dir).to eq(Dir.home + "/.brewer/recipes/")
57
- end
58
- end
59
-
60
60
  describe ".dummy_recipe_vars" do
61
61
  it "returns a hash of dummy recipe vars" do
62
62
  dummy = dummy_recipe_vars
@@ -0,0 +1,173 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Kitchen do
4
+ before :each do
5
+ @kitchen = Brewer::Kitchen.new
6
+ end
7
+
8
+ describe "#new" do
9
+ it "returns a kitchen object" do
10
+ expect(Brewer::Kitchen.new).to be_an_instance_of Brewer::Kitchen
11
+ end
12
+ end
13
+
14
+ describe ".present?" do
15
+ context "when the kitchen is there" do
16
+ before { @kitchen.clone }
17
+ it "returns true" do
18
+ expect(@kitchen.present?).to be true
19
+ end
20
+ end
21
+
22
+ context "when the kitchen is not there" do
23
+ before { @kitchen.clear }
24
+ it "returns false" do
25
+ expect(@kitchen.present?).to be false
26
+ end
27
+ end
28
+ end
29
+
30
+ describe ".clone" do
31
+ context "when the kitchen is not there" do
32
+ before { @kitchen.clear }
33
+ specify { expect(@kitchen.present?).to be false }
34
+ it "clones it" do
35
+ @kitchen.clone
36
+ expect(@kitchen.present?).to be true
37
+ end
38
+ end
39
+
40
+ context "when the kitchen is there" do
41
+ before { @kitchen.clone }
42
+ specify { expect(@kitchen.present?).to be true }
43
+ it "does nothing" do
44
+ expect(@kitchen.clone).to be false
45
+ expect(@kitchen.present?).to be true
46
+ end
47
+ end
48
+ end
49
+
50
+ describe ".clone" do
51
+ context "when the kitchen is there" do
52
+ before { @kitchen.clone }
53
+ specify { expect(@kitchen.present?).to be true }
54
+ it "returns false" do
55
+ expect(@kitchen.clone).to be false
56
+ expect(@kitchen.present?).to be true
57
+ end
58
+ end
59
+
60
+ context "when the kitchen is not there" do
61
+ before { @kitchen.clear }
62
+ specify{ expect(@kitchen.present?).to be false }
63
+ it "clones the kitchen and returns true" do
64
+ expect(@kitchen.clone).to be true
65
+ expect(@kitchen.present?).to be true
66
+ end
67
+ end
68
+ end
69
+
70
+ describe ".list_recipes" do
71
+ it "returns an array of recipes" do
72
+ expect(@kitchen.list_recipes).to be_an_instance_of Array
73
+ end
74
+ end
75
+
76
+ describe ".list_recipes_as_table" do
77
+ context "when the recipe list is empty" do
78
+ before {
79
+ @kitchen.clear
80
+ # Need an empty directory
81
+ Dir.mkdir(kitchen_dir)
82
+ }
83
+ it "returns a message" do
84
+ capture_stdout { expect(@kitchen.list_recipes_as_table).to eq("No Saved Recipes") }
85
+ end
86
+ end
87
+
88
+ context "when the recipe list is not empty" do
89
+ before { @kitchen.refresh }
90
+ it "returns a TerminalTable of the recipes" do
91
+ capture_stdout { expect(@kitchen.list_recipes_as_table).to be_an_instance_of Terminal::Table }
92
+ end
93
+ end
94
+ end
95
+
96
+ describe ".refresh" do
97
+ before { @kitchen.clone }
98
+ it "clears and clones the repo" do
99
+ expect(@kitchen.present?).to be true
100
+ expect(@kitchen.refresh).to be true
101
+ expect(@kitchen.present?).to be true
102
+ end
103
+ end
104
+
105
+ describe ".load" do
106
+ before { @kitchen.clone }
107
+ specify { expect(@kitchen.recipe_exists?("dummy_recipe")).to be true }
108
+ it "loads a recipe into the @recipe variable" do
109
+ expect(@kitchen.load("dummy_recipe")).to be true
110
+ expect(@kitchen.recipe).to be_an_instance_of Recipe
111
+ end
112
+ end
113
+
114
+ describe ".store" do
115
+ context "when a recipe is loaded" do
116
+ before {
117
+ @kitchen.recipe = Recipe.new(blank: true)
118
+ @kitchen.recipe.vars['name'] = "test_recipe"
119
+ }
120
+ it "stores the recipe" do
121
+ expect(@kitchen.store).to be true
122
+ end
123
+ end
124
+ end
125
+
126
+ describe ".recipe_exists?" do
127
+ context "when the recipe exists" do
128
+ before {
129
+ @kitchen.recipe = Brewer::Recipe.new(blank: true)
130
+ @kitchen.recipe.vars['name'] = "test_recipe"
131
+ @kitchen.store
132
+ }
133
+ it "returns true" do
134
+ expect(@kitchen.recipe_exists?("test_recipe")).to be true
135
+ end
136
+ end
137
+
138
+ context "when the recipe does not exist" do
139
+ it "returns false" do
140
+ expect(@kitchen.recipe_exists?("doesnt_exist")).to be false
141
+ end
142
+ end
143
+ end
144
+
145
+ describe ".loaded_recipe?" do
146
+ context "when there is a loaded recipe" do
147
+ before {
148
+ @kitchen.recipe = Brewer::Recipe.new(blank: true)
149
+ @kitchen.recipe.vars = dummy_recipe_vars
150
+ }
151
+ it "returns true" do
152
+ expect(@kitchen.load("dummy_recipe")).to be true
153
+ expect(@kitchen.loaded_recipe?).to be true
154
+ end
155
+ end
156
+
157
+ context "when there is not loaded recipe" do
158
+ before { @kitchen.recipe = nil }
159
+ it "returns false" do
160
+ expect(@kitchen.loaded_recipe?).to be false
161
+ end
162
+ end
163
+ end
164
+
165
+ describe ".delete_recipe" do
166
+ it "deletes a recipe" do
167
+ expect(@kitchen.recipe_exists?("dummy_recipe")).to be true
168
+ expect(@kitchen.delete_recipe("dummy_recipe")).to be true
169
+ expect(@kitchen.recipe_exists?("dummy_recipe")).to be false
170
+ end
171
+ end
172
+
173
+ end
@@ -1,100 +1,19 @@
1
1
  require_relative "spec_helper"
2
- require 'fileutils'
3
2
 
4
- include Helpers
5
-
6
- describe Recipe do
3
+ describe Brewer::Recipe do
7
4
  before :each do
8
- @brewer = Brewer::Brewer.new
9
- @recipe = Brewer::Recipe.new(@brewer)
10
- @recipe.new_dummy
11
- @recipe.store
5
+ @kitchen = Brewer::Kitchen.new
6
+ @kitchen.recipe.vars = dummy_recipe_vars
7
+ @kitchen.store
8
+ @recipe = Brewer::Recipe.new("dummy_recipe")
12
9
  end
13
10
 
14
11
  describe "#new" do
15
12
  it "returns a new recipe object" do
16
- expect(Brewer::Recipe.new(@brewer)).to be_an_instance_of Brewer::Recipe
17
- end
18
- end
19
-
20
- describe ".new_dummy" do
21
- before { @recipe.clear }
22
- it "returns a new dummy recipe" do
23
- expect(@recipe.vars).to be_empty
24
- @recipe.new_dummy
25
- expect(@recipe.vars).not_to be_empty
26
- expect(@recipe.vars['name']).to eq("dummy_recipe")
27
- end
28
- end
29
-
30
- describe ".make_recipe_dir" do
31
- before { FileUtils.rm_rf(recipe_dir) }
32
- specify { !Dir.exists?(recipe_dir) }
33
- it "makes the recipe storage directory" do
34
- expect(@recipe.make_recipe_dir).to be true
35
- end
36
- specify { Dir.exists?(recipe_dir) }
37
- end
38
-
39
- describe ".store" do
40
- context "when there is a loaded recipe" do
41
- before { @recipe.delete_recipe_file }
42
- it "stores the loaded recipe" do
43
- expect(@recipe.loaded_recipe?).to be false
44
- @recipe.store
45
- expect(@recipe.loaded_recipe?).to be true
46
- end
47
- end
48
-
49
- context "when there is no loaded recipe" do
50
- before { @recipe.clear }
51
- specify { expect(@recipe.vars).to be_empty }
52
- it "raises an exception" do
53
- expect { @recipe.store }.to raise_error(/store/)
54
- end
13
+ expect(Brewer::Recipe.new(blank: true)).to be_an_instance_of Brewer::Recipe
14
+ expect(Brewer::Recipe.new("dummy_recipe")).to be_an_instance_of Brewer::Recipe
55
15
  end
56
16
  end
57
17
 
58
- describe ".load" do
59
- context "when the recipe exists" do
60
- before { @recipe.clear }
61
- it "loads the recipe" do
62
- capture_stdout { expect(@recipe.load("dummy_recipe")).to be true }
63
- expect(@recipe.loaded_recipe?).to be true
64
- end
65
- end
66
-
67
- context "when the recipe does not exist" do
68
- it "raises an error" do
69
- expect { @recipe.load("not_a_real_recipe") }.to raise_error(/does not exist/)
70
- end
71
- end
72
- end
73
-
74
- describe ".list_recipes" do
75
- it "returns an array of recipes" do
76
- expect(@recipe.list_recipes).to be_an_instance_of Array
77
- expect(@recipe.list_recipes).not_to be_empty
78
- end
79
- end
80
-
81
- describe ".list_as_table" do
82
- context "when there are no recipes" do
83
- before { FileUtils.rm_rf(Dir.glob(recipe_dir("*"))) }
84
- it "returns without a table" do
85
- expect(@recipe.list_as_table).to eq("No Saved Recipes.")
86
- end
87
- end
88
-
89
- context "when there are recipes" do
90
- before {
91
- @recipe.new_dummy
92
- @recipe.store
93
- }
94
- it "returns a TerminalTable" do
95
- expect(@recipe.list_as_table).to be_an_instance_of Terminal::Table
96
- end
97
- end
98
- end
99
18
 
100
19
  end
@@ -5,13 +5,14 @@ describe Settings do
5
5
 
6
6
  before :all do
7
7
  @adaptibrew = Adaptibrew.new.clone
8
- @settings = Settings.new(true)
8
+ @settings = Settings.new(cache_file: "test_settings.yml")
9
9
  end
10
10
 
11
11
  describe ".load_cached_settings" do
12
12
  context "when there are cached settings" do
13
13
  before {
14
- @settings.parse_and_cache
14
+ @settings.parse
15
+ @settings.cache
15
16
  @settings.settings = {}
16
17
  }
17
18
 
@@ -35,7 +36,8 @@ describe Settings do
35
36
  describe ".cache?" do
36
37
  context "when the cache exists" do
37
38
  before {
38
- @settings.parse_and_cache
39
+ @settings.parse
40
+ @settings.cache
39
41
  }
40
42
  it "returns true" do
41
43
  expect(@settings.cache?).to be true
@@ -62,7 +64,10 @@ describe Settings do
62
64
 
63
65
  describe ".create_cache" do
64
66
  context "when the cache exists" do
65
- before { @settings.parse_and_cache }
67
+ before {
68
+ @settings.parse
69
+ @settings.cache
70
+ }
66
71
 
67
72
  specify { expect(@settings.cache?).to be true }
68
73
  it "returns true" do
@@ -82,7 +87,7 @@ describe Settings do
82
87
  end
83
88
 
84
89
  describe ".add" do
85
- before { @settings = Settings.new }
90
+ before { @settings = Settings.new(cache_file: "test_settings.yml") }
86
91
  specify { expect(@settings.settings['test_key']).to be nil }
87
92
  it "adds a new setting to the cache" do
88
93
  @settings.add({'test_key' => 'test_value'})
@@ -102,7 +107,10 @@ describe Settings do
102
107
  end
103
108
 
104
109
  describe ".clear_cache" do
105
- before { @settings.parse_and_cache}
110
+ before {
111
+ @settings.parse
112
+ @settings.cache
113
+ }
106
114
 
107
115
  specify { expect(@settings.cache?).to be true }
108
116
  it "deletes the cache file" do
@@ -119,7 +127,10 @@ describe Settings do
119
127
  end
120
128
 
121
129
  describe ".change" do
122
- before { @settings.parse_and_cache }
130
+ before {
131
+ @settings.parse
132
+ @settings.cache
133
+ }
123
134
 
124
135
  specify { expect(@settings.settings['DEBUG'].to_b).to be false}
125
136
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brewer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.97
4
+ version: 0.0.98
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Sweeney
@@ -251,6 +251,7 @@ files:
251
251
  - lib/brewer/adaptibrew.rb
252
252
  - lib/brewer/brewer.rb
253
253
  - lib/brewer/helpers.rb
254
+ - lib/brewer/kitchen.rb
254
255
  - lib/brewer/procedures.rb
255
256
  - lib/brewer/recipe.rb
256
257
  - lib/brewer/settings.rb
@@ -260,6 +261,7 @@ files:
260
261
  - spec/brewer_spec.rb
261
262
  - spec/hardware_spec.rb
262
263
  - spec/helpers_spec.rb
264
+ - spec/kitchen_spec.rb
263
265
  - spec/recipe_spec.rb
264
266
  - spec/settings_spec.rb
265
267
  - spec/spec_helper.rb
@@ -293,6 +295,7 @@ test_files:
293
295
  - spec/brewer_spec.rb
294
296
  - spec/hardware_spec.rb
295
297
  - spec/helpers_spec.rb
298
+ - spec/kitchen_spec.rb
296
299
  - spec/recipe_spec.rb
297
300
  - spec/settings_spec.rb
298
301
  - spec/spec_helper.rb