From 8eae5abc76ebb4c5d77499aaeba75adb694af3ea Mon Sep 17 00:00:00 2001 From: John Mertz Date: Fri, 1 Mar 2024 16:06:19 -0700 Subject: [PATCH] Remove vestigial code. Improve conversation view, simplify --- voipms-sms-tui.py | 236 +++++++++++++++++++++++++--------------------- 1 file changed, 129 insertions(+), 107 deletions(-) diff --git a/voipms-sms-tui.py b/voipms-sms-tui.py index 7c6b36a..01d5979 100644 --- a/voipms-sms-tui.py +++ b/voipms-sms-tui.py @@ -5,16 +5,16 @@ # Copyright (C) 2024 John Mertz # # This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public +# modify it under the terms of the GNU Affero Lesser General Public # License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. +# version 3 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public +# You should have received a copy of the GNU Affero Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # @@ -28,17 +28,52 @@ import urwid class ConversationModel: def __init__(self): + self.settings = { + "user_left": 1 + } self.data = { - "1234567890": ["Alice Bobson", { 'id': 1, 'sender':'1111111111', 'timestamp':100, 'msg': "hi"},{ 'id': 2, 'sender':'1234567890', 'timestamp':200, 'msg': "wassup!"}], - "1112223333": ["", { 'id': 1, 'sender':'1111111111', 'timestamp':1, 'msg': "hello"},{ 'id': 2, 'sender':'1112223333', 'timestamp':2, 'msg': "oh, hi"}], + "1234567890": [ + "Alice Bobson", + { + 'id': 1, + 'sender':'1111111111', + 'timestamp':100, 'msg': "hi" + },{ + 'id': 2, + 'sender':'1234567890', + 'timestamp':200, + 'msg': "Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi." + },{ + 'id': 3, + 'sender':'1234567890', + 'timestamp':300, + 'msg': "wassup!" + },{ + 'id': 4, + 'sender':'1111111111', + 'timestamp':400, + 'msg': "Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi." + } + ], + "1112223333": [ + "", + { + 'id': 1, + 'sender':'1111111111', + 'timestamp':1, + 'msg': "hello" + },{ + 'id': 2, + 'sender':'1112223333', + 'timestamp':2, + 'msg': "oh, hi" + } + ], } self.conversations = [] for key in self.data: self.conversations.append(key) self.current_conversation=self.conversations[0] - self.settings = { - "me_left": 1 - } def get_conversations(self): return self.conversations @@ -52,70 +87,64 @@ class ConversationModel: last_time = 0 for m in d: if not last_time: - if m != "": - lines.append(urwid.AttrMap(urwid.Text(m, urwid.CENTER), "header")) - else: - lines.append(urwid.Text(self.current_conversation, urwid.CENTER)) last_time=1 continue if m['timestamp']-last_time >= 10: lines.append(urwid.Text(str(m['timestamp']), urwid.CENTER)) last_time = m['timestamp'] - if (m['sender'] == self.current_conversation) ^ (self.settings['me_left'] == 1): - lines.append(urwid.Padding(urwid.Text(m['msg'], urwid.RIGHT),left=10,right=1)) + if (m['sender'] == self.current_conversation) ^ (self.settings['user_left'] == 1): + lines.append( + urwid.Columns( + [ + urwid.Divider(" "), + (urwid.WEIGHT, 8, urwid.Padding( + urwid.LineBox(urwid.Text(m['msg'])), align='right', width=len(m['msg'])+2 + )), + ] + ) + ) else: - lines.append(urwid.Padding(urwid.Text(m['msg'], urwid.LEFT),left=1,right=10)) + lines.append( + urwid.Columns( + [ + (urwid.WEIGHT, 8, urwid.Padding( + urwid.LineBox(urwid.Text(m['msg'])), width=len(m['msg'])+2 + )), + urwid.Divider(" "), + ] + ) + ) return lines class ConversationView(urwid.WidgetWrap): - """ - A class responsible for providing the application's interface and - graph display. - """ - palette: typing.ClassVar[tuple[str, str, str, ...]] = [ + palette = [ ("body", "black", "light gray", "standout"), ("header", "white", "dark red", "bold"), - ("screen edge", "light blue", "dark cyan"), - ("main shadow", "dark gray", "black"), - ("line", "black", "light gray", "standout"), - ("bg background", "light gray", "black"), - ("bg 1", "black", "dark blue", "standout"), - ("bg 1 smooth", "dark blue", "black"), - ("bg 2", "black", "dark cyan", "standout"), - ("bg 2 smooth", "dark cyan", "black"), - ("button normal", "light gray", "dark blue", "standout"), - ("button select", "white", "dark green"), - ("line", "black", "light gray", "standout"), - ("pg normal", "white", "black", "standout"), - ("pg complete", "white", "dark magenta"), - ("pg smooth", "dark magenta", "black"), + ("footer", "black", "dark cyan"), + ("sidebar", "dark gray", "black"), + ("buttn", "white", "dark green"), + ("buttnf", "white", "light green", "bold"), ] - graph_samples_per_bar = 10 - graph_num_bars = 5 - graph_offset_per_second = 5 - - - def __init__(self, controller): - self.controller = controller + def __init__(self, model): + self.model = model self.started = True self.offset = 0 self.last_offset = None super().__init__(self.main_window()) def update_conversation(self, force_update=False): - return urwid.SimpleListWalker(self.controller.get_messages()) + return urwid.SimpleListWalker(self.model.get_messages()) def on_conversation_button(self, button, state): - """Notify the controller of a new conversation setting.""" + """Notify the model of a new conversation setting.""" if state: - # The new conversation is the label of the button - self.controller.set_conversation(button.get_label().split("\n")[0]) - self.model.set_conversation(conversation) - self.graph = self.conversation() + self.model.set_conversation(button.get_label().split("\n")[0]) + self.model.set_conversation(self.conversation) + self.chat = self.conversation() self.view = urwid.Frame( - urwid.AttrMap(self.graph, "body"), + urwid.AttrMap(self.chat, "body"), footer=self.send ) self.last_offset = None @@ -126,15 +155,11 @@ class ConversationView(urwid.WidgetWrap): if rb.base_widget.label == m: rb.base_widget.set_state(True, do_callback=False) break - self.last_offset = None - conversation = self.controller.get_conversations()[0] - - def bar_graph(self, smooth=False): - satt = None - if smooth: - satt = {(1, 0): "bg 1 smooth", (2, 0): "bg 2 smooth"} - w = urwid.BarGraph(["bg background", "bg 1", "bg 2"], satt=satt) - return w + if m != "": + self.header = urwid.Text(m, urwid.CENTER) + else: + self.header = urwid.Text(self.current_conversation, urwid.CENTER) + conversation = self.model.get_conversations()[0] def conversation(self): return urwid.ListBox(self.update_conversation()) @@ -157,7 +182,7 @@ class ConversationView(urwid.WidgetWrap): raise urwid.ExitMainLoop() def conversation_selection(self): - conversations = self.controller.get_conversations() + conversations = self.model.get_conversations() # setup conversation radio buttons self.conversation_buttons = [] group = [] @@ -178,15 +203,15 @@ class ConversationView(urwid.WidgetWrap): field=msg.edit_text def main_window(self): - #self.graph = self.bar_graph() - self.graph = self.conversation() - self.send_content = "preset" - self.send_box = urwid.Edit("", self.send_content, multiline=True) - urwid.connect_signal(self.send_box, 'change', self.send_update(self.send_content,self.send_box)) + self.chat = self.conversation() + self.send_content = "Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. Oh, Hi. wassup!" + self.send_edit = urwid.Edit("", self.send_content, multiline=True) + self.send_box = urwid.Padding(self.send_edit, left=1, right=1) + urwid.connect_signal(self.send_edit, 'change', self.send_update(self.send_content,self.send_edit)) self.send_button = urwid.Padding( urwid.AttrMap( urwid.Button( - "SEND", self.send_message(self.send_box), align=urwid.CENTER + "SEND", self.send_message(self.send_edit), align=urwid.CENTER ), "buttn", "buttnf" ), @@ -197,57 +222,54 @@ class ConversationView(urwid.WidgetWrap): (urwid.WEIGHT, 8, self.send_box), self.send_button, ]) + self.header = urwid.Text("VoIP.ms SMS TUI", urwid.CENTER) self.view = urwid.Frame( - urwid.AttrMap(self.graph, "body"), - footer=self.send + urwid.AttrMap(self.chat, "body"), + header=urwid.AttrMap(self.header, "header"), + footer=urwid.AttrMap(self.send, "footer") ) c = self.conversation_selection() - w = urwid.Columns([c, (urwid.WEIGHT, 3, self.view)], dividechars=0, focus_column=0) + w = urwid.Columns( + [ + urwid.AttrMap(c, "sidebar"), + (urwid.WEIGHT, 3, self.view) + ], + dividechars=0, focus_column=0 + ) w = urwid.AttrMap(w, "body") return w -class SMSController: - """ - A class responsible for setting up the model and view and running - the application. - """ - - def __init__(self): - self.model = ConversationModel() - self.view = ConversationView(self) - # use the first conversation as the default - conversation = self.get_conversations()[0] - self.model.set_conversation(conversation) - # update the view - self.view.on_conversation_change(conversation) - self.view.update_conversation(True) - - def get_conversations(self): - """Allow our view access to the list of conversations.""" - return self.model.get_conversations() - - def set_conversation(self, m) -> None: - """Allow our view to set the conversation.""" - self.model.set_conversation(m) - self.view.update_conversation(True) - - def get_messages(self): - """Provide data to our view for the graph.""" - return self.model.get_messages() - - def unhandled(self, key: str | tuple[str, int, int, int]) -> None: - if key == "F8": - self.exit_program - - def main(self): - urwid.MainLoop(self.view, self.view.palette, unhandled_input=self.unhandled).run() - self.loop.run() - - def main(): - SMSController().main() + + def get_conversations(): + return model.get_conversations() + + def set_conversation(m) -> None: + model.set_conversation(m) + view.update_conversation(True) + + def get_messages(): + return model.get_messages() + + def unhandled( key: str | tuple[str, int, int, int]) -> None: + if key == "F8": + exit_program + + model = ConversationModel() + view = ConversationView(model) + # use the first conversation as the default + conversation = get_conversations()[0] + model.set_conversation(conversation) + # update the view + view.on_conversation_change(conversation) + view.update_conversation(True) + urwid.MainLoop(view, view.palette, unhandled_input=unhandled).run() + + +def setup(): + main() if __name__ == "__main__": - main() + setup()