mirror of
https://github.com/markqvist/NomadNet.git
synced 2025-12-17 14:54:26 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b82cfce3f8 | ||
|
|
722cb35759 | ||
|
|
6da665f1c7 | ||
|
|
efc24d361b | ||
|
|
848514ec54 | ||
|
|
3a4d7eed82 | ||
|
|
f2e7e098f9 | ||
|
|
ee6cc9fd4f | ||
|
|
398c3c3504 | ||
|
|
f86cdb4c5e | ||
|
|
953c8c94c7 | ||
|
|
0c94dfa482 | ||
|
|
08f1d4cda7 | ||
|
|
718e2ca859 |
@@ -236,6 +236,7 @@ class ConversationMessage:
|
||||
self.lxm = LXMF.LXMessage.unpack_from_file(open(self.file_path, "rb"))
|
||||
self.loaded = True
|
||||
self.timestamp = self.lxm.timestamp
|
||||
self.sort_timestamp = os.path.getmtime(self.file_path)
|
||||
|
||||
if self.lxm.state > LXMF.LXMessage.DRAFT and self.lxm.state < LXMF.LXMessage.SENT:
|
||||
found = False
|
||||
|
||||
@@ -87,7 +87,8 @@ class Directory:
|
||||
if self.trust_level(associated_peer) == DirectoryEntry.TRUSTED:
|
||||
node_entry = DirectoryEntry(source_hash, display_name=app_data.decode("utf-8"), trust_level=DirectoryEntry.TRUSTED, hosts_node=True)
|
||||
self.remember(node_entry)
|
||||
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
|
||||
|
||||
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
|
||||
|
||||
def remove_announce_with_timestamp(self, timestamp):
|
||||
selected_announce = None
|
||||
|
||||
@@ -223,6 +223,12 @@ class NomadNetworkApp:
|
||||
def conversations(self):
|
||||
return nomadnet.Conversation.conversation_list(self)
|
||||
|
||||
def has_unread_conversations(self):
|
||||
if len(nomadnet.Conversation.unread_conversations) > 0:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def conversation_is_unread(self, source_hash):
|
||||
if bytes.fromhex(source_hash) in nomadnet.Conversation.unread_conversations:
|
||||
return True
|
||||
@@ -430,8 +436,8 @@ announce_at_start = yes
|
||||
intro_time = 1
|
||||
|
||||
# You can specify the display theme.
|
||||
# theme = dark
|
||||
theme = light
|
||||
# theme = light
|
||||
theme = dark
|
||||
|
||||
# Specify the number of colors to use
|
||||
# valid colormodes are:
|
||||
@@ -486,12 +492,12 @@ enable_node = no
|
||||
node_name = None
|
||||
|
||||
# Automatic announce interval in minutes.
|
||||
# 12 hours by default.
|
||||
# 6 hours by default.
|
||||
|
||||
announce_interval = 720
|
||||
announce_interval = 360
|
||||
|
||||
# Whether to announce when the node starts
|
||||
|
||||
announce_at_start = No
|
||||
announce_at_start = Yes
|
||||
|
||||
'''.splitlines()
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.0.9"
|
||||
__version__ = "0.1.1"
|
||||
@@ -2,6 +2,7 @@ import RNS
|
||||
import urwid
|
||||
import time
|
||||
import os
|
||||
import platform
|
||||
|
||||
import nomadnet
|
||||
from nomadnet.ui.textui import *
|
||||
@@ -90,6 +91,13 @@ GLYPHSETS = {
|
||||
"nerdfont": 3
|
||||
}
|
||||
|
||||
if platform.system() == "Darwin":
|
||||
urm_char = " \uf0e0 "
|
||||
ur_char = "\uf0e0 "
|
||||
else:
|
||||
urm_char = " \uf003 "
|
||||
ur_char = "\uf003 "
|
||||
|
||||
GLYPHS = {
|
||||
# Glyph name # Plain # Unicode # Nerd Font
|
||||
("check", "=", "\u2713", "\u2713"),
|
||||
@@ -103,13 +111,14 @@ GLYPHS = {
|
||||
("arrow_d", "\\/", "\u2193", "\u2193"),
|
||||
("warning", "!", "\u26a0", "\uf12a"),
|
||||
("info", "i", "\u2139", "\ufb4d"),
|
||||
("unread", "[U]", "\u2709", "\uf003 "),
|
||||
("unread", "[!]", "\u2709", ur_char),
|
||||
("divider1", "-", "\u2504", "\u2504"),
|
||||
("peer", "[P]", "\u24c5 ", "\uf415"),
|
||||
("node", "[N]", "\u24c3 ", "\uf502"),
|
||||
("page", "", "\u25a4", "\uf719 "),
|
||||
("speed", "", "\u25F7", "\uf9c4"),
|
||||
("decoration_menu", "", "", " \uf93a"),
|
||||
("decoration_menu", " +", " +", " \uf93a"),
|
||||
("unread_menu", " !", " \u2709", urm_char),
|
||||
("globe", "", "", "\uf484"),
|
||||
}
|
||||
|
||||
@@ -183,6 +192,7 @@ class TextUI:
|
||||
|
||||
self.set_colormode(colormode)
|
||||
|
||||
self.main_display.start()
|
||||
self.loop.run()
|
||||
|
||||
def set_colormode(self, colormode):
|
||||
|
||||
@@ -90,6 +90,8 @@ class Browser:
|
||||
if self.destination_hash != None:
|
||||
self.load_page()
|
||||
|
||||
self.clean_cache()
|
||||
|
||||
def current_url(self):
|
||||
if self.destination_hash == None:
|
||||
return ""
|
||||
@@ -201,8 +203,12 @@ class Browser:
|
||||
else:
|
||||
self.display_widget.set_attr_map({None: "body_text"})
|
||||
self.browser_header = self.make_control_widget()
|
||||
remote_display_string = self.app.directory.simplest_display_str(self.destination_hash)
|
||||
if remote_display_string == RNS.prettyhexrep(self.loopback):
|
||||
if self.destination_hash != None:
|
||||
remote_display_string = self.app.directory.simplest_display_str(self.destination_hash)
|
||||
else:
|
||||
remote_display_string = ""
|
||||
|
||||
if self.loopback != None and remote_display_string == RNS.prettyhexrep(self.loopback):
|
||||
remote_display_string = self.app.node.name
|
||||
|
||||
self.linebox.set_title(remote_display_string)
|
||||
@@ -697,6 +703,22 @@ class Browser:
|
||||
|
||||
return None
|
||||
|
||||
def clean_cache(self):
|
||||
files = os.listdir(self.app.cachepath)
|
||||
for file in files:
|
||||
cachepath = self.app.cachepath+"/"+file
|
||||
try:
|
||||
components = file.split("_")
|
||||
if len(components) == 2 and len(components[0]) == 64 and len(components[1]) > 0:
|
||||
expires = float(components[1])
|
||||
|
||||
if time.time() > expires:
|
||||
RNS.log("Removing stale cache entry "+str(file), RNS.LOG_DEBUG)
|
||||
os.unlink(cachepath)
|
||||
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
|
||||
def cache_page(self, cache_time):
|
||||
url_hash = self.url_hash(self.current_url())
|
||||
@@ -860,4 +882,4 @@ class UrlEdit(urwid.Edit):
|
||||
if key == "enter":
|
||||
self.confirmed(self)
|
||||
else:
|
||||
return super(UrlEdit, self).keypress(size, key)
|
||||
return super(UrlEdit, self).keypress(size, key)
|
||||
@@ -316,14 +316,15 @@ class ConversationsDisplay():
|
||||
self.ilb.select_item(ilb_position)
|
||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.loop.draw_screen()
|
||||
|
||||
if self.currently_displayed_conversation != None:
|
||||
if self.app.conversation_is_unread(self.currently_displayed_conversation):
|
||||
self.app.mark_conversation_read(self.currently_displayed_conversation)
|
||||
try:
|
||||
if os.path.isfile(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread"):
|
||||
os.unlink(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread")
|
||||
except Exception as e:
|
||||
raise e
|
||||
if self.app.ui.main_display.sub_displays.active_display == self.app.ui.main_display.sub_displays.conversations_display:
|
||||
if self.currently_displayed_conversation != None:
|
||||
if self.app.conversation_is_unread(self.currently_displayed_conversation):
|
||||
self.app.mark_conversation_read(self.currently_displayed_conversation)
|
||||
try:
|
||||
if os.path.isfile(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread"):
|
||||
os.unlink(self.app.conversationpath + "/" + self.currently_displayed_conversation + "/unread")
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
|
||||
@@ -422,7 +423,8 @@ class ConversationsDisplay():
|
||||
|
||||
if trust_level != DirectoryEntry.TRUSTED:
|
||||
display_text += " <"+source_hash+">"
|
||||
else:
|
||||
|
||||
if trust_level != DirectoryEntry.UNTRUSTED:
|
||||
if unread:
|
||||
if source_hash != self.currently_displayed_conversation:
|
||||
display_text += " "+g["unread"]
|
||||
@@ -664,7 +666,7 @@ class ConversationWidget(urwid.WidgetWrap):
|
||||
message_widget = LXMessageWidget(message)
|
||||
self.message_widgets.append(message_widget)
|
||||
|
||||
self.message_widgets.sort(key=lambda m: m.timestamp, reverse=False)
|
||||
self.message_widgets.sort(key=lambda m: m.sort_timestamp, reverse=False)
|
||||
|
||||
from nomadnet.vendor.additional_urwid_widgets import IndicativeListBox
|
||||
self.messagelist = IndicativeListBox(self.message_widgets, position = len(self.message_widgets)-1)
|
||||
@@ -698,6 +700,7 @@ class LXMessageWidget(urwid.WidgetWrap):
|
||||
app = nomadnet.NomadNetworkApp.get_shared_instance()
|
||||
g = app.ui.glyphs
|
||||
self.timestamp = message.get_timestamp()
|
||||
self.sort_timestamp = message.sort_timestamp
|
||||
time_format = app.time_format
|
||||
message_time = datetime.fromtimestamp(self.timestamp)
|
||||
encryption_string = ""
|
||||
|
||||
@@ -135,6 +135,9 @@ class MainDisplay():
|
||||
def redraw_now(self, sender=None, data=None):
|
||||
self.app.ui.loop.draw_screen()
|
||||
|
||||
def start(self):
|
||||
self.menu_display.start()
|
||||
|
||||
def quit(self, sender=None):
|
||||
raise urwid.ExitMainLoop
|
||||
|
||||
@@ -147,11 +150,16 @@ class MenuColumns(urwid.Columns):
|
||||
return super(MenuColumns, self).keypress(size, key)
|
||||
|
||||
class MenuDisplay():
|
||||
UPDATE_INTERVAL = 2
|
||||
|
||||
def __init__(self, app, handler):
|
||||
self.app = app
|
||||
g = self.app.ui.glyphs
|
||||
self.update_interval = MenuDisplay.UPDATE_INTERVAL
|
||||
self.g = self.app.ui.glyphs
|
||||
|
||||
menu_text = ("pack", urwid.Text(g["decoration_menu"]))
|
||||
self.menu_indicator = urwid.Text("")
|
||||
|
||||
menu_text = ("pack", self.menu_indicator)
|
||||
button_network = (11, MenuButton("Network", on_press=handler.show_network))
|
||||
button_conversations = (17, MenuButton("Conversations", on_press=handler.show_conversations))
|
||||
button_directory = (13, MenuButton("Directory", on_press=handler.show_directory))
|
||||
@@ -170,4 +178,25 @@ class MenuDisplay():
|
||||
columns = MenuColumns(buttons, dividechars=1)
|
||||
columns.handler = handler
|
||||
|
||||
self.update_display()
|
||||
|
||||
self.widget = urwid.AttrMap(columns, "menubar")
|
||||
|
||||
def start(self):
|
||||
self.update_display_job()
|
||||
|
||||
def update_display_job(self, event = None, sender = None):
|
||||
self.update_display()
|
||||
self.app.ui.loop.set_alarm_in(self.update_interval, self.update_display_job)
|
||||
|
||||
def update_display(self):
|
||||
if self.app.has_unread_conversations():
|
||||
self.indicate_unread()
|
||||
else:
|
||||
self.indicate_normal()
|
||||
|
||||
def indicate_normal(self):
|
||||
self.menu_indicator.set_text(self.g["decoration_menu"])
|
||||
|
||||
def indicate_unread(self):
|
||||
self.menu_indicator.set_text(self.g["unread_menu"])
|
||||
|
||||
@@ -110,6 +110,12 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
self.parent.browser.retrieve_url(RNS.hexrep(source_hash, delimit=False))
|
||||
show_announce_stream(None)
|
||||
|
||||
def save_node(sender):
|
||||
node_entry = DirectoryEntry(source_hash, display_name=data_str, trust_level=trust_level, hosts_node=True)
|
||||
self.app.directory.remember(node_entry)
|
||||
self.app.ui.main_display.sub_displays.network_display.directory_change_callback()
|
||||
show_announce_stream(None)
|
||||
|
||||
def converse(sender):
|
||||
show_announce_stream(None)
|
||||
try:
|
||||
@@ -133,8 +139,15 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
|
||||
if is_node:
|
||||
type_button = ("weight", 0.45, urwid.Button("Connect", on_press=connect))
|
||||
save_button = ("weight", 0.45, urwid.Button("Save", on_press=save_node))
|
||||
else:
|
||||
type_button = ("weight", 0.45, urwid.Button("Converse", on_press=converse))
|
||||
save_button = None
|
||||
|
||||
if is_node:
|
||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), save_button, ("weight", 0.1, urwid.Text("")), type_button])
|
||||
else:
|
||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button])
|
||||
|
||||
pile_widgets = [
|
||||
urwid.Text("Time : "+ts_string, align="left"),
|
||||
@@ -145,7 +158,7 @@ class AnnounceInfo(urwid.WidgetWrap):
|
||||
urwid.Divider(g["divider1"]),
|
||||
urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"),
|
||||
urwid.Divider(g["divider1"]),
|
||||
urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button])
|
||||
button_columns
|
||||
]
|
||||
|
||||
if is_node:
|
||||
@@ -700,63 +713,69 @@ class NodeInfo(urwid.WidgetWrap):
|
||||
g = self.app.ui.glyphs
|
||||
|
||||
self.dialog_open = False
|
||||
display_name = self.app.node.name
|
||||
if display_name == None:
|
||||
display_name = ""
|
||||
|
||||
t_id = urwid.Text("Addr : "+RNS.hexrep(self.app.node.destination.hash, delimit=False))
|
||||
e_name = urwid.Text("Name : "+display_name)
|
||||
|
||||
def announce_query(sender):
|
||||
def dismiss_dialog(sender):
|
||||
self.dialog_open = False
|
||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
||||
self.parent.left_pile.contents[2] = (NodeInfo(self.app, self.parent), options)
|
||||
|
||||
self.app.node.announce()
|
||||
|
||||
dialog = DialogLineBox(
|
||||
urwid.Pile([
|
||||
urwid.Text("\n\n\nAnnounce Sent\n\n", align="center"),
|
||||
urwid.Button("OK", on_press=dismiss_dialog)
|
||||
]), title=g["info"]
|
||||
)
|
||||
dialog.delegate = self
|
||||
bottom = self
|
||||
|
||||
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
|
||||
overlay = dialog
|
||||
|
||||
self.dialog_open = True
|
||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
||||
self.parent.left_pile.contents[2] = (overlay, options)
|
||||
widget_style = ""
|
||||
|
||||
def show_peer_info(sender):
|
||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
||||
self.parent.left_pile.contents[2] = (LocalPeer(self.app, self.parent), options)
|
||||
|
||||
def connect_query(sender):
|
||||
self.parent.browser.retrieve_url(RNS.hexrep(self.app.node.destination.hash, delimit=False))
|
||||
|
||||
if NodeInfo.announce_timer == None:
|
||||
self.t_last_announce = NodeAnnounceTime(self.app)
|
||||
NodeInfo.announce_timer = self.t_last_announce
|
||||
else:
|
||||
self.t_last_announce = NodeInfo.announce_timer
|
||||
self.t_last_announce.update_time()
|
||||
|
||||
if NodeInfo.links_timer == None:
|
||||
self.t_active_links = NodeActiveConnections(self.app)
|
||||
NodeInfo.links_timer = self.t_active_links
|
||||
else:
|
||||
self.t_active_links = NodeInfo.links_timer
|
||||
self.t_active_links.update_stat()
|
||||
|
||||
announce_button = urwid.Button("Announce Now", on_press=announce_query)
|
||||
connect_button = urwid.Button("Browse", on_press=connect_query)
|
||||
|
||||
widget_style = ""
|
||||
|
||||
if self.app.enable_node:
|
||||
if self.app.node != None:
|
||||
display_name = self.app.node.name
|
||||
else:
|
||||
display_name = None
|
||||
|
||||
if display_name == None:
|
||||
display_name = ""
|
||||
|
||||
t_id = urwid.Text("Addr : "+RNS.hexrep(self.app.node.destination.hash, delimit=False))
|
||||
e_name = urwid.Text("Name : "+display_name)
|
||||
|
||||
def announce_query(sender):
|
||||
def dismiss_dialog(sender):
|
||||
self.dialog_open = False
|
||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
||||
self.parent.left_pile.contents[2] = (NodeInfo(self.app, self.parent), options)
|
||||
|
||||
self.app.node.announce()
|
||||
|
||||
dialog = DialogLineBox(
|
||||
urwid.Pile([
|
||||
urwid.Text("\n\n\nAnnounce Sent\n\n", align="center"),
|
||||
urwid.Button("OK", on_press=dismiss_dialog)
|
||||
]), title=g["info"]
|
||||
)
|
||||
dialog.delegate = self
|
||||
bottom = self
|
||||
|
||||
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
|
||||
overlay = dialog
|
||||
|
||||
self.dialog_open = True
|
||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
||||
self.parent.left_pile.contents[2] = (overlay, options)
|
||||
|
||||
def connect_query(sender):
|
||||
self.parent.browser.retrieve_url(RNS.hexrep(self.app.node.destination.hash, delimit=False))
|
||||
|
||||
if NodeInfo.announce_timer == None:
|
||||
self.t_last_announce = NodeAnnounceTime(self.app)
|
||||
NodeInfo.announce_timer = self.t_last_announce
|
||||
else:
|
||||
self.t_last_announce = NodeInfo.announce_timer
|
||||
self.t_last_announce.update_time()
|
||||
|
||||
if NodeInfo.links_timer == None:
|
||||
self.t_active_links = NodeActiveConnections(self.app)
|
||||
NodeInfo.links_timer = self.t_active_links
|
||||
else:
|
||||
self.t_active_links = NodeInfo.links_timer
|
||||
self.t_active_links.update_stat()
|
||||
|
||||
announce_button = urwid.Button("Announce Now", on_press=announce_query)
|
||||
connect_button = urwid.Button("Browse", on_press=connect_query)
|
||||
|
||||
pile = urwid.Pile([
|
||||
t_id,
|
||||
e_name,
|
||||
@@ -784,8 +803,9 @@ class NodeInfo(urwid.WidgetWrap):
|
||||
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Local Node Info"), widget_style))
|
||||
|
||||
def start(self):
|
||||
self.t_last_announce.start()
|
||||
self.t_active_links.start()
|
||||
if self.app.node != None:
|
||||
self.t_last_announce.start()
|
||||
self.t_active_links.start()
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user