1
1
from protobuf_decoder .protobuf_decoder import Parser
2
- from textual .widgets import Label , Static , Collapsible , Rule , Button , TextArea
3
- from textual .containers import Horizontal , Vertical
2
+ from textual .app import ComposeResult
3
+ from textual .reactive import reactive
4
+ from textual .screen import Screen
5
+ from textual .widgets import Label , Static , Collapsible , Rule , Button , OptionList
6
+ from textual .widgets .option_list import Option
7
+ from textual .containers import Horizontal , Vertical , Grid
4
8
import json
5
9
6
- from db_connection import getKey , listVersions
10
+ from db_connection import deleteVersion , getKey , listVersions
7
11
8
12
class ProtobufDecoder ():
9
13
def __init__ (self ):
@@ -28,9 +32,37 @@ def __init__(self, stub, key: str, collection: str, **kwargs):
28
32
except Exception as e :
29
33
print ("Could not load versions: " + str (e ))
30
34
35
+ selected_version = reactive (0 )
36
+
37
+ cached_data = {}
31
38
def get_data (self ):
32
- data = getKey (self .stub , self .collection , self .key , self .selected_version )
33
- return data
39
+ if self .selected_version in self .cached_data :
40
+ return self .cached_data [self .selected_version ]
41
+ self .cached_data [self .selected_version ] = getKey (self .stub , self .collection , self .key , self .selected_version )
42
+ return self .cached_data [self .selected_version ]
43
+
44
+ def get_filename (self ):
45
+ return f"{ self .collection } _{ self .key } _{ self .selected_version } .bin"
46
+
47
+ def download_data (self ):
48
+ data = self .get_data ()
49
+ with open (self .get_filename (), "wb" ) as f :
50
+ f .write (data )
51
+ self .app .push_screen (DownloadNotification (filename = self .get_filename ()))
52
+
53
+ def delete_data (self ):
54
+ async def delete_callback (result : bool ):
55
+ if result :
56
+ deleteVersion (self .stub , self .collection , self .key , self .selected_version )
57
+ self .versions = listVersions (self .stub , self .collection , self .key )
58
+ self .versions .sort ()
59
+ if len (self .versions ) == 0 :
60
+ self .app .pop_screen ()
61
+ else :
62
+ self .selected_version = self .versions [- 1 ]
63
+ await self .recompose ()
64
+
65
+ self .app .push_screen (DeleteModal (stub = self .stub , collection = self .collection , key = self .key , version = self .selected_version ), delete_callback )
34
66
35
67
def display_record (self ):
36
68
data = self .get_data ()
@@ -97,7 +129,8 @@ def render_info_panel(self):
97
129
return Vertical (
98
130
Static (f"Exploring record/wire for { self .collection } :{ self .key } . Currently viewing version { self .selected_version } " ),
99
131
Rule (),
100
- Button ("Download selected version" ),
132
+ Button ("Download selected version" , id = "download_button" ),
133
+ Button ("Delete selected version" , id = "delete_button" ),
101
134
Rule (),
102
135
* self .render_version_buttons (),
103
136
id = "record_explorer_info_panel"
@@ -109,7 +142,61 @@ def compose(self):
109
142
yield self .display_record ()
110
143
yield self .render_info_panel ()
111
144
112
-
145
+ async def on_button_pressed (self , event ):
146
+ if event .button .id .startswith ("version_" ):
147
+ version = int (event .button .id .split ("_" )[1 ])
148
+ self .selected_version = version
149
+ await self .recompose ()
150
+ if event .button .id == "download_button" :
151
+ self .download_data ()
152
+ if event .button .id == "delete_button" :
153
+ self .delete_data ()
154
+
155
+
156
+ class DownloadNotification (Screen ):
157
+ """Screen with a note on where the downloaded file is stored."""
158
+
159
+ CSS_PATH = "modal.tcss"
160
+
161
+ def __init__ (self , name = None , id = None , classes = None , filename = None , ** kwargs ):
162
+ super ().__init__ (name , id , classes )
163
+ self .filename = filename
164
+
165
+ def compose (self ) -> ComposeResult :
166
+ yield Vertical (
167
+ Label (f"The version has been stored in { self .filename } " , id = "note" ),
168
+ Button ("Okay" , variant = "primary" , id = "okay" ),
169
+ id = "dialog" ,
170
+ )
171
+
172
+ def on_button_pressed (self , event : Button .Pressed ) -> None :
173
+ if event .button .id == "okay" :
174
+ self .app .pop_screen ()
175
+
176
+ class DeleteModal (Screen ):
177
+ """Screen with a note on where the downloaded file is stored."""
178
+
179
+ CSS_PATH = "modal.tcss"
180
+
181
+ def __init__ (self , name = None , id = None , classes = None ,collection = None , key = None , version = None , ** kwargs ):
182
+ super ().__init__ (name , id , classes )
183
+ self .collection = collection
184
+ self .key = key
185
+ self .version = version
186
+
187
+ def compose (self ) -> ComposeResult :
188
+ yield Vertical (
189
+ Label (f"Are you sure you want to delete version { self .version } of { self .collection } :{ self .key } ?" , id = "note" ),
190
+ Button ("Yes" , variant = "error" , id = "yes" ),
191
+ Button ("No" , variant = "primary" , id = "no" ),
192
+ id = "dialog" ,
193
+ )
194
+
195
+ def on_button_pressed (self , event : Button .Pressed ) -> None :
196
+ if event .button .id == "yes" :
197
+ self .dismiss (True )
198
+ if event .button .id == "no" :
199
+ self .dismiss (False )
113
200
114
201
if __name__ == "__main__" :
115
202
print ("Running decoder demo!" )
0 commit comments