brewer 0.0.97 → 0.0.98

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: 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