cryptum 0.0.230
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 +7 -0
- data/.github/workflows/main.yml +16 -0
- data/.gitignore +30 -0
- data/.rspec +3 -0
- data/.rspec_status +0 -0
- data/.rubocop.yml +5 -0
- data/.rubocop_todo.yml +250 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +36 -0
- data/LICENSE +674 -0
- data/README.md +72 -0
- data/Rakefile +19 -0
- data/bin/cryptum +72 -0
- data/bin/cryptum-forecast +199 -0
- data/bin/cryptum-repl +73 -0
- data/bin/cryptum_autoinc_version +38 -0
- data/build_cryptum_gem.sh +52 -0
- data/cryptum.gemspec +50 -0
- data/cryptum_container.sh +1 -0
- data/docker/cryptum.json +60 -0
- data/docker/cryptum_container.sh +59 -0
- data/docker/packer_secrets.json.EXAMPLE +7 -0
- data/docker/provisioners/cryptum.sh +11 -0
- data/docker/provisioners/docker_bashrc.sh +2 -0
- data/docker/provisioners/docker_rvm.sh +22 -0
- data/docker/provisioners/init_image.sh +28 -0
- data/docker/provisioners/post_install.sh +6 -0
- data/docker/provisioners/ruby.sh +16 -0
- data/docker/provisioners/upload_globals.sh +49 -0
- data/etc/bot_confs/.gitkeep +0 -0
- data/etc/bot_confs/BOT_CONF.TEMPLATE +10 -0
- data/etc/coinbase_pro.yaml.EXAMPLE +8 -0
- data/git_commit.sh +22 -0
- data/lib/cryptum/api.rb +693 -0
- data/lib/cryptum/bot_conf.rb +76 -0
- data/lib/cryptum/event/buy.rb +144 -0
- data/lib/cryptum/event/cancel.rb +49 -0
- data/lib/cryptum/event/history.rb +64 -0
- data/lib/cryptum/event/key_press.rb +64 -0
- data/lib/cryptum/event/sell.rb +120 -0
- data/lib/cryptum/event.rb +168 -0
- data/lib/cryptum/log.rb +34 -0
- data/lib/cryptum/matrix.rb +181 -0
- data/lib/cryptum/option/choice.rb +26 -0
- data/lib/cryptum/option.rb +161 -0
- data/lib/cryptum/order_book/generate.rb +111 -0
- data/lib/cryptum/order_book/indicator.rb +16 -0
- data/lib/cryptum/order_book/market_trend.rb +161 -0
- data/lib/cryptum/order_book/profit_margin.rb +55 -0
- data/lib/cryptum/order_book/weighted_avg.rb +157 -0
- data/lib/cryptum/order_book.rb +156 -0
- data/lib/cryptum/portfolio/balance.rb +123 -0
- data/lib/cryptum/portfolio.rb +15 -0
- data/lib/cryptum/ui/command.rb +274 -0
- data/lib/cryptum/ui/key_press_event.rb +22 -0
- data/lib/cryptum/ui/market_trend.rb +117 -0
- data/lib/cryptum/ui/order_execution.rb +478 -0
- data/lib/cryptum/ui/order_plan.rb +376 -0
- data/lib/cryptum/ui/order_timer.rb +119 -0
- data/lib/cryptum/ui/portfolio.rb +231 -0
- data/lib/cryptum/ui/signal_engine.rb +122 -0
- data/lib/cryptum/ui/terminal_window.rb +95 -0
- data/lib/cryptum/ui/ticker.rb +317 -0
- data/lib/cryptum/ui.rb +306 -0
- data/lib/cryptum/version.rb +5 -0
- data/lib/cryptum/web_sock/coinbase.rb +94 -0
- data/lib/cryptum/web_sock/event_machine.rb +182 -0
- data/lib/cryptum/web_sock.rb +16 -0
- data/lib/cryptum.rb +183 -0
- data/order_books/.gitkeep +0 -0
- data/reinstall_cryptum_gemset.sh +29 -0
- data/spec/lib/cryptum/api_spec.rb +10 -0
- data/spec/lib/cryptum/event_spec.rb +10 -0
- data/spec/lib/cryptum/log_spec.rb +10 -0
- data/spec/lib/cryptum/option_spec.rb +10 -0
- data/spec/lib/cryptum/order_book/generate_spec.rb +10 -0
- data/spec/lib/cryptum/order_book/market_trend_spec.rb +10 -0
- data/spec/lib/cryptum/order_book_spec.rb +10 -0
- data/spec/lib/cryptum/ui/command_spec.rb +10 -0
- data/spec/lib/cryptum/ui/ticker_spec.rb +10 -0
- data/spec/lib/cryptum/ui_spec.rb +10 -0
- data/spec/lib/cryptum/web_sock_spec.rb +10 -0
- data/spec/lib/cryptum_spec.rb +10 -0
- data/spec/spec_helper.rb +3 -0
- data/upgrade_Gemfile_gems.sh +20 -0
- data/upgrade_cryptum.sh +13 -0
- data/upgrade_gem.sh +4 -0
- data/upgrade_ruby.sh +46 -0
- metadata +472 -0
@@ -0,0 +1,317 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module Cryptum
|
6
|
+
# This plugin is used to Refresh the Cryptum console UI
|
7
|
+
module UI
|
8
|
+
module Ticker
|
9
|
+
public_class_method def self.refresh(opts = {})
|
10
|
+
option_choice = opts[:option_choice]
|
11
|
+
start_time = opts[:start_time]
|
12
|
+
ticker_win = opts[:ticker_win]
|
13
|
+
key_press_event = opts[:key_press_event]
|
14
|
+
order_book = opts[:order_book]
|
15
|
+
event = opts[:event]
|
16
|
+
|
17
|
+
this_product = order_book[:this_product]
|
18
|
+
quote_increment = this_product[:quote_increment]
|
19
|
+
fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
|
20
|
+
|
21
|
+
symbol_out = "#{this_product[:id]}.#{option_choice.market_trend_reset}s"
|
22
|
+
fiat = this_product[:quote_currency].to_sym
|
23
|
+
fiat_symbol = '?'
|
24
|
+
fiat_symbol = '$' if fiat == :USD
|
25
|
+
fiat_symbol = "\u20ac" if fiat == :EUR
|
26
|
+
|
27
|
+
last_ticker_price = order_book[:ticker_price].to_f
|
28
|
+
second_to_last_ticker_price = order_book[:ticker_price_second_to_last].to_f
|
29
|
+
|
30
|
+
sequence = event[:sequence].to_i
|
31
|
+
last_sequence = order_book[:sequence].to_i
|
32
|
+
|
33
|
+
raise "ERROR: Sequence Order Mismatch - #{last_sequence} #{sequence}" unless sequence >= last_sequence
|
34
|
+
|
35
|
+
order_book[:sequence] = sequence
|
36
|
+
open_24h = event[:open_24h].to_f
|
37
|
+
order_book[:open_24h] = open_24h
|
38
|
+
|
39
|
+
open_24h_out = "#{Cryptum.open_symbol} #{fiat_symbol}#{format("%0.#{fiat_smallest_decimal}f", open_24h)}"
|
40
|
+
|
41
|
+
beautify_ticker = Cryptum.beautify_large_number(
|
42
|
+
value: format("%0.#{fiat_smallest_decimal}f", event[:price].to_f)
|
43
|
+
)
|
44
|
+
ticker_fmt = "#{fiat_symbol}#{beautify_ticker}"
|
45
|
+
if last_ticker_price.zero?
|
46
|
+
ticker_price_color = :white
|
47
|
+
ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}"
|
48
|
+
elsif last_ticker_price < event[:price].to_f
|
49
|
+
ticker_price_color = :green
|
50
|
+
ticker_price_out = "#{Cryptum.up_arrow} #{ticker_fmt}"
|
51
|
+
elsif last_ticker_price > event[:price].to_f
|
52
|
+
ticker_price_color = :red
|
53
|
+
ticker_price_out = "#{Cryptum.down_arrow} #{ticker_fmt}"
|
54
|
+
else
|
55
|
+
ticker_price_color = :yellow
|
56
|
+
ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}"
|
57
|
+
end
|
58
|
+
|
59
|
+
order_book[:ticker_price_third_to_last] = format("%0.#{fiat_smallest_decimal}f", second_to_last_ticker_price)
|
60
|
+
order_book[:ticker_price_second_to_last] = format("%0.#{fiat_smallest_decimal}f", last_ticker_price)
|
61
|
+
order_book[:ticker_price] = format("%0.#{fiat_smallest_decimal}f", event[:price].to_f)
|
62
|
+
|
63
|
+
volume_24h = format('%0.7f', event[:volume_24h])
|
64
|
+
volume_24h_out = Cryptum.beautify_large_number(
|
65
|
+
value: volume_24h
|
66
|
+
)
|
67
|
+
order_book[:volume_24h] = volume_24h
|
68
|
+
|
69
|
+
volume_30d = format('%0.7f', event[:volume_30d])
|
70
|
+
volume_30d_out = Cryptum.beautify_large_number(
|
71
|
+
value: volume_30d
|
72
|
+
)
|
73
|
+
|
74
|
+
# TODO: Potential for RACE CONDITIONS - MIGRATE TO
|
75
|
+
# Cryptum::Event.parse
|
76
|
+
# Indicate if 24 Hour High is Reached During Sesssion
|
77
|
+
high_24h = format(
|
78
|
+
"%0.#{fiat_smallest_decimal}f",
|
79
|
+
event[:high_24h]
|
80
|
+
)
|
81
|
+
high_24h_out = Cryptum.beautify_large_number(
|
82
|
+
value: high_24h
|
83
|
+
)
|
84
|
+
order_book[:high_24h] = high_24h
|
85
|
+
|
86
|
+
low_24h = format(
|
87
|
+
"%0.#{fiat_smallest_decimal}f",
|
88
|
+
event[:low_24h]
|
89
|
+
)
|
90
|
+
low_24h_out = Cryptum.beautify_large_number(
|
91
|
+
value: low_24h
|
92
|
+
)
|
93
|
+
order_book[:low_24h] = low_24h
|
94
|
+
margin_percent_open_24h = (1 - (open_24h / order_book[:ticker_price].to_f)) * 100
|
95
|
+
|
96
|
+
beautify_margin_percent_open_24h = Cryptum.beautify_large_number(
|
97
|
+
value: format('%0.4f', margin_percent_open_24h)
|
98
|
+
)
|
99
|
+
if margin_percent_open_24h.positive?
|
100
|
+
margin_percent_open_24h_color = :green
|
101
|
+
margin_percent_open_24h_out = "#{Cryptum.up_arrow} #{beautify_margin_percent_open_24h}%"
|
102
|
+
elsif margin_percent_open_24h.negative?
|
103
|
+
# Space removed to account for negative number.
|
104
|
+
margin_percent_open_24h_color = :red
|
105
|
+
margin_percent_open_24h_out = "#{Cryptum.down_arrow}#{beautify_margin_percent_open_24h}%"
|
106
|
+
else
|
107
|
+
margin_percent_open_24h_color = :yellow
|
108
|
+
margin_percent_open_24h_out = "#{Cryptum.flat_arrow} #{beautify_margin_percent_open_24h}%"
|
109
|
+
end
|
110
|
+
|
111
|
+
current_time_out = Time.now.strftime('%Y-%m-%d %H:%M:%S%z')
|
112
|
+
|
113
|
+
order_history = order_book[:order_history]
|
114
|
+
open_sell_orders = order_history.select do |order|
|
115
|
+
order[:status] == 'open' &&
|
116
|
+
order[:side] == 'sell'
|
117
|
+
end
|
118
|
+
|
119
|
+
sorted_open_sell_orders = open_sell_orders.sort_by do |order|
|
120
|
+
order[:price].to_f
|
121
|
+
end
|
122
|
+
|
123
|
+
lowest_selling_price = '0.00'
|
124
|
+
highest_selling_price = '0.00'
|
125
|
+
lowest_selling_price = sorted_open_sell_orders.first[:price] unless sorted_open_sell_orders.empty?
|
126
|
+
highest_selling_price = sorted_open_sell_orders.last[:price] unless sorted_open_sell_orders.empty?
|
127
|
+
lowest_selling_price_out = Cryptum.beautify_large_number(
|
128
|
+
value: format(
|
129
|
+
"%0.#{fiat_smallest_decimal}f",
|
130
|
+
lowest_selling_price
|
131
|
+
)
|
132
|
+
)
|
133
|
+
|
134
|
+
highest_selling_price_out = Cryptum.beautify_large_number(
|
135
|
+
value: format(
|
136
|
+
"%0.#{fiat_smallest_decimal}f",
|
137
|
+
highest_selling_price
|
138
|
+
)
|
139
|
+
)
|
140
|
+
# TODO: Everything Above this Line Needs to be Indicators ^
|
141
|
+
|
142
|
+
# UI
|
143
|
+
col_just1 = 15
|
144
|
+
col_just2 = 14
|
145
|
+
col_just3 = 21
|
146
|
+
col_just3_alt = (Curses.cols - Cryptum::UI.col_third) - 1
|
147
|
+
col_just4 = (Curses.cols - Cryptum::UI.col_fourth) - 1
|
148
|
+
|
149
|
+
Cryptum::UI.detect_key_press_in_ui(
|
150
|
+
key_press_event: key_press_event,
|
151
|
+
ui_win: ticker_win
|
152
|
+
)
|
153
|
+
|
154
|
+
# ROW 1
|
155
|
+
out_line_no = 0
|
156
|
+
Cryptum::UI.line(
|
157
|
+
ui_win: ticker_win,
|
158
|
+
out_line_no: out_line_no
|
159
|
+
)
|
160
|
+
|
161
|
+
out_line_no += 1
|
162
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
163
|
+
ticker_win.clrtoeol
|
164
|
+
if Curses.can_change_color?
|
165
|
+
Cryptum::UI.colorize(
|
166
|
+
ui_win: ticker_win,
|
167
|
+
color: :rainbow,
|
168
|
+
style: :bold,
|
169
|
+
string: symbol_out.ljust(col_just1)
|
170
|
+
)
|
171
|
+
else
|
172
|
+
Cryptum::UI.colorize(
|
173
|
+
ui_win: ticker_win,
|
174
|
+
color: :yellow,
|
175
|
+
style: :bold,
|
176
|
+
string: symbol_out.ljust(col_just1)
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_second)
|
181
|
+
Cryptum::UI.colorize(
|
182
|
+
ui_win: ticker_win,
|
183
|
+
color: margin_percent_open_24h_color,
|
184
|
+
style: :bold,
|
185
|
+
string: margin_percent_open_24h_out.ljust(col_just2)
|
186
|
+
)
|
187
|
+
|
188
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
189
|
+
Cryptum::UI.colorize(
|
190
|
+
ui_win: ticker_win,
|
191
|
+
color: :blue,
|
192
|
+
style: :bold,
|
193
|
+
string: open_24h_out.ljust(col_just3)
|
194
|
+
)
|
195
|
+
|
196
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_fourth)
|
197
|
+
Cryptum::UI.colorize(
|
198
|
+
ui_win: ticker_win,
|
199
|
+
color: ticker_price_color,
|
200
|
+
style: :bold,
|
201
|
+
string: ticker_price_out.rjust(col_just4)
|
202
|
+
)
|
203
|
+
|
204
|
+
# ROW 2
|
205
|
+
out_line_no += 1
|
206
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
207
|
+
ticker_win.clrtoeol
|
208
|
+
Cryptum::UI.colorize(
|
209
|
+
ui_win: ticker_win,
|
210
|
+
color: :white,
|
211
|
+
style: :bold,
|
212
|
+
string: 'Highest | Lowest Sell Price:'
|
213
|
+
)
|
214
|
+
|
215
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
216
|
+
Cryptum::UI.colorize(
|
217
|
+
ui_win: ticker_win,
|
218
|
+
color: :white,
|
219
|
+
style: :bold,
|
220
|
+
string: "$#{highest_selling_price_out} | $#{lowest_selling_price_out}".rjust(
|
221
|
+
col_just3_alt,
|
222
|
+
'.'
|
223
|
+
)
|
224
|
+
)
|
225
|
+
|
226
|
+
# ROW 2
|
227
|
+
out_line_no += 1
|
228
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
229
|
+
ticker_win.clrtoeol
|
230
|
+
Cryptum::UI.colorize(
|
231
|
+
ui_win: ticker_win,
|
232
|
+
color: :green,
|
233
|
+
style: :bold,
|
234
|
+
string: '24 Hr High:'
|
235
|
+
)
|
236
|
+
|
237
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
238
|
+
Cryptum::UI.colorize(
|
239
|
+
ui_win: ticker_win,
|
240
|
+
color: :green,
|
241
|
+
string: "#{Cryptum.up_arrow} #{fiat_symbol}#{high_24h_out}".rjust(col_just3_alt, '.')
|
242
|
+
)
|
243
|
+
|
244
|
+
# ROW 3
|
245
|
+
out_line_no += 1
|
246
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
247
|
+
ticker_win.clrtoeol
|
248
|
+
Cryptum::UI.colorize(
|
249
|
+
ui_win: ticker_win,
|
250
|
+
color: :red,
|
251
|
+
string: '24 Hr Low:'
|
252
|
+
)
|
253
|
+
|
254
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
255
|
+
Cryptum::UI.colorize(
|
256
|
+
ui_win: ticker_win,
|
257
|
+
color: :red,
|
258
|
+
string: "#{Cryptum.down_arrow} #{fiat_symbol}#{low_24h_out}".rjust(col_just3_alt, '.')
|
259
|
+
)
|
260
|
+
|
261
|
+
# ROW 4
|
262
|
+
out_line_no += 1
|
263
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
264
|
+
ticker_win.clrtoeol
|
265
|
+
Cryptum::UI.colorize(
|
266
|
+
ui_win: ticker_win,
|
267
|
+
color: :blue,
|
268
|
+
style: :bold,
|
269
|
+
string: '24 Hr | 30 Day Market Volume:'
|
270
|
+
)
|
271
|
+
|
272
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
273
|
+
Cryptum::UI.colorize(
|
274
|
+
ui_win: ticker_win,
|
275
|
+
color: :blue,
|
276
|
+
string: "#{volume_24h_out} | #{volume_30d_out}".rjust(col_just3_alt, '.')
|
277
|
+
)
|
278
|
+
|
279
|
+
# ROW 5
|
280
|
+
out_line_no += 1
|
281
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
|
282
|
+
ticker_win.clrtoeol
|
283
|
+
Cryptum::UI.colorize(
|
284
|
+
ui_win: ticker_win,
|
285
|
+
color: :cyan,
|
286
|
+
style: :bold,
|
287
|
+
string: 'Start Time:'
|
288
|
+
)
|
289
|
+
|
290
|
+
ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
|
291
|
+
Cryptum::UI.colorize(
|
292
|
+
ui_win: ticker_win,
|
293
|
+
color: :cyan,
|
294
|
+
string: start_time.rjust(col_just3_alt, '.')
|
295
|
+
)
|
296
|
+
|
297
|
+
ticker_win.refresh
|
298
|
+
rescue Interrupt
|
299
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
300
|
+
Cryptum.exit_gracefully(which_self: self)
|
301
|
+
rescue StandardError => e
|
302
|
+
raise e
|
303
|
+
end
|
304
|
+
|
305
|
+
# Display Usage for this Module
|
306
|
+
public_class_method def self.help
|
307
|
+
puts "USAGE:
|
308
|
+
#{self}.refresh(
|
309
|
+
symbol: 'required - Symbol for this Session (e.g. btc-usd)',
|
310
|
+
order_book: 'required - Order Book Data Structure',
|
311
|
+
event: 'required - Event from Coinbase Web Socket'
|
312
|
+
)
|
313
|
+
"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
data/lib/cryptum/ui.rb
ADDED
@@ -0,0 +1,306 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'curses'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module Cryptum
|
7
|
+
# Cryptum::UI Module used for Presenting the
|
8
|
+
# Cryptum Curses Interface
|
9
|
+
module UI
|
10
|
+
autoload :KeyPressEvent, 'cryptum/ui/key_press_event'
|
11
|
+
autoload :TerminalWindow, 'cryptum/ui/terminal_window'
|
12
|
+
autoload :Ticker, 'cryptum/ui/ticker'
|
13
|
+
autoload :Portfolio, 'cryptum/ui/portfolio'
|
14
|
+
autoload :OrderPlan, 'cryptum/ui/order_plan'
|
15
|
+
autoload :OrderTimer, 'cryptum/ui/order_timer'
|
16
|
+
autoload :MarketTrend, 'cryptum/ui/market_trend'
|
17
|
+
autoload :SignalEngine, 'cryptum/ui/signal_engine'
|
18
|
+
autoload :OrderExecution, 'cryptum/ui/order_execution'
|
19
|
+
autoload :Command, 'cryptum/ui/command'
|
20
|
+
|
21
|
+
# Initialize the UI
|
22
|
+
public_class_method def self.init
|
23
|
+
# Initialize curses Screen
|
24
|
+
Curses.init_screen
|
25
|
+
|
26
|
+
# Ensure the cursor is invisible
|
27
|
+
Curses.curs_set(0)
|
28
|
+
|
29
|
+
# Do not echo keystrokes back to the UI
|
30
|
+
Curses.noecho
|
31
|
+
|
32
|
+
# Used to immediately evaluate characters submitted
|
33
|
+
# without pressing ENTER (e.g. b, r, & w key events)
|
34
|
+
Curses.crmode
|
35
|
+
# Curses.nocrmode
|
36
|
+
# Curses.raw # NO
|
37
|
+
# Curses.noraw
|
38
|
+
# Disable Line Buffering
|
39
|
+
Curses.ESCDELAY = 0
|
40
|
+
|
41
|
+
# Start Color!
|
42
|
+
Curses.start_color
|
43
|
+
|
44
|
+
# This is important to ensure -1 maintains
|
45
|
+
# the original background color in the terminal
|
46
|
+
# when defining color pairs
|
47
|
+
Curses.use_default_colors
|
48
|
+
|
49
|
+
# This object is used to pass all of the UI sections
|
50
|
+
# around to various Cryptum modules
|
51
|
+
Cryptum::UI::TerminalWindow.new
|
52
|
+
rescue Interrupt
|
53
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
54
|
+
Cryptum.exit_gracefully(which_self: self)
|
55
|
+
rescue StandardError => e
|
56
|
+
# Produce a Stacktrace for anything else
|
57
|
+
Curses.close_screen
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
|
61
|
+
# Create New Curses Window
|
62
|
+
public_class_method def self.window(opts = {})
|
63
|
+
height = opts[:height].to_i
|
64
|
+
width = opts[:width].to_i
|
65
|
+
top = opts[:top].to_i
|
66
|
+
left = opts[:left].to_i
|
67
|
+
|
68
|
+
window = Curses::Window.new(
|
69
|
+
height,
|
70
|
+
width,
|
71
|
+
top,
|
72
|
+
left
|
73
|
+
)
|
74
|
+
window.nodelay = true
|
75
|
+
|
76
|
+
window
|
77
|
+
rescue Interrupt
|
78
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
79
|
+
Cryptum.exit_gracefully(which_self: self)
|
80
|
+
rescue StandardError => e
|
81
|
+
# Produce a Stacktrace for anything else
|
82
|
+
Curses.close_screen
|
83
|
+
raise e
|
84
|
+
end
|
85
|
+
|
86
|
+
# Draw a Box Around a Window
|
87
|
+
public_class_method def self.line(opts = {})
|
88
|
+
ui_win = opts[:ui_win]
|
89
|
+
out_line_no = opts[:out_line_no].to_i
|
90
|
+
|
91
|
+
ui_win.setpos(out_line_no, 0)
|
92
|
+
if Curses.can_change_color?
|
93
|
+
colorize(
|
94
|
+
ui_win: ui_win,
|
95
|
+
color: :custom,
|
96
|
+
red: 192,
|
97
|
+
green: 192,
|
98
|
+
blue: 192,
|
99
|
+
string: "\u2500" * Curses.cols
|
100
|
+
)
|
101
|
+
else
|
102
|
+
colorize(
|
103
|
+
ui_win: ui_win,
|
104
|
+
color: :white,
|
105
|
+
string: "\u2500" * Curses.cols
|
106
|
+
)
|
107
|
+
end
|
108
|
+
rescue Interrupt
|
109
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
110
|
+
Cryptum.exit_gracefully(which_self: self)
|
111
|
+
rescue StandardError => e
|
112
|
+
# Produce a Stacktrace for anything else
|
113
|
+
Curses.close_screen
|
114
|
+
raise e
|
115
|
+
end
|
116
|
+
|
117
|
+
# Jump to First Column
|
118
|
+
public_class_method def self.colorize(opts = {})
|
119
|
+
ui_win = opts[:ui_win]
|
120
|
+
color = opts[:color].to_s.to_sym
|
121
|
+
red = opts[:red].to_i
|
122
|
+
green = opts[:green].to_i
|
123
|
+
blue = opts[:blue].to_i
|
124
|
+
|
125
|
+
style = opts[:style].to_s.to_sym
|
126
|
+
style = :normal if opts[:style].nil?
|
127
|
+
|
128
|
+
bg = opts[:bg].to_i
|
129
|
+
bg = -1 if opts[:bg].nil?
|
130
|
+
|
131
|
+
string = opts[:string]
|
132
|
+
|
133
|
+
case color
|
134
|
+
when :black
|
135
|
+
color_id = 0
|
136
|
+
color_fg = Curses::COLOR_BLACK
|
137
|
+
color_bg = bg
|
138
|
+
when :red
|
139
|
+
color_id = 1
|
140
|
+
color_fg = Curses::COLOR_RED
|
141
|
+
color_bg = bg
|
142
|
+
when :green
|
143
|
+
color_id = 2
|
144
|
+
color_fg = Curses::COLOR_GREEN
|
145
|
+
color_bg = bg
|
146
|
+
when :yellow
|
147
|
+
color_id = 3
|
148
|
+
color_fg = Curses::COLOR_YELLOW
|
149
|
+
color_bg = bg
|
150
|
+
when :blue
|
151
|
+
color_id = 4
|
152
|
+
color_fg = Curses::COLOR_BLUE
|
153
|
+
color_bg = bg
|
154
|
+
when :magenta
|
155
|
+
color_id = 5
|
156
|
+
color_fg = Curses::COLOR_MAGENTA
|
157
|
+
color_bg = bg
|
158
|
+
when :cyan
|
159
|
+
color_id = 6
|
160
|
+
color_fg = Curses::COLOR_CYAN
|
161
|
+
color_bg = bg
|
162
|
+
when :white
|
163
|
+
color_id = 7
|
164
|
+
color_fg = Curses::COLOR_WHITE
|
165
|
+
color_bg = bg
|
166
|
+
when :rainbow
|
167
|
+
color_id = 254
|
168
|
+
red = Random.rand(0..1000)
|
169
|
+
green = Random.rand(0..1000)
|
170
|
+
blue = Random.rand(0..1000)
|
171
|
+
Curses.init_color(color_id, red, green, blue)
|
172
|
+
color_fg = color_id
|
173
|
+
color_bg = bg
|
174
|
+
when :custom
|
175
|
+
color_id = 255
|
176
|
+
Curses.init_color(color_id, red, green, blue)
|
177
|
+
color_fg = color_id
|
178
|
+
color_bg = bg
|
179
|
+
else
|
180
|
+
raise "Color Not Implemented for this Method: #{color}"
|
181
|
+
end
|
182
|
+
|
183
|
+
case style
|
184
|
+
when :blink
|
185
|
+
font = Curses::A_BLINK
|
186
|
+
when :bold
|
187
|
+
font = Curses::A_BOLD
|
188
|
+
when :highlight
|
189
|
+
font = Curses::A_STANDOUT
|
190
|
+
when :normal
|
191
|
+
font = Curses::A_NORMAL
|
192
|
+
when :reverse
|
193
|
+
font = Curses::A_REVERSE
|
194
|
+
else
|
195
|
+
raise "Font Style Not Implemented for this Method: #{style}"
|
196
|
+
end
|
197
|
+
|
198
|
+
Curses.init_pair(color_id, color_fg, color_bg)
|
199
|
+
ui_win.attron(Curses.color_pair(color_id) | font) do
|
200
|
+
ui_win.addstr(string)
|
201
|
+
end
|
202
|
+
rescue Interrupt
|
203
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
204
|
+
Cryptum.exit_gracefully(which_self: self)
|
205
|
+
rescue StandardError => e
|
206
|
+
# Produce a Stacktrace for anything else
|
207
|
+
Curses.close_screen
|
208
|
+
raise e
|
209
|
+
end
|
210
|
+
|
211
|
+
# Jump to First Column
|
212
|
+
public_class_method def self.col_center(opts = {})
|
213
|
+
str = opts[:str]
|
214
|
+
|
215
|
+
str_divided_by_two = str.length / 2
|
216
|
+
(Curses.cols / 2) - str_divided_by_two
|
217
|
+
rescue Interrupt
|
218
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
219
|
+
Cryptum.exit_gracefully(which_self: self)
|
220
|
+
rescue StandardError => e
|
221
|
+
# Produce a Stacktrace for anything else
|
222
|
+
Curses.close_screen
|
223
|
+
raise e
|
224
|
+
end
|
225
|
+
|
226
|
+
public_class_method def self.col_first
|
227
|
+
0
|
228
|
+
rescue Interrupt
|
229
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
230
|
+
Cryptum.exit_gracefully(which_self: self)
|
231
|
+
rescue StandardError => e
|
232
|
+
# Produce a Stacktrace for anything else
|
233
|
+
Curses.close_screen
|
234
|
+
raise e
|
235
|
+
end
|
236
|
+
|
237
|
+
# Jump to Second Column
|
238
|
+
public_class_method def self.col_second
|
239
|
+
(Curses.cols / 8) + 5
|
240
|
+
rescue Interrupt
|
241
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
242
|
+
Cryptum.exit_gracefully(which_self: self)
|
243
|
+
rescue StandardError => e
|
244
|
+
# Produce a Stacktrace for anything else
|
245
|
+
Curses.close_screen
|
246
|
+
raise e
|
247
|
+
end
|
248
|
+
|
249
|
+
# Jump to Third Column
|
250
|
+
public_class_method def self.col_third
|
251
|
+
((Curses.cols / 8) * 3) + 2
|
252
|
+
rescue Interrupt
|
253
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
254
|
+
Cryptum.exit_gracefully(which_self: self)
|
255
|
+
rescue StandardError => e
|
256
|
+
# Produce a Stacktrace for anything else
|
257
|
+
Curses.close_screen
|
258
|
+
raise e
|
259
|
+
end
|
260
|
+
|
261
|
+
# Jump to Fourth Column
|
262
|
+
public_class_method def self.col_fourth
|
263
|
+
((Curses.cols / 4) * 3) - 3
|
264
|
+
rescue Interrupt
|
265
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
266
|
+
Cryptum.exit_gracefully(which_self: self)
|
267
|
+
rescue StandardError => e
|
268
|
+
# Produce a Stacktrace for anything else
|
269
|
+
Curses.close_screen
|
270
|
+
raise e
|
271
|
+
end
|
272
|
+
|
273
|
+
public_class_method def self.detect_key_press_in_ui(opts = {})
|
274
|
+
key_press_event = opts[:key_press_event]
|
275
|
+
ui_win = opts[:ui_win]
|
276
|
+
|
277
|
+
case ui_win.getch
|
278
|
+
when 'G'
|
279
|
+
key_press_event.key_g = true
|
280
|
+
when 'r'
|
281
|
+
key_press_event.key_r = true
|
282
|
+
when 'u'
|
283
|
+
key_press_event.key_u = true
|
284
|
+
when 'w'
|
285
|
+
key_press_event.key_w = true
|
286
|
+
when 'x'
|
287
|
+
key_press_event.key_x = true
|
288
|
+
end
|
289
|
+
|
290
|
+
key_press_event
|
291
|
+
rescue Interrupt
|
292
|
+
# Exit Gracefully if CTRL+C is Pressed During Session
|
293
|
+
Cryptum.exit_gracefully(which_self: self)
|
294
|
+
rescue StandardError => e
|
295
|
+
# Produce a Stacktrace for anything else
|
296
|
+
Curses.close_screen
|
297
|
+
raise e
|
298
|
+
end
|
299
|
+
|
300
|
+
# Display a List of Every UI Module
|
301
|
+
|
302
|
+
public_class_method def self.help
|
303
|
+
constants.sort
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|