wassup 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +8 -2
- data/examples/debug/Supfile +72 -13
- data/examples/josh-fastlane/Supfile +32 -31
- data/lib/wassup/app.rb +2 -1
- data/lib/wassup/pane.rb +166 -125
- data/lib/wassup/pane_builder.rb +46 -0
- data/lib/wassup/version.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 432db97778e804dfdfe02ec44d382aa7e7a275745c8b2ae73b4dd579bf215ae7
|
4
|
+
data.tar.gz: 99ccf1045dbad2b6431df2a55be38c643204b3389a0da7a3ecc06d7ede6d0218
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 264ec05425e3078e3ae97089dc890884b8c9aeff6ac6a10c6a49e6bf85c75dda370fb9135c665118e7fa4efdae1407865ae681074a462291b96eee2b700222c5
|
7
|
+
data.tar.gz: c8f13c8cd5f63e494e5408f5cc318a523d6ccc2922f227c7c630d4cc18e865367392a0e1038f6ae79abadf6e1c161edc535dc0908b216adbe91dc80f8f29318b
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
|
1
|
+
<h3 align="center">
|
2
|
+
<img height="200" alt="Wassup logo" src="https://user-images.githubusercontent.com/401294/145626927-7eb0fda5-c62a-47c8-9422-074b178fd8ef.png" />
|
3
|
+
</h3>
|
2
4
|
|
3
|
-
|
5
|
+
[](https://github.com/fastlane/fastlane/blob/master/LICENSE)
|
6
|
+
[](https://rubygems.org/gems/wassup)
|
4
7
|
|
8
|
+
**Wassup** is a scriptable terminal dashboard. Configure panes and content logic in a `Supfile` and then run `wassup`.
|
9
|
+
|
10
|
+
<hr/>
|
5
11
|
|
6
12
|
https://user-images.githubusercontent.com/401294/144465499-a8903d4c-f003-4550-b47c-f70c17cc02d8.mov
|
7
13
|
|
data/examples/debug/Supfile
CHANGED
@@ -8,10 +8,10 @@ add_pane do |pane|
|
|
8
8
|
pane.title = "Time Update - Every Second"
|
9
9
|
|
10
10
|
pane.interval = 1
|
11
|
-
pane.content do
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
pane.content do |content|
|
12
|
+
date = `date`
|
13
|
+
|
14
|
+
content.add_row(date)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,11 +24,11 @@ add_pane do |pane|
|
|
24
24
|
pane.highlight = false
|
25
25
|
pane.title = "Time Update - Every 5 Seconds"
|
26
26
|
|
27
|
-
pane.interval =
|
28
|
-
pane.content do
|
29
|
-
|
30
|
-
|
31
|
-
|
27
|
+
pane.interval = 30
|
28
|
+
pane.content do |content|
|
29
|
+
date = `date`
|
30
|
+
|
31
|
+
content.add_row(date)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -42,13 +42,72 @@ add_pane do |pane|
|
|
42
42
|
pane.title = "Maybe Error - Every 10 Seconds"
|
43
43
|
|
44
44
|
pane.interval = 10
|
45
|
-
pane.content do
|
45
|
+
pane.content do |content|
|
46
46
|
if [true, false].sample
|
47
47
|
raise "An error occured! Oh no!"
|
48
48
|
end
|
49
49
|
|
50
|
-
[
|
51
|
-
|
52
|
-
|
50
|
+
output = "[fg=cyan]No error occured[fg=white]"
|
51
|
+
|
52
|
+
content.add_row(output)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
add_pane do |pane|
|
57
|
+
pane.height = 0.25
|
58
|
+
pane.width = 0.35
|
59
|
+
pane.top = 0.25
|
60
|
+
pane.left = 0.25
|
61
|
+
|
62
|
+
pane.highlight = false
|
63
|
+
pane.title = "Multiple Contents"
|
64
|
+
|
65
|
+
pane.interval = 10
|
66
|
+
pane.content do |content|
|
67
|
+
content.add_row("Line 1 of page 1", page: "Page 1")
|
68
|
+
content.add_row("Line 2 of page 1", page: "Page 1")
|
69
|
+
content.add_row("Line 1 of page 2", page: "Page 2")
|
70
|
+
content.add_row("Line 2 of page 2", page: "Page 2")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
add_pane do |pane|
|
75
|
+
pane.height = 0.25
|
76
|
+
pane.width = 0.6
|
77
|
+
pane.top = 0.5
|
78
|
+
pane.left = 0
|
79
|
+
|
80
|
+
pane.highlight = false
|
81
|
+
pane.title = "Time Update - Slow Reload"
|
82
|
+
|
83
|
+
pane.interval = 30
|
84
|
+
pane.show_refresh = true
|
85
|
+
pane.content do |content|
|
86
|
+
sleep 10
|
87
|
+
|
88
|
+
date = `date`
|
89
|
+
|
90
|
+
content.add_row(date)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
require 'stringio'
|
95
|
+
foo = StringIO.new
|
96
|
+
$stdout = foo
|
97
|
+
|
98
|
+
add_pane do |pane|
|
99
|
+
pane.height = 1
|
100
|
+
pane.width = 0.4
|
101
|
+
pane.top = 0.0
|
102
|
+
pane.left = 0.6
|
103
|
+
|
104
|
+
pane.highlight = false
|
105
|
+
pane.title = "STDOUT"
|
106
|
+
|
107
|
+
pane.interval = 4
|
108
|
+
pane.content do |content|
|
109
|
+
$stdout.string.split("\n").each do |line|
|
110
|
+
content.add_row(line)
|
111
|
+
end
|
53
112
|
end
|
54
113
|
end
|
@@ -21,8 +21,9 @@ add_pane do |pane|
|
|
21
21
|
|
22
22
|
pane.title = "Stats: fastlane-community"
|
23
23
|
|
24
|
-
pane.interval =
|
25
|
-
pane.
|
24
|
+
pane.interval = 2
|
25
|
+
pane.show_refresh = false
|
26
|
+
pane.content do |builder|
|
26
27
|
days_1 = 0
|
27
28
|
days_7 = 0
|
28
29
|
days_30 = 0
|
@@ -41,13 +42,11 @@ add_pane do |pane|
|
|
41
42
|
days_365 +=1 if days <= 365
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
"Opened 365 days: #{days_365}"
|
50
|
-
]
|
45
|
+
builder.add_row("Opened today: #{days_1}")
|
46
|
+
builder.add_row("Opened 7 days: #{days_7}")
|
47
|
+
builder.add_row("Opened 30 days: #{days_30}")
|
48
|
+
builder.add_row("Opened 60 days: #{days_60}")
|
49
|
+
builder.add_row("Opened 365 days: #{days_365}")
|
51
50
|
end
|
52
51
|
end
|
53
52
|
|
@@ -64,8 +63,9 @@ add_pane do |pane|
|
|
64
63
|
|
65
64
|
pane.title = "Stats: fastlane/fastlane"
|
66
65
|
|
67
|
-
pane.interval =
|
68
|
-
pane.
|
66
|
+
pane.interval = 2
|
67
|
+
pane.show_refresh = false
|
68
|
+
pane.content do |builder|
|
69
69
|
days_1 = 0
|
70
70
|
days_7 = 0
|
71
71
|
days_30 = 0
|
@@ -86,14 +86,12 @@ add_pane do |pane|
|
|
86
86
|
days_60_plus +=1 if days > 60
|
87
87
|
end
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
"More than 60 days: #{days_60_plus}",
|
96
|
-
]
|
89
|
+
builder.add_row("Opened today: #{days_1}")
|
90
|
+
builder.add_row("Opened 7 days: #{days_7}")
|
91
|
+
builder.add_row("Opened 30 days: #{days_30}")
|
92
|
+
builder.add_row("Opened 45 days: #{days_45}")
|
93
|
+
builder.add_row("Opened 60 days: #{days_60}")
|
94
|
+
builder.add_row("More than 60 days: #{days_60_plus}")
|
97
95
|
end
|
98
96
|
end
|
99
97
|
|
@@ -111,7 +109,8 @@ add_pane do |pane|
|
|
111
109
|
pane.title = "Circle CI - fastlane/fastlane"
|
112
110
|
|
113
111
|
pane.interval = 60 * 5
|
114
|
-
pane.
|
112
|
+
pane.show_refresh = true
|
113
|
+
pane.content do |builder|
|
115
114
|
resp = RestClient::Request.execute(
|
116
115
|
method: :get,
|
117
116
|
url: "https://circleci.com/api/v2/project/github/fastlane/fastlane/pipeline",
|
@@ -125,7 +124,7 @@ add_pane do |pane|
|
|
125
124
|
end.map do |item|
|
126
125
|
id = item["id"]
|
127
126
|
number = item["number"]
|
128
|
-
message = item["vcs"]["commit"]["subject"]
|
127
|
+
message = (item["vcs"]["commit"] || {})["subject"]
|
129
128
|
login = item["trigger"]["actor"]["login"]
|
130
129
|
|
131
130
|
resp = RestClient::Request.execute(
|
@@ -145,7 +144,10 @@ add_pane do |pane|
|
|
145
144
|
status = "[fg=yellow]#{status}[fg=white]"
|
146
145
|
end
|
147
146
|
|
148
|
-
|
147
|
+
display = "#{number} (#{status}) by #{login} - #{message}"
|
148
|
+
object = [item, workflow]
|
149
|
+
|
150
|
+
builder.add_row(display, object)
|
149
151
|
end
|
150
152
|
end
|
151
153
|
pane.selection do |data|
|
@@ -179,7 +181,8 @@ add_pane do |pane|
|
|
179
181
|
pane.title = "Open PRs - fastlane-community"
|
180
182
|
|
181
183
|
pane.interval = 60 * 5
|
182
|
-
pane.
|
184
|
+
pane.show_refresh = true
|
185
|
+
pane.content do |builder|
|
183
186
|
fastlane_community_prs = []
|
184
187
|
|
185
188
|
resp = RestClient::Request.execute(
|
@@ -213,13 +216,9 @@ add_pane do |pane|
|
|
213
216
|
days = (Time.now - date).to_i / (24 * 60 * 60)
|
214
217
|
days_formatted = '%3.3s' % days.to_s
|
215
218
|
|
216
|
-
|
219
|
+
display = "[fg=yellow]#{number_formatted}[fg=cyan] #{days_formatted}d ago[fg=white] #{title}"
|
220
|
+
builder.add_row(display, pr, page: name)
|
217
221
|
end
|
218
|
-
|
219
|
-
{
|
220
|
-
title: name,
|
221
|
-
content: prs
|
222
|
-
}
|
223
222
|
end
|
224
223
|
end
|
225
224
|
pane.selection do |data|
|
@@ -243,7 +242,8 @@ add_pane do |pane|
|
|
243
242
|
pane.title = "Open PRs - fastlane/fastlane"
|
244
243
|
|
245
244
|
pane.interval = 60 * 5
|
246
|
-
pane.
|
245
|
+
pane.show_refresh = true
|
246
|
+
pane.content do |builder|
|
247
247
|
fastlane_prs = []
|
248
248
|
|
249
249
|
resp = RestClient::Request.execute(
|
@@ -264,7 +264,8 @@ add_pane do |pane|
|
|
264
264
|
days = (Time.now - date).to_i / (24 * 60 * 60)
|
265
265
|
days_formatted = '%3.3s' % days.to_s
|
266
266
|
|
267
|
-
|
267
|
+
display = "[fg=yellow]##{number}[fg=cyan] #{days_formatted}d ago[fg=white] #{title}"
|
268
|
+
builder.add_row(display, pr)
|
268
269
|
end
|
269
270
|
end
|
270
271
|
pane.selection do |data|
|
data/lib/wassup/app.rb
CHANGED
@@ -34,6 +34,7 @@ module Wassup
|
|
34
34
|
highlight: pane_builder.highlight,
|
35
35
|
focus_number: number,
|
36
36
|
interval: pane_builder.interval,
|
37
|
+
show_refresh: pane_builder.show_refresh,
|
37
38
|
content_block: pane_builder.content_block,
|
38
39
|
selection_blocks: pane_builder.selection_blocks
|
39
40
|
)
|
@@ -74,7 +75,7 @@ module Wassup
|
|
74
75
|
|
75
76
|
begin
|
76
77
|
|
77
|
-
@hidden_pane = Pane.new(0, 0, 0, 0, highlight: false, focus_number: 0, interval: nil, content_block: nil, selection_blocks: nil)
|
78
|
+
@hidden_pane = Pane.new(0, 0, 0, 0, highlight: false, focus_number: 0, interval: nil, show_refresh: false, content_block: nil, selection_blocks: nil)
|
78
79
|
@hidden_pane.focus_handler = @focus_handler
|
79
80
|
@focused_pane = @hidden_pane
|
80
81
|
|
data/lib/wassup/pane.rb
CHANGED
@@ -6,10 +6,10 @@ module Wassup
|
|
6
6
|
class Pane
|
7
7
|
attr_accessor :win
|
8
8
|
attr_accessor :subwin
|
9
|
-
attr_accessor :data_lines
|
10
|
-
attr_accessor :data_objects
|
11
9
|
attr_accessor :top
|
12
10
|
|
11
|
+
attr_accessor :contents
|
12
|
+
|
13
13
|
attr_accessor :title
|
14
14
|
|
15
15
|
attr_accessor :focused
|
@@ -30,13 +30,37 @@ module Wassup
|
|
30
30
|
attr_accessor :selection_blocks
|
31
31
|
|
32
32
|
attr_accessor :content_thread
|
33
|
+
attr_accessor :show_refresh
|
33
34
|
|
34
35
|
attr_accessor :selected_view_index
|
35
|
-
attr_accessor :all_view_data_objects
|
36
36
|
|
37
37
|
attr_accessor :win_height, :win_width, :win_top, :win_left
|
38
38
|
|
39
|
-
|
39
|
+
class Content
|
40
|
+
class Row
|
41
|
+
attr_accessor :display
|
42
|
+
attr_accessor :object
|
43
|
+
|
44
|
+
def initialize(display, object)
|
45
|
+
@display = display
|
46
|
+
@object = object || display
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
attr_accessor :title
|
51
|
+
attr_accessor :data
|
52
|
+
|
53
|
+
def initialize(title = nil)
|
54
|
+
@title = title
|
55
|
+
@data = []
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_row(display, object = nil)
|
59
|
+
@data << Row.new(display, object)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize(height, width, top, left, title: nil, highlight: true, focus_number: nil, interval:, show_refresh:, content_block:, selection_blocks:)
|
40
64
|
self.win_height = Curses.lines * height
|
41
65
|
self.win_width = Curses.cols * width
|
42
66
|
self.win_top = Curses.lines * top
|
@@ -52,11 +76,11 @@ module Wassup
|
|
52
76
|
self.virtual_scroll = true
|
53
77
|
|
54
78
|
self.top = 0
|
55
|
-
|
56
|
-
|
79
|
+
|
80
|
+
self.contents = []
|
81
|
+
self.show_refresh = show_refresh
|
57
82
|
|
58
83
|
self.selected_view_index = 0
|
59
|
-
self.all_view_data_objects = [] # Array of array
|
60
84
|
|
61
85
|
self.win.refresh
|
62
86
|
self.subwin.refresh
|
@@ -77,16 +101,16 @@ module Wassup
|
|
77
101
|
self.subwin = nil
|
78
102
|
end
|
79
103
|
|
80
|
-
if (
|
104
|
+
if (self.contents || []).size > 1
|
81
105
|
top_bump = 4
|
82
106
|
|
83
|
-
view_title =
|
107
|
+
view_title = self.contents[self.selected_view_index].title || "<No Title>"
|
84
108
|
view_title += " " * 100
|
85
109
|
|
86
110
|
self.win.setpos(2, 2)
|
87
111
|
self.win.addstr(view_title[0...self.win.maxx()-3])
|
88
112
|
|
89
|
-
subtitle = "(#{self.selected_view_index + 1} out of #{self.
|
113
|
+
subtitle = "(#{self.selected_view_index + 1} out of #{self.contents.size})"
|
90
114
|
subtitle += " " * 100
|
91
115
|
self.win.setpos(3, 2)
|
92
116
|
self.win.addstr(subtitle[0...self.win.maxx()-3])
|
@@ -120,28 +144,52 @@ module Wassup
|
|
120
144
|
end
|
121
145
|
end
|
122
146
|
|
147
|
+
def data_lines
|
148
|
+
return [] if self.selected_view_index.nil?
|
149
|
+
content = (self.contents || [])[self.selected_view_index]
|
150
|
+
|
151
|
+
if content.nil?
|
152
|
+
return []
|
153
|
+
else
|
154
|
+
content.data.map(&:display)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def refreshing?
|
159
|
+
return !self.content_thread.nil?
|
160
|
+
end
|
161
|
+
|
123
162
|
def refresh(force: false)
|
124
|
-
|
163
|
+
if force
|
164
|
+
self.last_refreshed = nil
|
165
|
+
end
|
166
|
+
|
167
|
+
return if !needs_refresh?
|
125
168
|
|
126
169
|
thread = self.content_thread
|
127
170
|
if !thread.nil?
|
128
171
|
if thread.status == "sleep" || thread.status == "run" || thread.status == "aborting"
|
172
|
+
self.update_refresh
|
129
173
|
return
|
130
174
|
elsif thread.status == nil
|
131
|
-
self.add_line("thread status is nil")
|
132
175
|
return
|
133
176
|
elsif thread.status == false
|
134
|
-
|
135
|
-
if
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
self.refresh_content(content)
|
177
|
+
rtn = thread.value
|
178
|
+
if rtn.is_a?(Ope)
|
179
|
+
content = Wassup::Pane::Content.new
|
180
|
+
|
181
|
+
content.add_row("[fg=red]Error during refersh[fg=white]")
|
182
|
+
content.add_row("[fg=red]at #{Time.now}[fg=while]")
|
183
|
+
content.add_row("")
|
184
|
+
content.add_row("[fg=yellow]Will try again next interval[fg=white]")
|
185
|
+
|
186
|
+
self.refresh_content([content])
|
187
|
+
elsif rtn.is_a?(Wassup::PaneBuilder::ContentBuilder)
|
188
|
+
self.refresh_content(rtn.contents)
|
144
189
|
end
|
190
|
+
|
191
|
+
self.update_box
|
192
|
+
self.update_title
|
145
193
|
else
|
146
194
|
# This shouldn't happen
|
147
195
|
# TODO: also fix this
|
@@ -151,26 +199,21 @@ module Wassup
|
|
151
199
|
the_block = self.content_block
|
152
200
|
self.content_thread = Thread.new {
|
153
201
|
begin
|
154
|
-
|
202
|
+
builder = Wassup::PaneBuilder::ContentBuilder.new(self.contents)
|
203
|
+
content = the_block.call(builder)
|
204
|
+
|
205
|
+
builder
|
155
206
|
rescue => ex
|
156
207
|
next Ope.new(ex)
|
157
208
|
end
|
158
209
|
}
|
210
|
+
self.update_box
|
211
|
+
self.update_title
|
159
212
|
end
|
160
213
|
end
|
161
214
|
|
162
|
-
def refresh_content(
|
163
|
-
|
164
|
-
return if content.first.nil?
|
165
|
-
|
166
|
-
if content.first.is_a?(Hash)
|
167
|
-
self.all_view_data_objects = content
|
168
|
-
else
|
169
|
-
self.all_view_data_objects = [
|
170
|
-
content
|
171
|
-
]
|
172
|
-
end
|
173
|
-
|
215
|
+
def refresh_content(contents)
|
216
|
+
self.contents = contents
|
174
217
|
self.load_current_view()
|
175
218
|
self.last_refreshed = Time.now
|
176
219
|
|
@@ -179,33 +222,54 @@ module Wassup
|
|
179
222
|
|
180
223
|
def load_current_view
|
181
224
|
self.setup_subwin()
|
182
|
-
view_content = self.all_view_data_objects[self.selected_view_index]
|
183
225
|
|
184
226
|
# this might be bad
|
185
227
|
self.highlighted_line = nil
|
228
|
+
self.virtual_reload()
|
229
|
+
end
|
230
|
+
|
231
|
+
def title=(title)
|
232
|
+
@title = title
|
233
|
+
self.update_box()
|
234
|
+
self.update_title()
|
235
|
+
end
|
236
|
+
|
237
|
+
attr_accessor :refresh_char_count
|
238
|
+
def refresh_char
|
239
|
+
return "" unless self.show_refresh
|
186
240
|
|
187
|
-
|
188
|
-
|
189
|
-
view_content = view_content[:content]
|
241
|
+
if self.refresh_char_count.nil?
|
242
|
+
self.refresh_char_count = 0
|
190
243
|
end
|
191
244
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
@data_objects << item[1]
|
200
|
-
self.add_line(item[0])
|
245
|
+
if self.refreshing?
|
246
|
+
array = ['\\', '|', '/', '|']
|
247
|
+
rtn = array[self.refresh_char_count]
|
248
|
+
|
249
|
+
self.refresh_char_count += 1
|
250
|
+
if self.refresh_char_count >= array.size
|
251
|
+
self.refresh_char_count = 0
|
201
252
|
end
|
253
|
+
|
254
|
+
return rtn
|
255
|
+
else
|
256
|
+
return ""
|
202
257
|
end
|
203
258
|
end
|
204
259
|
|
205
|
-
|
206
|
-
|
207
|
-
self.
|
208
|
-
|
260
|
+
attr_accessor :last_refresh_char_at
|
261
|
+
def update_refresh
|
262
|
+
return unless self.should_box
|
263
|
+
|
264
|
+
self.last_refresh_char_at ||= Time.now
|
265
|
+
|
266
|
+
if Time.now - self.last_refresh_char_at >= 0.15
|
267
|
+
self.win.setpos(0, 1)
|
268
|
+
self.win.addstr(self.refresh_char)
|
269
|
+
self.win.refresh
|
270
|
+
|
271
|
+
self.last_refresh_char_at = Time.now
|
272
|
+
end
|
209
273
|
end
|
210
274
|
|
211
275
|
def update_title
|
@@ -236,16 +300,6 @@ module Wassup
|
|
236
300
|
self.win.refresh
|
237
301
|
end
|
238
302
|
|
239
|
-
def add_line(text)
|
240
|
-
data_lines << text
|
241
|
-
|
242
|
-
if self.virtual_scroll
|
243
|
-
self.virtual_reload
|
244
|
-
else
|
245
|
-
self.load_thing
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
303
|
# Load the file into memory and
|
250
304
|
# put the first part on the curses display.
|
251
305
|
def load_thing
|
@@ -258,8 +312,9 @@ module Wassup
|
|
258
312
|
end
|
259
313
|
|
260
314
|
def virtual_reload
|
261
|
-
return if self.data_lines.nil?
|
315
|
+
return if self.data_lines.nil? || self.data_lines.empty?
|
262
316
|
|
317
|
+
# TODO: This errored out but might be because thread stuff???
|
263
318
|
self.data_lines[self.top..(self.top+self.subwin.maxy-1)].each_with_index do |line, idx|
|
264
319
|
|
265
320
|
write_full_line = false
|
@@ -267,65 +322,49 @@ module Wassup
|
|
267
322
|
|
268
323
|
max_char = self.subwin.maxx()-3
|
269
324
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
#
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
new_char_count = char_count + part.size
|
314
|
-
if new_char_count >= max_char
|
315
|
-
part = part[0...(max_char - char_count)]
|
316
|
-
end
|
317
|
-
|
318
|
-
self.subwin.setpos(idx, char_count)
|
319
|
-
self.subwin.addstr(part)
|
320
|
-
|
321
|
-
char_count += part.size
|
322
|
-
end
|
323
|
-
|
324
|
-
end
|
325
|
-
|
326
|
-
self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
|
327
|
-
self.subwin.clrtoeol()
|
328
|
-
#end
|
325
|
+
self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
|
326
|
+
|
327
|
+
splits = line.split(/\[.*?\]/) # returns ["hey something", "other thing", "okay"]
|
328
|
+
scans = line.scan(/\[.*?\]/) #returns ["red", "white"]
|
329
|
+
scans = scans.map do |str|
|
330
|
+
if str.start_with?('[fg=')
|
331
|
+
str = str.gsub('[fg=', '').gsub(']','')
|
332
|
+
Wassup::Color.new(str)
|
333
|
+
else
|
334
|
+
str
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
all_parts = splits.zip(scans).flatten.compact
|
339
|
+
|
340
|
+
char_count = 0
|
341
|
+
|
342
|
+
if should_highlight
|
343
|
+
self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::HIGHLIGHT))
|
344
|
+
end
|
345
|
+
|
346
|
+
all_parts.each do |part|
|
347
|
+
if part.is_a?(Wassup::Color)
|
348
|
+
#color = Curses.color_pair([1,2,3,4].sample)
|
349
|
+
if !should_highlight
|
350
|
+
self.subwin.attrset(Curses.color_pair(part.color_pair))
|
351
|
+
end
|
352
|
+
else
|
353
|
+
new_char_count = char_count + part.size
|
354
|
+
if new_char_count >= max_char
|
355
|
+
part = part[0...(max_char - char_count)]
|
356
|
+
end
|
357
|
+
|
358
|
+
self.subwin.setpos(idx, char_count)
|
359
|
+
self.subwin.addstr(part)
|
360
|
+
|
361
|
+
char_count += part.size
|
362
|
+
end
|
363
|
+
|
364
|
+
end
|
365
|
+
|
366
|
+
self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
|
367
|
+
self.subwin.clrtoeol()
|
329
368
|
end
|
330
369
|
self.subwin.refresh
|
331
370
|
end
|
@@ -387,7 +426,7 @@ module Wassup
|
|
387
426
|
def scroll_left
|
388
427
|
self.selected_view_index -= 1
|
389
428
|
if self.selected_view_index < 0
|
390
|
-
self.selected_view_index = self.
|
429
|
+
self.selected_view_index = self.contents.size - 1
|
391
430
|
end
|
392
431
|
|
393
432
|
self.load_current_view
|
@@ -395,7 +434,7 @@ module Wassup
|
|
395
434
|
|
396
435
|
def scroll_right
|
397
436
|
self.selected_view_index += 1
|
398
|
-
if self.selected_view_index >= self.
|
437
|
+
if self.selected_view_index >= self.contents.size
|
399
438
|
self.selected_view_index = 0
|
400
439
|
end
|
401
440
|
|
@@ -465,7 +504,9 @@ module Wassup
|
|
465
504
|
else
|
466
505
|
selection_block = self.selection_blocks[input]
|
467
506
|
if !selection_block.nil? && !self.highlighted_line.nil?
|
468
|
-
|
507
|
+
content = self.contents[self.selected_view_index]
|
508
|
+
row = content.data[self.highlighted_line]
|
509
|
+
data = row.object || row.display
|
469
510
|
selection_block.call(data)
|
470
511
|
end
|
471
512
|
end
|
data/lib/wassup/pane_builder.rb
CHANGED
@@ -10,10 +10,56 @@ module Wassup
|
|
10
10
|
|
11
11
|
attr_accessor :title
|
12
12
|
|
13
|
+
attr_accessor :show_refresh
|
14
|
+
|
13
15
|
attr_accessor :interval
|
14
16
|
attr_accessor :content_block
|
15
17
|
attr_accessor :selection_blocks
|
16
18
|
|
19
|
+
class ContentBuilder
|
20
|
+
attr_accessor :contents
|
21
|
+
|
22
|
+
def initialize(contents)
|
23
|
+
@contents = contents
|
24
|
+
@need_to_clear = true
|
25
|
+
@show_refresh = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear=(clear)
|
29
|
+
@need_to_clear = clear
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_row(display, object=nil, page:nil)
|
33
|
+
if @need_to_clear
|
34
|
+
@need_to_clear = false
|
35
|
+
self.contents = []
|
36
|
+
end
|
37
|
+
|
38
|
+
content = nil
|
39
|
+
|
40
|
+
# Create contents if none
|
41
|
+
if page.nil?
|
42
|
+
if self.contents.empty?
|
43
|
+
content = Pane::Content.new
|
44
|
+
self.contents << content
|
45
|
+
else
|
46
|
+
content = self.contents.first
|
47
|
+
end
|
48
|
+
elsif page.is_a?(String)
|
49
|
+
content = self.contents.find do |content|
|
50
|
+
content.title == page
|
51
|
+
end
|
52
|
+
|
53
|
+
if content.nil?
|
54
|
+
content = Pane::Content.new(page)
|
55
|
+
self.contents << content
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
content.add_row(display, object)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
17
63
|
def initialize()
|
18
64
|
@height = 1
|
19
65
|
@weight = 1
|
data/lib/wassup/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wassup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Holtz
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: curses
|
@@ -63,7 +63,7 @@ licenses:
|
|
63
63
|
metadata:
|
64
64
|
homepage_uri: https://github.com/joshdholtz/wassup
|
65
65
|
source_code_uri: https://github.com/joshdholtz/wassup
|
66
|
-
post_install_message:
|
66
|
+
post_install_message:
|
67
67
|
rdoc_options: []
|
68
68
|
require_paths:
|
69
69
|
- lib
|
@@ -78,8 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
- !ruby/object:Gem::Version
|
79
79
|
version: '0'
|
80
80
|
requirements: []
|
81
|
-
rubygems_version: 3.
|
82
|
-
signing_key:
|
81
|
+
rubygems_version: 3.0.3.1
|
82
|
+
signing_key:
|
83
83
|
specification_version: 4
|
84
84
|
summary: A scriptable terminal dashboard
|
85
85
|
test_files: []
|