mirror of
https://github.com/markqvist/NomadNet.git
synced 2025-12-17 06:44:21 +01:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b14d42a17c | ||
|
|
51f0048e7c | ||
|
|
c2fb2ca9f8 | ||
|
|
6a4f202624 | ||
|
|
add8b295ec | ||
|
|
f1989cfc6e | ||
|
|
d9bba6fd69 | ||
|
|
4a3c987cef | ||
|
|
026ff7b5c7 | ||
|
|
bcca6be487 | ||
|
|
3181e2124f | ||
|
|
6026f42f34 | ||
|
|
e695cce3ba | ||
|
|
ff45c597f8 | ||
|
|
a4c348529e | ||
|
|
641f326be7 | ||
|
|
014b9faea6 | ||
|
|
ac7eecbd99 | ||
|
|
04376a9f96 | ||
|
|
c004adfb8c | ||
|
|
8b69947098 | ||
|
|
ca730ded3b | ||
|
|
6a460d9600 | ||
|
|
92a49c12c0 | ||
|
|
a876c09b4c | ||
|
|
bf0b08c154 | ||
|
|
77eca5d23e | ||
|
|
ed6ba63317 | ||
|
|
d856f3fd28 | ||
|
|
24d850107d | ||
|
|
9943cad15f | ||
|
|
dcd5f7df95 | ||
|
|
d840ca32ae | ||
|
|
37063932bb | ||
|
|
0ed4e09b82 | ||
|
|
910e527cc7 | ||
|
|
4eef326d6b | ||
|
|
691f4df098 | ||
|
|
407cc8fb5f | ||
|
|
1f7302903a | ||
|
|
5736012f2c | ||
|
|
bb98a512f3 | ||
|
|
ae0d4c6e0c | ||
|
|
2449b39f77 | ||
|
|
e022d469f8 | ||
|
|
a4f665e650 | ||
|
|
19d1d8504f | ||
|
|
276a5f56e1 | ||
|
|
89dd17ece5 | ||
|
|
82bb479957 | ||
|
|
082026ca1b | ||
|
|
df9fccf199 | ||
|
|
efd1d08399 | ||
|
|
a5623978a2 |
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
11
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: ✨ Feature Request or Idea
|
||||||
|
url: https://github.com/markqvist/Reticulum/discussions/new?category=ideas
|
||||||
|
about: Propose and discuss features and ideas
|
||||||
|
- name: 💬 Questions, Help & Discussion
|
||||||
|
about: Ask anything, or get help
|
||||||
|
url: https://github.com/markqvist/Reticulum/discussions/new/choose
|
||||||
|
- name: 📖 Read the Reticulum Manual
|
||||||
|
url: https://markqvist.github.io/Reticulum/manual/
|
||||||
|
about: The complete documentation for Reticulum
|
||||||
35
.github/ISSUE_TEMPLATE/🐛-bug-report.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/🐛-bug-report.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: "\U0001F41B Bug Report"
|
||||||
|
about: Report a reproducible bug
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Read the Contribution Guidelines**
|
||||||
|
Before creating a bug report on this issue tracker, you **must** read the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md). Issues that do not follow the contribution guidelines **will be deleted without comment**.
|
||||||
|
|
||||||
|
- The issue tracker is used by developers of this project. **Do not use it to ask general questions, or for support requests**.
|
||||||
|
- Ideas and feature requests can be made on the [Discussions](https://github.com/markqvist/Reticulum/discussions). **Only** feature requests accepted by maintainers and developers are tracked and included on the issue tracker. **Do not post feature requests here**.
|
||||||
|
- After reading the [Contribution Guidelines](https://github.com/markqvist/Reticulum/blob/master/Contributing.md), delete this section from your bug report.
|
||||||
|
|
||||||
|
**Describe the Bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Describe in detail how to reproduce the bug.
|
||||||
|
|
||||||
|
**Expected Behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Logs & Screenshots**
|
||||||
|
Please include any relevant log output. If applicable, also add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**System Information**
|
||||||
|
- OS and version
|
||||||
|
- Python version
|
||||||
|
- Program version
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM python:3.11-rc-alpine3.14 as build
|
FROM python:3.12-alpine as build
|
||||||
|
|
||||||
RUN apk add --no-cache build-base linux-headers libffi-dev cargo
|
RUN apk add --no-cache build-base linux-headers libffi-dev cargo
|
||||||
|
|
||||||
@@ -8,10 +8,10 @@ ENV PATH="/opt/venv/bin:$PATH"
|
|||||||
RUN pip3 install setuptools-rust pyopenssl cryptography
|
RUN pip3 install setuptools-rust pyopenssl cryptography
|
||||||
|
|
||||||
COPY . /app/
|
COPY . /app/
|
||||||
RUN cd /app/ && python3 setup.py install
|
RUN cd /app/ && pip3 install .
|
||||||
|
|
||||||
# Use multi-stage build, as we don't need rust compilation on the final image
|
# Use multi-stage build, as we don't need rust compilation on the final image
|
||||||
FROM python:3.11-rc-alpine3.14
|
FROM python:3.12-alpine
|
||||||
|
|
||||||
LABEL org.opencontainers.image.documentation="https://github.com/markqvist/NomadNet#nomad-network-daemon-with-docker"
|
LABEL org.opencontainers.image.documentation="https://github.com/markqvist/NomadNet#nomad-network-daemon-with-docker"
|
||||||
|
|
||||||
|
|||||||
32
Dockerfile.build
Normal file
32
Dockerfile.build
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
FROM python:alpine
|
||||||
|
LABEL authors="Petr Blaha petr.blaha@cleverdata.cz"
|
||||||
|
USER root
|
||||||
|
RUN apk update
|
||||||
|
RUN apk add build-base libffi-dev cargo pkgconfig linux-headers py3-virtualenv
|
||||||
|
|
||||||
|
RUN addgroup -S myuser && adduser -S -G myuser myuser
|
||||||
|
USER myuser
|
||||||
|
WORKDIR /home/myuser
|
||||||
|
|
||||||
|
RUN pip install --upgrade pip
|
||||||
|
RUN pip install setuptools-rust pyopenssl cryptography
|
||||||
|
|
||||||
|
|
||||||
|
ENV PATH="/home/myuser/.local/bin:${PATH}"
|
||||||
|
|
||||||
|
################### BEGIN NomadNet ###########################################
|
||||||
|
|
||||||
|
COPY --chown=myuser:myuser requirements.txt requirements.txt
|
||||||
|
|
||||||
|
RUN pip install --user -r requirements.txt
|
||||||
|
|
||||||
|
|
||||||
|
COPY --chown=myuser:myuser . .
|
||||||
|
|
||||||
|
#Python create virtual environment
|
||||||
|
RUN virtualenv /home/myuser/NomadNet/venv
|
||||||
|
RUN source /home/myuser/NomadNet/venv/bin/activate
|
||||||
|
|
||||||
|
RUN make all
|
||||||
|
|
||||||
|
################### END NomadNet ###########################################
|
||||||
6
Dockerfile.howto
Normal file
6
Dockerfile.howto
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Run docker command one by one(all four), it will build NomadNet artifact and copy to dist directory.
|
||||||
|
# No need to build locally and install dependencies
|
||||||
|
docker build -t nomadnetdockerimage -f Dockerfile.build .
|
||||||
|
docker run -d -it --name nomadnetdockercontainer nomadnetdockerimage /bin/sh
|
||||||
|
docker cp nomadnetdockercontainer:/home/myuser/dist .
|
||||||
|
docker rm -f nomadnetdockercontainer
|
||||||
24
README.md
24
README.md
@@ -22,9 +22,6 @@ If you'd rather want to use an LXMF client with a graphical user interface, you
|
|||||||
- An easy to use and bandwidth efficient markup language for writing pages
|
- An easy to use and bandwidth efficient markup language for writing pages
|
||||||
- Page caching in browser
|
- Page caching in browser
|
||||||
|
|
||||||
## Current Status
|
|
||||||
The current version of the program should be considered a beta release. The program works well, but there will most probably be bugs and possibly sub-optimal performance in some scenarios. On the other hand, this is the ideal time to have an influence on the direction of the development of Nomad Network. To do so, join the discussion, report bugs and request features here on the GitHub project.
|
|
||||||
|
|
||||||
## How do I get started?
|
## How do I get started?
|
||||||
The easiest way to install Nomad Network is via pip:
|
The easiest way to install Nomad Network is via pip:
|
||||||
|
|
||||||
@@ -121,6 +118,23 @@ $ docker run -d \
|
|||||||
$ docker run -i ghcr.io/markqvist/nomadnet:master --daemon --console
|
$ docker run -i ghcr.io/markqvist/nomadnet:master --daemon --console
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Tools & Extensions
|
||||||
|
|
||||||
|
Nomad Network is a very flexible and extensible platform, and a variety of community-provided tools, utilities and node-side extensions exist:
|
||||||
|
|
||||||
|
- [NomadForum](https://codeberg.org/AutumnSpark1226/nomadForum) ([GitHub mirror](https://github.com/AutumnSpark1226/nomadForum))
|
||||||
|
- [NomadForecast](https://github.com/faragher/NomadForecast)
|
||||||
|
- [micron-blog](https://github.com/randogoth/micron-blog)
|
||||||
|
- [md2mu](https://github.com/randogoth/md2mu)
|
||||||
|
- [Any2MicronConverter](https://github.com/SebastianObi/Any2MicronConverter)
|
||||||
|
- [Some nomadnet page examples](https://github.com/SebastianObi/NomadNet-Pages)
|
||||||
|
- [More nomadnet page examples](https://github.com/epenguins/NomadNet_pages)
|
||||||
|
- [LXMF-Bot](https://github.com/randogoth/lxmf-bot)
|
||||||
|
- [LXMF Messageboard](https://github.com/chengtripp/lxmf_messageboard)
|
||||||
|
- [LXMEvent](https://github.com/faragher/LXMEvent)
|
||||||
|
- [POPR](https://github.com/faragher/POPR)
|
||||||
|
- [LXMF Tools](https://github.com/SebastianObi/LXMF-Tools)
|
||||||
|
|
||||||
## Help & Discussion
|
## Help & Discussion
|
||||||
|
|
||||||
For help requests, discussion, sharing ideas or anything else related to Nomad Network, please have a look at the [Nomad Network discussions pages](https://github.com/markqvist/Reticulum/discussions/categories/nomad-network).
|
For help requests, discussion, sharing ideas or anything else related to Nomad Network, please have a look at the [Nomad Network discussions pages](https://github.com/markqvist/Reticulum/discussions/categories/nomad-network).
|
||||||
@@ -134,11 +148,11 @@ You can help support the continued development of open, free and private communi
|
|||||||
```
|
```
|
||||||
- Ethereum
|
- Ethereum
|
||||||
```
|
```
|
||||||
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
|
0xFDabC71AC4c0C78C95aDDDe3B4FA19d6273c5E73
|
||||||
```
|
```
|
||||||
- Bitcoin
|
- Bitcoin
|
||||||
```
|
```
|
||||||
3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq
|
35G9uWVzrpJJibzUwpNUQGQNFzLirhrYAH
|
||||||
```
|
```
|
||||||
- Ko-Fi: https://ko-fi.com/markqvist
|
- Ko-Fi: https://ko-fi.com/markqvist
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ class Conversation:
|
|||||||
|
|
||||||
self.__changed_callback = None
|
self.__changed_callback = None
|
||||||
|
|
||||||
if not RNS.Transport.has_path(bytes.fromhex(source_hash)):
|
if not RNS.Identity.recall(bytes.fromhex(self.source_hash)):
|
||||||
RNS.Transport.request_path(bytes.fromhex(source_hash))
|
RNS.Transport.request_path(bytes.fromhex(source_hash))
|
||||||
|
|
||||||
self.source_identity = RNS.Identity.recall(bytes.fromhex(self.source_hash))
|
self.source_identity = RNS.Identity.recall(bytes.fromhex(self.source_hash))
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ class Directory:
|
|||||||
|
|
||||||
entries = {}
|
entries = {}
|
||||||
for e in unpacked_list:
|
for e in unpacked_list:
|
||||||
|
|
||||||
|
if e[1] == None:
|
||||||
|
e[1] = "Undefined"
|
||||||
|
|
||||||
if len(e) > 3:
|
if len(e) > 3:
|
||||||
hosts_node = e[3]
|
hosts_node = e[3]
|
||||||
else:
|
else:
|
||||||
@@ -254,11 +257,12 @@ class Directory:
|
|||||||
if announced_display_name == None:
|
if announced_display_name == None:
|
||||||
return self.directory_entries[source_hash].trust_level
|
return self.directory_entries[source_hash].trust_level
|
||||||
else:
|
else:
|
||||||
for entry in self.directory_entries:
|
if not self.directory_entries[source_hash].trust_level == DirectoryEntry.TRUSTED:
|
||||||
e = self.directory_entries[entry]
|
for entry in self.directory_entries:
|
||||||
if e.display_name == announced_display_name:
|
e = self.directory_entries[entry]
|
||||||
if e.source_hash != source_hash:
|
if e.display_name == announced_display_name:
|
||||||
return DirectoryEntry.WARNING
|
if e.source_hash != source_hash:
|
||||||
|
return DirectoryEntry.WARNING
|
||||||
|
|
||||||
return self.directory_entries[source_hash].trust_level
|
return self.directory_entries[source_hash].trust_level
|
||||||
else:
|
else:
|
||||||
@@ -375,4 +379,4 @@ class DirectoryEntry:
|
|||||||
self.hosts_node = hosts_node
|
self.hosts_node = hosts_node
|
||||||
self.identify = identify_on_connect
|
self.identify = identify_on_connect
|
||||||
else:
|
else:
|
||||||
raise TypeError("Attempt to add invalid source hash to directory")
|
raise TypeError("Attempt to add invalid source hash to directory")
|
||||||
|
|||||||
@@ -15,7 +15,11 @@ class Node:
|
|||||||
self.identity = self.app.identity
|
self.identity = self.app.identity
|
||||||
self.destination = RNS.Destination(self.identity, RNS.Destination.IN, RNS.Destination.SINGLE, "nomadnetwork", "node")
|
self.destination = RNS.Destination(self.identity, RNS.Destination.IN, RNS.Destination.SINGLE, "nomadnetwork", "node")
|
||||||
self.last_announce = time.time()
|
self.last_announce = time.time()
|
||||||
|
self.last_file_refresh = time.time()
|
||||||
|
self.last_page_refresh = time.time()
|
||||||
self.announce_interval = self.app.node_announce_interval
|
self.announce_interval = self.app.node_announce_interval
|
||||||
|
self.page_refresh_interval = self.app.page_refresh_interval
|
||||||
|
self.file_refresh_interval = self.app.file_refresh_interval
|
||||||
self.job_interval = Node.JOB_INTERVAL
|
self.job_interval = Node.JOB_INTERVAL
|
||||||
self.should_run_jobs = True
|
self.should_run_jobs = True
|
||||||
self.app_data = None
|
self.app_data = None
|
||||||
@@ -46,6 +50,8 @@ class Node:
|
|||||||
|
|
||||||
|
|
||||||
def register_pages(self):
|
def register_pages(self):
|
||||||
|
# TODO: Deregister previously registered pages
|
||||||
|
# that no longer exist.
|
||||||
self.servedpages = []
|
self.servedpages = []
|
||||||
self.scan_pages(self.app.pagespath)
|
self.scan_pages(self.app.pagespath)
|
||||||
|
|
||||||
@@ -65,6 +71,8 @@ class Node:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def register_files(self):
|
def register_files(self):
|
||||||
|
# TODO: Deregister previously registered files
|
||||||
|
# that no longer exist.
|
||||||
self.servedfiles = []
|
self.servedfiles = []
|
||||||
self.scan_files(self.app.filespath)
|
self.scan_files(self.app.filespath)
|
||||||
|
|
||||||
@@ -222,6 +230,16 @@ class Node:
|
|||||||
|
|
||||||
if now > self.last_announce + self.announce_interval*60:
|
if now > self.last_announce + self.announce_interval*60:
|
||||||
self.announce()
|
self.announce()
|
||||||
|
|
||||||
|
if self.page_refresh_interval > 0:
|
||||||
|
if now > self.last_page_refresh + self.page_refresh_interval*60:
|
||||||
|
self.register_pages()
|
||||||
|
self.last_page_refresh = time.time()
|
||||||
|
|
||||||
|
if self.file_refresh_interval > 0:
|
||||||
|
if now > self.last_file_refresh + self.file_refresh_interval*60:
|
||||||
|
self.register_files()
|
||||||
|
self.last_file_refresh = time.time()
|
||||||
|
|
||||||
time.sleep(self.job_interval)
|
time.sleep(self.job_interval)
|
||||||
|
|
||||||
|
|||||||
@@ -115,14 +115,20 @@ class NomadNetworkApp:
|
|||||||
|
|
||||||
self.downloads_path = os.path.expanduser("~/Downloads")
|
self.downloads_path = os.path.expanduser("~/Downloads")
|
||||||
|
|
||||||
self.firstrun = False
|
self.firstrun = False
|
||||||
self.should_run_jobs = True
|
self.should_run_jobs = True
|
||||||
self.job_interval = 5
|
self.job_interval = 5
|
||||||
self.defer_jobs = 90
|
self.defer_jobs = 90
|
||||||
|
self.page_refresh_interval = 0
|
||||||
|
self.file_refresh_interval = 0
|
||||||
|
|
||||||
self.peer_announce_at_start = True
|
self.peer_announce_at_start = True
|
||||||
self.try_propagation_on_fail = True
|
self.try_propagation_on_fail = True
|
||||||
self.disable_propagation = False
|
self.disable_propagation = False
|
||||||
|
self.notify_on_new_message = True
|
||||||
|
|
||||||
|
self.lxmf_max_propagation_size = None
|
||||||
|
self.lxmf_max_incoming_size = None
|
||||||
|
|
||||||
self.periodic_lxmf_sync = True
|
self.periodic_lxmf_sync = True
|
||||||
self.lxmf_sync_interval = 360*60
|
self.lxmf_sync_interval = 360*60
|
||||||
@@ -280,7 +286,11 @@ class NomadNetworkApp:
|
|||||||
|
|
||||||
self.directory = nomadnet.Directory(self)
|
self.directory = nomadnet.Directory(self)
|
||||||
|
|
||||||
self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.storagepath, autopeer = True)
|
self.message_router = LXMF.LXMRouter(
|
||||||
|
identity = self.identity, storagepath = self.storagepath, autopeer = True,
|
||||||
|
propagation_limit = self.lxmf_max_propagation_size, delivery_limit = self.lxmf_max_incoming_size,
|
||||||
|
)
|
||||||
|
|
||||||
self.message_router.register_delivery_callback(self.lxmf_delivery)
|
self.message_router.register_delivery_callback(self.lxmf_delivery)
|
||||||
|
|
||||||
for destination_hash in self.ignored_list:
|
for destination_hash in self.ignored_list:
|
||||||
@@ -427,16 +437,24 @@ class NomadNetworkApp:
|
|||||||
return "Receiving messages"
|
return "Receiving messages"
|
||||||
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_RESPONSE_RECEIVED:
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_RESPONSE_RECEIVED:
|
||||||
return "Messages received"
|
return "Messages received"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_NO_PATH:
|
||||||
|
return "No path to node"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_LINK_FAILED:
|
||||||
|
return "Link establisment failed"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_TRANSFER_FAILED:
|
||||||
|
return "Sync request failed"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_NO_IDENTITY_RCVD:
|
||||||
|
return "Remote got no identity"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_NO_ACCESS:
|
||||||
|
return "Node rejected request"
|
||||||
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_FAILED:
|
||||||
|
return "Sync failed"
|
||||||
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_COMPLETE:
|
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_COMPLETE:
|
||||||
new_msgs = self.message_router.propagation_transfer_last_result
|
new_msgs = self.message_router.propagation_transfer_last_result
|
||||||
if new_msgs == 0:
|
if new_msgs == 0:
|
||||||
return "Done, no new messages"
|
return "Done, no new messages"
|
||||||
else:
|
else:
|
||||||
return "Downloaded "+str(new_msgs)+" new messages"
|
return "Downloaded "+str(new_msgs)+" new messages"
|
||||||
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_NO_IDENTITY_RCVD:
|
|
||||||
return "Node did not receive identification"
|
|
||||||
elif self.message_router.propagation_transfer_state == LXMF.LXMRouter.PR_NO_ACCESS:
|
|
||||||
return "Node did not allow request"
|
|
||||||
else:
|
else:
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
|
|
||||||
@@ -536,6 +554,9 @@ class NomadNetworkApp:
|
|||||||
|
|
||||||
nomadnet.Conversation.ingest(message, self)
|
nomadnet.Conversation.ingest(message, self)
|
||||||
|
|
||||||
|
if self.notify_on_new_message:
|
||||||
|
self.notify_message_recieved()
|
||||||
|
|
||||||
if self.should_print(message):
|
if self.should_print(message):
|
||||||
self.print_message(message)
|
self.print_message(message)
|
||||||
|
|
||||||
@@ -639,6 +660,11 @@ class NomadNetworkApp:
|
|||||||
if os.path.isfile(self.conversationpath + "/" + source_hash + "/unread"):
|
if os.path.isfile(self.conversationpath + "/" + source_hash + "/unread"):
|
||||||
os.unlink(self.conversationpath + "/" + source_hash + "/unread")
|
os.unlink(self.conversationpath + "/" + source_hash + "/unread")
|
||||||
|
|
||||||
|
def notify_message_recieved(self):
|
||||||
|
if self.uimode == nomadnet.ui.UI_TEXT:
|
||||||
|
sys.stdout.write("\a")
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
def clear_tmp_dir(self):
|
def clear_tmp_dir(self):
|
||||||
if os.path.isdir(self.tmpfilespath):
|
if os.path.isdir(self.tmpfilespath):
|
||||||
for file in os.listdir(self.tmpfilespath):
|
for file in os.listdir(self.tmpfilespath):
|
||||||
@@ -712,10 +738,22 @@ class NomadNetworkApp:
|
|||||||
else:
|
else:
|
||||||
self.lxmf_sync_limit = None
|
self.lxmf_sync_limit = None
|
||||||
|
|
||||||
|
if option == "max_accepted_size":
|
||||||
|
value = self.config["client"].as_float(option)
|
||||||
|
|
||||||
|
if value > 0:
|
||||||
|
self.lxmf_max_incoming_size = value
|
||||||
|
else:
|
||||||
|
self.lxmf_max_incoming_size = 500
|
||||||
|
|
||||||
if option == "compact_announce_stream":
|
if option == "compact_announce_stream":
|
||||||
value = self.config["client"].as_bool(option)
|
value = self.config["client"].as_bool(option)
|
||||||
self.compact_stream = value
|
self.compact_stream = value
|
||||||
|
|
||||||
|
if option == "notify_on_new_message":
|
||||||
|
value = self.config["client"].as_bool(option)
|
||||||
|
self.notify_on_new_message = value
|
||||||
|
|
||||||
if option == "user_interface":
|
if option == "user_interface":
|
||||||
value = value.lower()
|
value = value.lower()
|
||||||
if value == "none":
|
if value == "none":
|
||||||
@@ -806,6 +844,14 @@ class NomadNetworkApp:
|
|||||||
else:
|
else:
|
||||||
self.disable_propagation = self.config["node"].as_bool("disable_propagation")
|
self.disable_propagation = self.config["node"].as_bool("disable_propagation")
|
||||||
|
|
||||||
|
if not "max_transfer_size" in self.config["node"]:
|
||||||
|
self.lxmf_max_propagation_size = 256
|
||||||
|
else:
|
||||||
|
value = self.config["node"].as_float("max_transfer_size")
|
||||||
|
if value < 1:
|
||||||
|
value = 1
|
||||||
|
self.lxmf_max_propagation_size = value
|
||||||
|
|
||||||
if not "announce_at_start" in self.config["node"]:
|
if not "announce_at_start" in self.config["node"]:
|
||||||
self.node_announce_at_start = False
|
self.node_announce_at_start = False
|
||||||
else:
|
else:
|
||||||
@@ -819,12 +865,30 @@ class NomadNetworkApp:
|
|||||||
if value < 1:
|
if value < 1:
|
||||||
value = 1
|
value = 1
|
||||||
self.node_announce_interval = value
|
self.node_announce_interval = value
|
||||||
|
|
||||||
if "pages_path" in self.config["node"]:
|
if "pages_path" in self.config["node"]:
|
||||||
self.pagespath = self.config["node"]["pages_path"]
|
self.pagespath = self.config["node"]["pages_path"]
|
||||||
|
|
||||||
|
if not "page_refresh_interval" in self.config["node"]:
|
||||||
|
self.page_refresh_interval = 0
|
||||||
|
else:
|
||||||
|
value = self.config["node"].as_int("page_refresh_interval")
|
||||||
|
if value < 0:
|
||||||
|
value = 0
|
||||||
|
self.page_refresh_interval = value
|
||||||
|
|
||||||
|
|
||||||
if "files_path" in self.config["node"]:
|
if "files_path" in self.config["node"]:
|
||||||
self.filespath = self.config["node"]["files_path"]
|
self.filespath = self.config["node"]["files_path"]
|
||||||
|
|
||||||
|
if not "file_refresh_interval" in self.config["node"]:
|
||||||
|
self.file_refresh_interval = 0
|
||||||
|
else:
|
||||||
|
value = self.config["node"].as_int("file_refresh_interval")
|
||||||
|
if value < 0:
|
||||||
|
value = 0
|
||||||
|
self.file_refresh_interval = value
|
||||||
|
|
||||||
|
|
||||||
if "prioritise_destinations" in self.config["node"]:
|
if "prioritise_destinations" in self.config["node"]:
|
||||||
self.prioritised_lxmf_destinations = self.config["node"].as_list("prioritise_destinations")
|
self.prioritised_lxmf_destinations = self.config["node"].as_list("prioritise_destinations")
|
||||||
@@ -925,6 +989,7 @@ destination = file
|
|||||||
enable_client = yes
|
enable_client = yes
|
||||||
user_interface = text
|
user_interface = text
|
||||||
downloads_path = ~/Downloads
|
downloads_path = ~/Downloads
|
||||||
|
notify_on_new_message = yes
|
||||||
|
|
||||||
# By default, the peer is announced at startup
|
# By default, the peer is announced at startup
|
||||||
# to let other peers reach it immediately.
|
# to let other peers reach it immediately.
|
||||||
@@ -952,6 +1017,13 @@ lxmf_sync_interval = 360
|
|||||||
# the limit, and download everything every time.
|
# the limit, and download everything every time.
|
||||||
lxmf_sync_limit = 8
|
lxmf_sync_limit = 8
|
||||||
|
|
||||||
|
# The maximum accepted unpacked size for mes-
|
||||||
|
# sages received directly from other peers,
|
||||||
|
# specified in kilobytes. Messages larger than
|
||||||
|
# this will be rejected before the transfer
|
||||||
|
# begins.
|
||||||
|
max_accepted_size = 500
|
||||||
|
|
||||||
# The announce stream will only show one entry
|
# The announce stream will only show one entry
|
||||||
# per destination or node by default. You can
|
# per destination or node by default. You can
|
||||||
# change this to show as many announces as have
|
# change this to show as many announces as have
|
||||||
@@ -1040,6 +1112,18 @@ announce_at_start = Yes
|
|||||||
# and defaults to 2 gigabytes.
|
# and defaults to 2 gigabytes.
|
||||||
# message_storage_limit = 2000
|
# message_storage_limit = 2000
|
||||||
|
|
||||||
|
# The maximum accepted transfer size per in-
|
||||||
|
# coming propagation transfer, in kilobytes.
|
||||||
|
# This also sets the upper limit for the size
|
||||||
|
# of single messages accepted onto this node.
|
||||||
|
#
|
||||||
|
# If a node wants to propagate a larger number
|
||||||
|
# of messages to this node, than what can fit
|
||||||
|
# within this limit, it will prioritise sending
|
||||||
|
# the smallest, newest messages first, and try
|
||||||
|
# with any remaining messages at a later point.
|
||||||
|
max_transfer_size = 256
|
||||||
|
|
||||||
# You can tell the LXMF message router to
|
# You can tell the LXMF message router to
|
||||||
# prioritise storage for one or more
|
# prioritise storage for one or more
|
||||||
# destinations. If the message store reaches
|
# destinations. If the message store reaches
|
||||||
@@ -1049,6 +1133,22 @@ announce_at_start = Yes
|
|||||||
# and generally you do not need to use it.
|
# and generally you do not need to use it.
|
||||||
# prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf
|
# prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf
|
||||||
|
|
||||||
|
# Automatic rescan interval of the pages directory in minutes.
|
||||||
|
# Default: int = 0 (no rescan)
|
||||||
|
page_refresh_interval = 0
|
||||||
|
|
||||||
|
# You can specify the interval in minutes for
|
||||||
|
# rescanning the hosted pages path. By default,
|
||||||
|
# this option is disabled, and the pages path
|
||||||
|
# will only be scanned on startup.
|
||||||
|
# page_refresh_interval = 0
|
||||||
|
|
||||||
|
# You can specify the interval in minutes for
|
||||||
|
# rescanning the hosted files path. By default,
|
||||||
|
# this option is disabled, and the files path
|
||||||
|
# will only be scanned on startup.
|
||||||
|
# file_refresh_interval = 0
|
||||||
|
|
||||||
[printing]
|
[printing]
|
||||||
|
|
||||||
# You can configure Nomad Network to print
|
# You can configure Nomad Network to print
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = "0.4.0"
|
__version__ = "0.4.9"
|
||||||
|
|||||||
@@ -97,10 +97,10 @@ GLYPHSETS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if platform.system() == "Darwin":
|
if platform.system() == "Darwin":
|
||||||
urm_char = " \uf0e0 "
|
urm_char = " \uf0e0"
|
||||||
ur_char = "\uf0e0 "
|
ur_char = "\uf0e0 "
|
||||||
else:
|
else:
|
||||||
urm_char = " \uf003 "
|
urm_char = " \uf003"
|
||||||
ur_char = "\uf003 "
|
ur_char = "\uf003 "
|
||||||
|
|
||||||
GLYPHS = {
|
GLYPHS = {
|
||||||
@@ -115,17 +115,17 @@ GLYPHS = {
|
|||||||
("arrow_u", "/\\", "\u2191", "\u2191"),
|
("arrow_u", "/\\", "\u2191", "\u2191"),
|
||||||
("arrow_d", "\\/", "\u2193", "\u2193"),
|
("arrow_d", "\\/", "\u2193", "\u2193"),
|
||||||
("warning", "!", "\u26a0", "\uf12a"),
|
("warning", "!", "\u26a0", "\uf12a"),
|
||||||
("info", "i", "\u2139", "\ufb4d"),
|
("info", "i", "\u2139", "\U000f064e"),
|
||||||
("unread", "[!]", "\u2709", ur_char),
|
("unread", "[!]", "\u2709", ur_char),
|
||||||
("divider1", "-", "\u2504", "\u2504"),
|
("divider1", "-", "\u2504", "\u2504"),
|
||||||
("peer", "[P]", "\u24c5 ", "\uf415"),
|
("peer", "[P]", "\u24c5 ", "\uf415"),
|
||||||
("node", "[N]", "\u24c3 ", "\uf502"),
|
("node", "[N]", "\u24c3 ", "\U000f0002"),
|
||||||
("page", "", "\u25a4 ", "\uf719 "),
|
("page", "", "\u25a4 ", "\uf719 "),
|
||||||
("speed", "", "\u25F7 ", "\uf9c4"),
|
("speed", "", "\u25F7 ", "\U000f04c5 "),
|
||||||
("decoration_menu", " +", " +", " \uf93a"),
|
("decoration_menu", " +", " +", " \U000f043b"),
|
||||||
("unread_menu", " !", " \u2709", urm_char),
|
("unread_menu", " !", " \u2709", urm_char),
|
||||||
("globe", "", "", "\uf484"),
|
("globe", "", "", "\uf484"),
|
||||||
("sent", "/\\", "\u2191", "\ufbf4"),
|
("sent", "/\\", "\u2191", "\U000f0cd8"),
|
||||||
("papermsg", "P", "\u25a4", "\uf719"),
|
("papermsg", "P", "\u25a4", "\uf719"),
|
||||||
("qrcode", "QR", "\u25a4", "\uf029"),
|
("qrcode", "QR", "\u25a4", "\uf029"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ class BrowserFrame(urwid.Frame):
|
|||||||
self.delegate.save_node_dialog()
|
self.delegate.save_node_dialog()
|
||||||
elif key == "ctrl g":
|
elif key == "ctrl g":
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.toggle_fullscreen()
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.toggle_fullscreen()
|
||||||
elif self.get_focus() == "body":
|
elif self.focus_position == "body":
|
||||||
if key == "down" or key == "up":
|
if key == "down" or key == "up":
|
||||||
try:
|
try:
|
||||||
if hasattr(self.delegate, "page_pile") and self.delegate.page_pile:
|
if hasattr(self.delegate, "page_pile") and self.delegate.page_pile:
|
||||||
def df(loop, user_data):
|
def df(loop, user_data):
|
||||||
st = None
|
st = None
|
||||||
nf = self.delegate.page_pile.get_focus()
|
nf = self.delegate.page_pile.focus
|
||||||
if hasattr(nf, "key_timeout"):
|
if hasattr(nf, "key_timeout"):
|
||||||
st = nf
|
st = nf
|
||||||
elif hasattr(nf, "original_widget"):
|
elif hasattr(nf, "original_widget"):
|
||||||
@@ -279,7 +279,10 @@ class Browser:
|
|||||||
self.browser_footer = urwid.Text("")
|
self.browser_footer = urwid.Text("")
|
||||||
|
|
||||||
self.page_pile = None
|
self.page_pile = None
|
||||||
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
|
self.browser_body = urwid.Filler(
|
||||||
|
urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align=urwid.CENTER),
|
||||||
|
urwid.MIDDLE,
|
||||||
|
)
|
||||||
|
|
||||||
self.frame = BrowserFrame(self.browser_body, header=self.browser_header, footer=self.browser_footer)
|
self.frame = BrowserFrame(self.browser_body, header=self.browser_header, footer=self.browser_footer)
|
||||||
self.frame.delegate = self
|
self.frame.delegate = self
|
||||||
@@ -306,28 +309,29 @@ class Browser:
|
|||||||
self.update_display()
|
self.update_display()
|
||||||
|
|
||||||
columns = urwid.Columns([
|
columns = urwid.Columns([
|
||||||
("weight", 0.5, urwid.Text(" ")),
|
(urwid.WEIGHT, 0.5, urwid.Text(" ")),
|
||||||
(8, urwid.Button("Back", on_press=back_action)),
|
(8, urwid.Button("Back", on_press=back_action)),
|
||||||
("weight", 0.5, urwid.Text(" "))
|
(urwid.WEIGHT, 0.5, urwid.Text(" ")),
|
||||||
])
|
])
|
||||||
|
|
||||||
if len(self.attr_maps) > 0:
|
if len(self.attr_maps) > 0:
|
||||||
pile = urwid.Pile([
|
pile = urwid.Pile([
|
||||||
urwid.Text("!\n\n"+self.status_text()+"\n", align="center"),
|
urwid.Text("!\n\n"+self.status_text()+"\n", align=urwid.CENTER),
|
||||||
columns
|
columns
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
pile = urwid.Pile([
|
pile = urwid.Pile([urwid.Text("!\n\n"+self.status_text(), align=urwid.CENTER)])
|
||||||
urwid.Text("!\n\n"+self.status_text(), align="center")
|
|
||||||
])
|
|
||||||
|
|
||||||
return urwid.Filler(pile, "middle")
|
return urwid.Filler(pile, urwid.MIDDLE)
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
if self.status == Browser.DISCONECTED:
|
if self.status == Browser.DISCONECTED:
|
||||||
self.display_widget.set_attr_map({None: "inactive_text"})
|
self.display_widget.set_attr_map({None: "inactive_text"})
|
||||||
self.page_pile = None
|
self.page_pile = None
|
||||||
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
|
self.browser_body = urwid.Filler(
|
||||||
|
urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align=urwid.CENTER),
|
||||||
|
urwid.MIDDLE,
|
||||||
|
)
|
||||||
self.browser_footer = urwid.Text("")
|
self.browser_footer = urwid.Text("")
|
||||||
self.browser_header = urwid.Text("")
|
self.browser_header = urwid.Text("")
|
||||||
self.linebox.set_title("Remote Node")
|
self.linebox.set_title("Remote Node")
|
||||||
@@ -354,7 +358,10 @@ class Browser:
|
|||||||
|
|
||||||
elif self.status <= Browser.REQUEST_SENT:
|
elif self.status <= Browser.REQUEST_SENT:
|
||||||
if len(self.attr_maps) == 0:
|
if len(self.attr_maps) == 0:
|
||||||
self.browser_body = urwid.Filler(urwid.Text("Retrieving\n["+self.current_url()+"]", align="center"), "middle")
|
self.browser_body = urwid.Filler(
|
||||||
|
urwid.Text("Retrieving\n["+self.current_url()+"]", align=urwid.CENTER),
|
||||||
|
urwid.MIDDLE,
|
||||||
|
)
|
||||||
|
|
||||||
self.browser_footer = self.make_status_widget()
|
self.browser_footer = self.make_status_widget()
|
||||||
|
|
||||||
@@ -517,7 +524,7 @@ class Browser:
|
|||||||
self.status = Browser.PATH_REQUESTED
|
self.status = Browser.PATH_REQUESTED
|
||||||
self.update_display()
|
self.update_display()
|
||||||
|
|
||||||
pr_time = time.time()
|
pr_time = time.time()+RNS.Transport.first_hop_timeout(self.destination_hash)
|
||||||
while not RNS.Transport.has_path(self.destination_hash):
|
while not RNS.Transport.has_path(self.destination_hash):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if now > pr_time+self.timeout:
|
if now > pr_time+self.timeout:
|
||||||
@@ -608,7 +615,7 @@ class Browser:
|
|||||||
self.load_page()
|
self.load_page()
|
||||||
|
|
||||||
def close_dialogs(self):
|
def close_dialogs(self):
|
||||||
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
|
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
|
||||||
self.delegate.columns.contents[1] = (self.display_widget, options)
|
self.delegate.columns.contents[1] = (self.display_widget, options)
|
||||||
|
|
||||||
def url_dialog(self):
|
def url_dialog(self):
|
||||||
@@ -629,7 +636,11 @@ class Browser:
|
|||||||
dialog = UrlDialogLineBox(
|
dialog = UrlDialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
e_url,
|
e_url,
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Go", on_press=confirmed))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Go", on_press=confirmed)),
|
||||||
|
])
|
||||||
]), title="Enter URL"
|
]), title="Enter URL"
|
||||||
)
|
)
|
||||||
e_url.confirmed = confirmed
|
e_url.confirmed = confirmed
|
||||||
@@ -637,46 +648,72 @@ class Browser:
|
|||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.display_widget
|
bottom = self.display_widget
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 65), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=(urwid.RELATIVE, 65),
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
|
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
|
||||||
self.delegate.columns.contents[1] = (overlay, options)
|
self.delegate.columns.contents[1] = (overlay, options)
|
||||||
self.delegate.columns.focus_position = 1
|
self.delegate.columns.focus_position = 1
|
||||||
|
|
||||||
def save_node_dialog(self):
|
def save_node_dialog(self):
|
||||||
def dismiss_dialog(sender):
|
if self.destination_hash != None:
|
||||||
self.close_dialogs()
|
try:
|
||||||
|
def dismiss_dialog(sender):
|
||||||
|
self.close_dialogs()
|
||||||
|
|
||||||
display_name = RNS.Identity.recall_app_data(self.destination_hash)
|
display_name = RNS.Identity.recall_app_data(self.destination_hash)
|
||||||
disp_str = ""
|
disp_str = ""
|
||||||
if display_name != None:
|
if display_name != None:
|
||||||
display_name = display_name.decode("utf-8")
|
display_name = display_name.decode("utf-8")
|
||||||
disp_str = " \""+display_name+"\""
|
disp_str = " \""+display_name+"\""
|
||||||
|
|
||||||
def confirmed(sender):
|
def confirmed(sender):
|
||||||
node_entry = DirectoryEntry(self.destination_hash, display_name=display_name, hosts_node=True)
|
node_entry = DirectoryEntry(self.destination_hash, display_name=display_name, hosts_node=True)
|
||||||
self.app.directory.remember(node_entry)
|
self.app.directory.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()
|
||||||
|
|
||||||
self.close_dialogs()
|
self.close_dialogs()
|
||||||
|
|
||||||
dialog = UrlDialogLineBox(
|
dialog = UrlDialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Save connected node"+disp_str+" "+RNS.prettyhexrep(self.destination_hash)+" to Known Nodes?\n"),
|
urwid.Text("Save connected node"+disp_str+" "+RNS.prettyhexrep(self.destination_hash)+" to Known Nodes?\n"),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Save", on_press=confirmed))])
|
urwid.Columns([
|
||||||
]), title="Save Node"
|
(urwid.WEIGHT, 0.45, urwid.Button("Cancel", on_press=dismiss_dialog)),
|
||||||
)
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=confirmed)),
|
||||||
|
])
|
||||||
|
]), title="Save Node"
|
||||||
|
)
|
||||||
|
|
||||||
dialog.confirmed = confirmed
|
dialog.confirmed = confirmed
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.display_widget
|
bottom = self.display_widget
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 50), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=(urwid.RELATIVE, 50),
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.delegate.columns.options("weight", self.delegate.right_area_width)
|
options = self.delegate.columns.options(urwid.WEIGHT, self.delegate.right_area_width)
|
||||||
self.delegate.columns.contents[1] = (overlay, options)
|
self.delegate.columns.contents[1] = (overlay, options)
|
||||||
self.delegate.columns.focus_position = 1
|
self.delegate.columns.focus_position = 1
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
|
||||||
def load_page(self):
|
def load_page(self):
|
||||||
if self.request_data == None:
|
if self.request_data == None:
|
||||||
@@ -770,7 +807,7 @@ class Browser:
|
|||||||
self.status = Browser.PATH_REQUESTED
|
self.status = Browser.PATH_REQUESTED
|
||||||
self.update_display()
|
self.update_display()
|
||||||
|
|
||||||
pr_time = time.time()
|
pr_time = time.time()+RNS.Transport.first_hop_timeout(self.destination_hash)
|
||||||
while not RNS.Transport.has_path(self.destination_hash):
|
while not RNS.Transport.has_path(self.destination_hash):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if now > pr_time+self.timeout:
|
if now > pr_time+self.timeout:
|
||||||
@@ -976,7 +1013,10 @@ class Browser:
|
|||||||
try:
|
try:
|
||||||
file_name = request_receipt.response[0]
|
file_name = request_receipt.response[0]
|
||||||
file_data = request_receipt.response[1]
|
file_data = request_receipt.response[1]
|
||||||
file_destination = self.app.downloads_path+"/"+file_name
|
file_destination_name = file_name.split("/")
|
||||||
|
file_destination_name = file_destination_name[len(file_destination_name)-1]
|
||||||
|
file_destination = self.app.downloads_path+"/"+file_destination_name
|
||||||
|
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
while os.path.isfile(file_destination):
|
while os.path.isfile(file_destination):
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ class ConfigDisplayShortcuts():
|
|||||||
class ConfigFiller(urwid.WidgetWrap):
|
class ConfigFiller(urwid.WidgetWrap):
|
||||||
def __init__(self, widget, app):
|
def __init__(self, widget, app):
|
||||||
self.app = app
|
self.app = app
|
||||||
self.filler = urwid.Filler(widget, "top")
|
self.filler = urwid.Filler(widget, urwid.TOP)
|
||||||
urwid.WidgetWrap.__init__(self, self.filler)
|
super().__init__(self.filler)
|
||||||
|
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up":
|
if key == "up":
|
||||||
self.app.ui.main_display.frame.set_focus("header")
|
self.app.ui.main_display.frame.focus_position = "header"
|
||||||
|
|
||||||
return super(ConfigFiller, self).keypress(size, key)
|
return super(ConfigFiller, self).keypress(size, key)
|
||||||
|
|
||||||
@@ -31,12 +31,20 @@ class ConfigDisplay():
|
|||||||
self.editor_term = EditorTerminal(self.app, self)
|
self.editor_term = EditorTerminal(self.app, self)
|
||||||
self.widget = urwid.LineBox(self.editor_term)
|
self.widget = urwid.LineBox(self.editor_term)
|
||||||
self.app.ui.main_display.update_active_sub_display()
|
self.app.ui.main_display.update_active_sub_display()
|
||||||
self.app.ui.main_display.frame.set_focus("body")
|
self.app.ui.main_display.frame.focus_position = "body"
|
||||||
self.editor_term.term.change_focus(True)
|
self.editor_term.term.change_focus(True)
|
||||||
|
|
||||||
pile = urwid.Pile([
|
pile = urwid.Pile([
|
||||||
urwid.Text(("body_text", "\nTo change the configuration, edit the config file located at:\n\n"+self.app.configpath+"\n\nRestart Nomad Network for changes to take effect\n"), align="center"),
|
urwid.Text(
|
||||||
urwid.Padding(urwid.Button("Open Editor", on_press=open_editor), width=15, align="center"),
|
(
|
||||||
|
"body_text",
|
||||||
|
"\nTo change the configuration, edit the config file located at:\n\n"
|
||||||
|
+self.app.configpath
|
||||||
|
+"\n\nRestart Nomad Network for changes to take effect\n",
|
||||||
|
),
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
urwid.Padding(urwid.Button("Open Editor", on_press=open_editor), width=15, align=urwid.CENTER),
|
||||||
])
|
])
|
||||||
|
|
||||||
self.config_explainer = ConfigFiller(pile, self.app)
|
self.config_explainer = ConfigFiller(pile, self.app)
|
||||||
@@ -71,11 +79,11 @@ class EditorTerminal(urwid.WidgetWrap):
|
|||||||
|
|
||||||
urwid.connect_signal(self.term, 'closed', quit_term)
|
urwid.connect_signal(self.term, 'closed', quit_term)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.term)
|
super().__init__(self.term)
|
||||||
|
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
# TODO: Decide whether there should be a way to get out while editing
|
# TODO: Decide whether there should be a way to get out while editing
|
||||||
#if key == "up":
|
#if key == "up":
|
||||||
# nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
# nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
return super(EditorTerminal, self).keypress(size, key)
|
return super(EditorTerminal, self).keypress(size, key)
|
||||||
@@ -37,9 +37,9 @@ class ConversationsArea(urwid.LineBox):
|
|||||||
elif key == "ctrl g":
|
elif key == "ctrl g":
|
||||||
self.delegate.toggle_fullscreen()
|
self.delegate.toggle_fullscreen()
|
||||||
elif key == "tab":
|
elif key == "tab":
|
||||||
self.delegate.app.ui.main_display.frame.set_focus("header")
|
self.delegate.app.ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "up" and (self.delegate.ilb.first_item_is_selected() or self.delegate.ilb.body_is_empty()):
|
elif key == "up" and (self.delegate.ilb.first_item_is_selected() or self.delegate.ilb.body_is_empty()):
|
||||||
self.delegate.app.ui.main_display.frame.set_focus("header")
|
self.delegate.app.ui.main_display.frame.focus_position = "header"
|
||||||
else:
|
else:
|
||||||
return super(ConversationsArea, self).keypress(size, key)
|
return super(ConversationsArea, self).keypress(size, key)
|
||||||
|
|
||||||
@@ -69,10 +69,10 @@ class ConversationsDisplay():
|
|||||||
|
|
||||||
self.columns_widget = urwid.Columns(
|
self.columns_widget = urwid.Columns(
|
||||||
[
|
[
|
||||||
# ("weight", ConversationsDisplay.list_width, self.listbox),
|
# (urwid.WEIGHT, ConversationsDisplay.list_width, self.listbox),
|
||||||
# ("weight", 1-ConversationsDisplay.list_width, self.make_conversation_widget(None))
|
# (urwid.WEIGHT, 1-ConversationsDisplay.list_width, self.make_conversation_widget(None))
|
||||||
(ConversationsDisplay.given_list_width, self.listbox),
|
(ConversationsDisplay.given_list_width, self.listbox),
|
||||||
("weight", 1, self.make_conversation_widget(None))
|
(urwid.WEIGHT, 1, self.make_conversation_widget(None))
|
||||||
],
|
],
|
||||||
dividechars=0, focus_column=0, box_columns=[0]
|
dividechars=0, focus_column=0, box_columns=[0]
|
||||||
)
|
)
|
||||||
@@ -105,7 +105,7 @@ class ConversationsDisplay():
|
|||||||
highlight_offFocus="list_off_focus"
|
highlight_offFocus="list_off_focus"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.listbox = ConversationsArea(urwid.Filler(self.ilb, height=("relative", 100)), title="Conversations")
|
self.listbox = ConversationsArea(urwid.Filler(self.ilb, height=urwid.RELATIVE_100), title="Conversations")
|
||||||
self.listbox.delegate = self
|
self.listbox.delegate = self
|
||||||
|
|
||||||
def delete_selected_conversation(self):
|
def delete_selected_conversation(self):
|
||||||
@@ -127,17 +127,33 @@ class ConversationsDisplay():
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Delete conversation with\n"+self.app.directory.simplest_display_str(bytes.fromhex(source_hash))+"\n", align="center"),
|
urwid.Text(
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
|
"Delete conversation with\n"+self.app.directory.simplest_display_str(bytes.fromhex(source_hash))+"\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
]), title="?"
|
]), title="?"
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
|
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def edit_selected_in_directory(self):
|
def edit_selected_in_directory(self):
|
||||||
@@ -223,9 +239,12 @@ class ConversationsDisplay():
|
|||||||
RNS.log("Could not save directory entry. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
RNS.log("Could not save directory entry. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
||||||
if not dialog_pile.error_display:
|
if not dialog_pile.error_display:
|
||||||
dialog_pile.error_display = True
|
dialog_pile.error_display = True
|
||||||
options = dialog_pile.options(height_type="pack")
|
options = dialog_pile.options(height_type=urwid.PACK)
|
||||||
dialog_pile.contents.append((urwid.Text(""), options))
|
dialog_pile.contents.append((urwid.Text(""), options))
|
||||||
dialog_pile.contents.append((urwid.Text(("error_text", "Could not save entry. Check your input."), align="center"), options))
|
dialog_pile.contents.append((
|
||||||
|
urwid.Text(("error_text", "Could not save entry. Check your input."), align=urwid.CENTER),
|
||||||
|
options,)
|
||||||
|
)
|
||||||
|
|
||||||
source_is_known = self.app.directory.is_known(bytes.fromhex(source_hash_text))
|
source_is_known = self.app.directory.is_known(bytes.fromhex(source_hash_text))
|
||||||
if source_is_known:
|
if source_is_known:
|
||||||
@@ -234,13 +253,23 @@ class ConversationsDisplay():
|
|||||||
def query_action(sender, user_data):
|
def query_action(sender, user_data):
|
||||||
self.close_conversation_by_hash(user_data)
|
self.close_conversation_by_hash(user_data)
|
||||||
nomadnet.Conversation.query_for_peer(user_data)
|
nomadnet.Conversation.query_for_peer(user_data)
|
||||||
options = dialog_pile.options(height_type="pack")
|
options = dialog_pile.options(height_type=urwid.PACK)
|
||||||
dialog_pile.contents = [
|
dialog_pile.contents = [
|
||||||
(urwid.Text("Query sent"), options),
|
(urwid.Text("Query sent"), options),
|
||||||
(urwid.Button("OK", on_press=dismiss_dialog), options)
|
(urwid.Button("OK", on_press=dismiss_dialog), options)
|
||||||
]
|
]
|
||||||
query_button = urwid.Button("Query network for keys", on_press=query_action, user_data=source_hash_text)
|
query_button = urwid.Button("Query network for keys", on_press=query_action, user_data=source_hash_text)
|
||||||
known_section = urwid.Pile([urwid.Divider(g["divider1"]), urwid.Text(g["info"]+"\n", align="center"), urwid.Text("The identity of this peer is not known, and you cannot currently send messages to it. You can query the network to obtain the identity.\n", align="center"), query_button, urwid.Divider(g["divider1"])])
|
known_section = urwid.Pile([
|
||||||
|
urwid.Divider(g["divider1"]),
|
||||||
|
urwid.Text(g["info"]+"\n", align=urwid.CENTER),
|
||||||
|
urwid.Text(
|
||||||
|
"The identity of this peer is not known, and you cannot currently send messages to it. "
|
||||||
|
"You can query the network to obtain the identity.\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
query_button,
|
||||||
|
urwid.Divider(g["divider1"]),
|
||||||
|
])
|
||||||
|
|
||||||
dialog_pile = urwid.Pile([
|
dialog_pile = urwid.Pile([
|
||||||
selected_id_widget,
|
selected_id_widget,
|
||||||
@@ -253,7 +282,11 @@ class ConversationsDisplay():
|
|||||||
r_direct,
|
r_direct,
|
||||||
r_propagated,
|
r_propagated,
|
||||||
known_section,
|
known_section,
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Save", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
dialog_pile.error_display = False
|
dialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -261,10 +294,19 @@ class ConversationsDisplay():
|
|||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
|
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def new_conversation(self):
|
def new_conversation(self):
|
||||||
@@ -312,9 +354,15 @@ class ConversationsDisplay():
|
|||||||
RNS.log("Could not start conversation. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
RNS.log("Could not start conversation. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
||||||
if not dialog_pile.error_display:
|
if not dialog_pile.error_display:
|
||||||
dialog_pile.error_display = True
|
dialog_pile.error_display = True
|
||||||
options = dialog_pile.options(height_type="pack")
|
options = dialog_pile.options(height_type=urwid.PACK)
|
||||||
dialog_pile.contents.append((urwid.Text(""), options))
|
dialog_pile.contents.append((urwid.Text(""), options))
|
||||||
dialog_pile.contents.append((urwid.Text(("error_text", "Could not start conversation. Check your input."), align="center"), options))
|
dialog_pile.contents.append((
|
||||||
|
urwid.Text(
|
||||||
|
("error_text", "Could not start conversation. Check your input."),
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
options,
|
||||||
|
))
|
||||||
|
|
||||||
dialog_pile = urwid.Pile([
|
dialog_pile = urwid.Pile([
|
||||||
e_id,
|
e_id,
|
||||||
@@ -324,7 +372,11 @@ class ConversationsDisplay():
|
|||||||
r_unknown,
|
r_unknown,
|
||||||
r_trusted,
|
r_trusted,
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Create", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Create", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
dialog_pile.error_display = False
|
dialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -332,10 +384,19 @@ class ConversationsDisplay():
|
|||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
|
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def ingest_lxm_uri(self):
|
def ingest_lxm_uri(self):
|
||||||
@@ -366,7 +427,10 @@ class ConversationsDisplay():
|
|||||||
rdialog_pile = urwid.Pile([
|
rdialog_pile = urwid.Pile([
|
||||||
urwid.Text("Message was decoded, decrypted successfully, and added to your conversation list."),
|
urwid.Text("Message was decoded, decrypted successfully, and added to your conversation list."),
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.6, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
rdialog_pile.error_display = False
|
rdialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -374,16 +438,28 @@ class ConversationsDisplay():
|
|||||||
rdialog.delegate = self
|
rdialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
roverlay = urwid.Overlay(
|
||||||
|
rdialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (roverlay, options)
|
self.columns_widget.contents[0] = (roverlay, options)
|
||||||
|
|
||||||
elif ingest_result == duplicate_signal:
|
elif ingest_result == duplicate_signal:
|
||||||
rdialog_pile = urwid.Pile([
|
rdialog_pile = urwid.Pile([
|
||||||
urwid.Text("The decoded message has already been processed by the LXMF Router, and will not be ingested again."),
|
urwid.Text("The decoded message has already been processed by the LXMF Router, and will not be ingested again."),
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.6, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
rdialog_pile.error_display = False
|
rdialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -391,9 +467,18 @@ class ConversationsDisplay():
|
|||||||
rdialog.delegate = self
|
rdialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
roverlay = urwid.Overlay(
|
||||||
|
rdialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (roverlay, options)
|
self.columns_widget.contents[0] = (roverlay, options)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -405,7 +490,10 @@ class ConversationsDisplay():
|
|||||||
rdialog_pile = urwid.Pile([
|
rdialog_pile = urwid.Pile([
|
||||||
urwid.Text(propagation_text),
|
urwid.Text(propagation_text),
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.6, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
rdialog_pile.error_display = False
|
rdialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -413,23 +501,36 @@ class ConversationsDisplay():
|
|||||||
rdialog.delegate = self
|
rdialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
roverlay = urwid.Overlay(rdialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
roverlay = urwid.Overlay(
|
||||||
|
rdialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (roverlay, options)
|
self.columns_widget.contents[0] = (roverlay, options)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("Could not ingest LXM URI. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
RNS.log("Could not ingest LXM URI. The contained exception was: "+str(e), RNS.LOG_VERBOSE)
|
||||||
if not dialog_pile.error_display:
|
if not dialog_pile.error_display:
|
||||||
dialog_pile.error_display = True
|
dialog_pile.error_display = True
|
||||||
options = dialog_pile.options(height_type="pack")
|
options = dialog_pile.options(height_type=urwid.PACK)
|
||||||
dialog_pile.contents.append((urwid.Text(""), options))
|
dialog_pile.contents.append((urwid.Text(""), options))
|
||||||
dialog_pile.contents.append((urwid.Text(("error_text", "Could ingest LXM from URI data. Check your input."), align="center"), options))
|
dialog_pile.contents.append((urwid.Text(("error_text", "Could ingest LXM from URI data. Check your input."), align=urwid.CENTER), options))
|
||||||
|
|
||||||
dialog_pile = urwid.Pile([
|
dialog_pile = urwid.Pile([
|
||||||
e_uri,
|
e_uri,
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Ingest", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Back", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Ingest", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
])
|
])
|
||||||
dialog_pile.error_display = False
|
dialog_pile.error_display = False
|
||||||
|
|
||||||
@@ -437,9 +538,18 @@ class ConversationsDisplay():
|
|||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def delete_conversation(self, source_hash):
|
def delete_conversation(self, source_hash):
|
||||||
@@ -471,7 +581,7 @@ class ConversationsDisplay():
|
|||||||
r_mall = urwid.RadioButton(max_messages_group, "Download all", state=True)
|
r_mall = urwid.RadioButton(max_messages_group, "Download all", state=True)
|
||||||
r_mlim = urwid.RadioButton(max_messages_group, "Limit to", state=False)
|
r_mlim = urwid.RadioButton(max_messages_group, "Limit to", state=False)
|
||||||
ie_lim = urwid.IntEdit("", 5)
|
ie_lim = urwid.IntEdit("", 5)
|
||||||
rbs = urwid.GridFlow([r_mlim, ie_lim], 12, 1, 0, align="left")
|
rbs = urwid.GridFlow([r_mlim, ie_lim], 12, 1, 0, align=urwid.LEFT)
|
||||||
|
|
||||||
def sync_now(sender):
|
def sync_now(sender):
|
||||||
limit = None
|
limit = None
|
||||||
@@ -495,7 +605,11 @@ class ConversationsDisplay():
|
|||||||
else:
|
else:
|
||||||
sync_button = hidden_sync_button
|
sync_button = hidden_sync_button
|
||||||
|
|
||||||
button_columns = urwid.Columns([("weight", 0.45, sync_button), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, cancel_button)])
|
button_columns = urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, sync_button),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, cancel_button),
|
||||||
|
])
|
||||||
real_sync_button.bc = button_columns
|
real_sync_button.bc = button_columns
|
||||||
|
|
||||||
pn_ident = None
|
pn_ident = None
|
||||||
@@ -518,7 +632,7 @@ class ConversationsDisplay():
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text(""+g["node"]+pn_display_str, align="center"),
|
urwid.Text(""+g["node"]+pn_display_str, align=urwid.CENTER),
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
sync_progress,
|
sync_progress,
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
@@ -529,12 +643,23 @@ class ConversationsDisplay():
|
|||||||
]), title="Message Sync"
|
]), title="Message Sync"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Text("" )), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, cancel_button)])
|
button_columns = urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Text("" )),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, cancel_button),
|
||||||
|
])
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
urwid.Text("No trusted nodes found, cannot sync!\n", align="center"),
|
urwid.Text("No trusted nodes found, cannot sync!\n", align=urwid.CENTER),
|
||||||
urwid.Text("To syncronise messages from the network, one or more nodes must be marked as trusted in the Known Nodes list, or a node must manually be selected as the default propagation node. Nomad Network will then automatically sync from the nearest trusted node, or the manually selected one.", align="left"),
|
urwid.Text(
|
||||||
|
"To synchronise messages from the network, "
|
||||||
|
"one or more nodes must be marked as trusted in the Known Nodes list, "
|
||||||
|
"or a node must manually be selected as the default propagation node. "
|
||||||
|
"Nomad Network will then automatically sync from the nearest trusted node, "
|
||||||
|
"or the manually selected one.",
|
||||||
|
align=urwid.LEFT,
|
||||||
|
),
|
||||||
urwid.Text(""),
|
urwid.Text(""),
|
||||||
button_columns
|
button_columns
|
||||||
]), title="Message Sync"
|
]), title="Message Sync"
|
||||||
@@ -550,10 +675,19 @@ class ConversationsDisplay():
|
|||||||
self.sync_dialog = dialog
|
self.sync_dialog = dialog
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
|
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def update_sync_dialog(self, loop = None, sender = None):
|
def update_sync_dialog(self, loop = None, sender = None):
|
||||||
@@ -561,9 +695,9 @@ class ConversationsDisplay():
|
|||||||
self.sync_dialog.sync_progress.set_completion(self.app.get_sync_progress())
|
self.sync_dialog.sync_progress.set_completion(self.app.get_sync_progress())
|
||||||
|
|
||||||
if self.app.get_sync_status() == "Idle" or self.app.message_router.propagation_transfer_state >= LXMF.LXMRouter.PR_COMPLETE:
|
if self.app.get_sync_status() == "Idle" or self.app.message_router.propagation_transfer_state >= LXMF.LXMRouter.PR_COMPLETE:
|
||||||
self.sync_dialog.bc.contents[0] = (self.sync_dialog.real_sync_button, self.sync_dialog.bc.options("weight", 0.45))
|
self.sync_dialog.bc.contents[0] = (self.sync_dialog.real_sync_button, self.sync_dialog.bc.options(urwid.WEIGHT, 0.45))
|
||||||
else:
|
else:
|
||||||
self.sync_dialog.bc.contents[0] = (self.sync_dialog.hidden_sync_button, self.sync_dialog.bc.options("weight", 0.45))
|
self.sync_dialog.bc.contents[0] = (self.sync_dialog.hidden_sync_button, self.sync_dialog.bc.options(urwid.WEIGHT, 0.45))
|
||||||
|
|
||||||
self.app.ui.loop.set_alarm_in(0.2, self.update_sync_dialog)
|
self.app.ui.loop.set_alarm_in(0.2, self.update_sync_dialog)
|
||||||
|
|
||||||
@@ -574,13 +708,22 @@ class ConversationsDisplay():
|
|||||||
def update_conversation_list(self):
|
def update_conversation_list(self):
|
||||||
ilb_position = self.ilb.get_selected_position()
|
ilb_position = self.ilb.get_selected_position()
|
||||||
self.update_listbox()
|
self.update_listbox()
|
||||||
# options = self.columns_widget.options("weight", ConversationsDisplay.list_width)
|
# options = self.columns_widget.options(urwid.WEIGHT, ConversationsDisplay.list_width)
|
||||||
options = self.columns_widget.options("given", ConversationsDisplay.given_list_width)
|
options = self.columns_widget.options(urwid.GIVEN, ConversationsDisplay.given_list_width)
|
||||||
if not (self.dialog_open and self.sync_dialog != None):
|
if not (self.dialog_open and self.sync_dialog != None):
|
||||||
self.columns_widget.contents[0] = (self.listbox, options)
|
self.columns_widget.contents[0] = (self.listbox, options)
|
||||||
else:
|
else:
|
||||||
bottom = self.listbox
|
bottom = self.listbox
|
||||||
overlay = urwid.Overlay(self.sync_dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
self.sync_dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
self.columns_widget.contents[0] = (overlay, options)
|
self.columns_widget.contents[0] = (overlay, options)
|
||||||
|
|
||||||
if ilb_position != None:
|
if ilb_position != None:
|
||||||
@@ -606,17 +749,17 @@ class ConversationsDisplay():
|
|||||||
self.app.mark_conversation_read(self.currently_displayed_conversation)
|
self.app.mark_conversation_read(self.currently_displayed_conversation)
|
||||||
|
|
||||||
self.currently_displayed_conversation = source_hash
|
self.currently_displayed_conversation = source_hash
|
||||||
# options = self.widget.options("weight", 1-ConversationsDisplay.list_width)
|
# options = self.widget.options(urwid.WEIGHT, 1-ConversationsDisplay.list_width)
|
||||||
options = self.widget.options("weight", 1)
|
options = self.widget.options(urwid.WEIGHT, 1)
|
||||||
self.widget.contents[1] = (self.make_conversation_widget(source_hash), options)
|
self.widget.contents[1] = (self.make_conversation_widget(source_hash), options)
|
||||||
if source_hash == None:
|
if source_hash == None:
|
||||||
self.widget.set_focus_column(0)
|
self.widget.focus_position = 0
|
||||||
else:
|
else:
|
||||||
if self.app.conversation_is_unread(source_hash):
|
if self.app.conversation_is_unread(source_hash):
|
||||||
self.app.mark_conversation_read(source_hash)
|
self.app.mark_conversation_read(source_hash)
|
||||||
self.update_conversation_list()
|
self.update_conversation_list()
|
||||||
|
|
||||||
self.widget.set_focus_column(1)
|
self.widget.focus_position = 1
|
||||||
conversation_position = None
|
conversation_position = None
|
||||||
index = 0
|
index = 0
|
||||||
for widget in self.list_widgets:
|
for widget in self.list_widgets:
|
||||||
@@ -756,9 +899,9 @@ class MessageEdit(urwid.Edit):
|
|||||||
y = self.get_cursor_coords(size)[1]
|
y = self.get_cursor_coords(size)[1]
|
||||||
if y == 0:
|
if y == 0:
|
||||||
if self.delegate.full_editor_active and self.name == "title_editor":
|
if self.delegate.full_editor_active and self.name == "title_editor":
|
||||||
self.delegate.frame.set_focus("body")
|
self.delegate.frame.focus_position = "body"
|
||||||
elif not self.delegate.full_editor_active and self.name == "content_editor":
|
elif not self.delegate.full_editor_active and self.name == "content_editor":
|
||||||
self.delegate.frame.set_focus("body")
|
self.delegate.frame.focus_position = "body"
|
||||||
else:
|
else:
|
||||||
return super(MessageEdit, self).keypress(size, key)
|
return super(MessageEdit, self).keypress(size, key)
|
||||||
else:
|
else:
|
||||||
@@ -769,11 +912,11 @@ class MessageEdit(urwid.Edit):
|
|||||||
|
|
||||||
class ConversationFrame(urwid.Frame):
|
class ConversationFrame(urwid.Frame):
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if self.get_focus() == "body":
|
if self.focus_position == "body":
|
||||||
if key == "up" and self.delegate.messagelist.top_is_visible:
|
if key == "up" and self.delegate.messagelist.top_is_visible:
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "down" and self.delegate.messagelist.bottom_is_visible:
|
elif key == "down" and self.delegate.messagelist.bottom_is_visible:
|
||||||
self.set_focus("footer")
|
self.focus_position = "footer"
|
||||||
else:
|
else:
|
||||||
return super(ConversationFrame, self).keypress(size, key)
|
return super(ConversationFrame, self).keypress(size, key)
|
||||||
elif key == "ctrl k":
|
elif key == "ctrl k":
|
||||||
@@ -788,7 +931,7 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
if source_hash == None:
|
if source_hash == None:
|
||||||
self.frame = None
|
self.frame = None
|
||||||
display_widget = urwid.LineBox(urwid.Filler(urwid.Text("\n No conversation selected"), "top"))
|
display_widget = urwid.LineBox(urwid.Filler(urwid.Text("\n No conversation selected"), "top"))
|
||||||
urwid.WidgetWrap.__init__(self, display_widget)
|
super().__init__(display_widget)
|
||||||
else:
|
else:
|
||||||
if source_hash in ConversationsDisplay.cached_conversation_widgets:
|
if source_hash in ConversationsDisplay.cached_conversation_widgets:
|
||||||
return ConversationsDisplay.cached_conversation_widgets[source_hash]
|
return ConversationsDisplay.cached_conversation_widgets[source_hash]
|
||||||
@@ -815,7 +958,11 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
|
|
||||||
header = None
|
header = None
|
||||||
if self.conversation.trust_level == DirectoryEntry.UNTRUSTED:
|
if self.conversation.trust_level == DirectoryEntry.UNTRUSTED:
|
||||||
header = urwid.AttrMap(urwid.Padding(urwid.Text(g["warning"]+" Warning: Conversation with untrusted peer "+g["warning"], align="center")), "msg_warning_untrusted")
|
header = urwid.AttrMap(
|
||||||
|
urwid.Padding(
|
||||||
|
urwid.Text(g["warning"]+" Warning: Conversation with untrusted peer "+g["warning"], align=urwid.CENTER)),
|
||||||
|
"msg_warning_untrusted",
|
||||||
|
)
|
||||||
|
|
||||||
self.minimal_editor = urwid.AttrMap(msg_editor, "msg_editor")
|
self.minimal_editor = urwid.AttrMap(msg_editor, "msg_editor")
|
||||||
self.minimal_editor.name = "minimal_editor"
|
self.minimal_editor.name = "minimal_editor"
|
||||||
@@ -852,7 +999,7 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
self.frame
|
self.frame
|
||||||
)
|
)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def clear_history_dialog(self):
|
def clear_history_dialog(self):
|
||||||
def dismiss_dialog(sender):
|
def dismiss_dialog(sender):
|
||||||
@@ -867,17 +1014,30 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Clear conversation history\n", align="center"),
|
urwid.Text("Clear conversation history\n", align=urwid.CENTER),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
]), title="?"
|
]), title="?"
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.messagelist
|
bottom = self.messagelist
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=34, valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=34,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
self.frame.contents["body"] = (overlay, self.frame.options())
|
self.frame.contents["body"] = (overlay, self.frame.options())
|
||||||
self.frame.set_focus("body")
|
self.frame.focus_position = "body"
|
||||||
|
|
||||||
def toggle_editor(self):
|
def toggle_editor(self):
|
||||||
if self.full_editor_active:
|
if self.full_editor_active:
|
||||||
@@ -894,7 +1054,17 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
if allowed:
|
if allowed:
|
||||||
self.frame.contents["footer"] = (self.minimal_editor, None)
|
self.frame.contents["footer"] = (self.minimal_editor, None)
|
||||||
else:
|
else:
|
||||||
warning = urwid.AttrMap(urwid.Padding(urwid.Text("\n"+g["info"]+"\n\nYou cannot currently message this peer, since it's identity keys are not known.\n\nWait for an announce to arrive from the peer, or query the network for it.\n\nTo query the network, select this conversation in the conversation list, press Ctrl-E, and use the query button.\n", align="center")), "msg_header_caution")
|
warning = urwid.AttrMap(
|
||||||
|
urwid.Padding(urwid.Text(
|
||||||
|
"\n"+g["info"]+"\n\nYou cannot currently message this peer, since it's identity keys are not known. "
|
||||||
|
"The keys have been requested from the network and should arrive shortly, if available. "
|
||||||
|
"Close this conversation and reopen it to try again.\n\n"
|
||||||
|
"To query the network manually, select this conversation in the conversation list, "
|
||||||
|
"press Ctrl-E, and use the query button.\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
)),
|
||||||
|
"msg_header_caution",
|
||||||
|
)
|
||||||
self.frame.contents["footer"] = (warning, None)
|
self.frame.contents["footer"] = (warning, None)
|
||||||
|
|
||||||
def toggle_focus_area(self):
|
def toggle_focus_area(self):
|
||||||
@@ -905,9 +1075,9 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if name == "messagelist":
|
if name == "messagelist":
|
||||||
self.frame.set_focus("footer")
|
self.frame.focus_position = "footer"
|
||||||
elif name == "minimal_editor" or name == "full_editor":
|
elif name == "minimal_editor" or name == "full_editor":
|
||||||
self.frame.set_focus("body")
|
self.frame.focus_position = "body"
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "tab":
|
if key == "tab":
|
||||||
@@ -982,17 +1152,20 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("The paper message was saved to:\n\n"+str(path)+"\n", align="center"),
|
urwid.Text("The paper message was saved to:\n\n"+str(path)+"\n", align=urwid.CENTER),
|
||||||
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.6, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
]), title=g["papermsg"].replace(" ", "")
|
]), title=g["papermsg"].replace(" ", "")
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.messagelist
|
bottom = self.messagelist
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=60, valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=60, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
|
||||||
|
|
||||||
self.frame.contents["body"] = (overlay, self.frame.options())
|
self.frame.contents["body"] = (overlay, self.frame.options())
|
||||||
self.frame.set_focus("body")
|
self.frame.focus_position = "body"
|
||||||
|
|
||||||
def print_paper_message_qr(self):
|
def print_paper_message_qr(self):
|
||||||
content = self.content_editor.get_edit_text()
|
content = self.content_editor.get_edit_text()
|
||||||
@@ -1044,25 +1217,28 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Select the desired paper message output method.\nSaved files will be written to:\n\n"+str(self.app.downloads_path)+"\n", align="center"),
|
urwid.Text(
|
||||||
|
"Select the desired paper message output method.\nSaved files will be written to:\n\n"+str(self.app.downloads_path)+"\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
urwid.Columns([
|
urwid.Columns([
|
||||||
("weight", 0.5, urwid.Button("Print QR", on_press=print_qr)),
|
(urwid.WEIGHT, 0.5, urwid.Button("Print QR", on_press=print_qr)),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.5, urwid.Button("Save QR", on_press=save_qr)),
|
(urwid.WEIGHT, 0.5, urwid.Button("Save QR", on_press=save_qr)),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.5, urwid.Button("Save URI", on_press=save_uri)),
|
(urwid.WEIGHT, 0.5, urwid.Button("Save URI", on_press=save_uri)),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.5, urwid.Button("Cancel", on_press=dismiss_dialog))
|
(urwid.WEIGHT, 0.5, urwid.Button("Cancel", on_press=dismiss_dialog))
|
||||||
])
|
])
|
||||||
]), title="Create Paper Message"
|
]), title="Create Paper Message"
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.messagelist
|
bottom = self.messagelist
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=60, valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=60, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
|
||||||
|
|
||||||
self.frame.contents["body"] = (overlay, self.frame.options())
|
self.frame.contents["body"] = (overlay, self.frame.options())
|
||||||
self.frame.set_focus("body")
|
self.frame.focus_position = "body"
|
||||||
|
|
||||||
def paper_message_failed(self):
|
def paper_message_failed(self):
|
||||||
def dismiss_dialog(sender):
|
def dismiss_dialog(sender):
|
||||||
@@ -1071,17 +1247,23 @@ class ConversationWidget(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Could not output paper message,\ncheck your settings. See the log\nfile for any error messages.\n", align="center"),
|
urwid.Text(
|
||||||
urwid.Columns([("weight", 0.6, urwid.Text("")), ("weight", 0.4, urwid.Button("OK", on_press=dismiss_dialog))])
|
"Could not output paper message,\ncheck your settings. See the log\nfile for any error messages.\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.6, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.4, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
]), title="!"
|
]), title="!"
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self.messagelist
|
bottom = self.messagelist
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=34, valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=34, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
|
||||||
|
|
||||||
self.frame.contents["body"] = (overlay, self.frame.options())
|
self.frame.contents["body"] = (overlay, self.frame.options())
|
||||||
self.frame.set_focus("body")
|
self.frame.focus_position = "body"
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.delegate.close_conversation(self)
|
self.delegate.close_conversation(self)
|
||||||
@@ -1141,7 +1323,7 @@ class LXMessageWidget(urwid.WidgetWrap):
|
|||||||
urwid.Text("")
|
urwid.Text("")
|
||||||
])
|
])
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, display_widget)
|
super().__init__(display_widget)
|
||||||
|
|
||||||
class SyncProgressBar(urwid.ProgressBar):
|
class SyncProgressBar(urwid.ProgressBar):
|
||||||
def get_text(self):
|
def get_text(self):
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class DirectoryDisplay():
|
|||||||
])
|
])
|
||||||
|
|
||||||
self.shortcuts_display = DirectoryDisplayShortcuts(self.app)
|
self.shortcuts_display = DirectoryDisplayShortcuts(self.app)
|
||||||
self.widget = urwid.Filler(pile, 'top')
|
self.widget = urwid.Filler(pile, urwid.TOP)
|
||||||
|
|
||||||
def shortcuts(self):
|
def shortcuts(self):
|
||||||
return self.shortcuts_display
|
return self.shortcuts_display
|
||||||
@@ -6,13 +6,13 @@ class IntroDisplay():
|
|||||||
font = urwid.font.HalfBlock5x4Font()
|
font = urwid.font.HalfBlock5x4Font()
|
||||||
|
|
||||||
big_text = urwid.BigText(("intro_title", self.app.config["textui"]["intro_text"]), font)
|
big_text = urwid.BigText(("intro_title", self.app.config["textui"]["intro_text"]), font)
|
||||||
big_text = urwid.Padding(big_text, align="center", width="clip")
|
big_text = urwid.Padding(big_text, align=urwid.CENTER, width=urwid.CLIP)
|
||||||
|
|
||||||
intro = urwid.Pile([
|
intro = urwid.Pile([
|
||||||
big_text,
|
big_text,
|
||||||
urwid.Text(("Version %s" % (str(self.app.version))), align="center"),
|
urwid.Text(("Version %s" % (str(self.app.version))), align=urwid.CENTER),
|
||||||
urwid.Divider(),
|
urwid.Divider(),
|
||||||
urwid.Text(("-= Starting =- "), align="center"),
|
urwid.Text(("-= Starting =- "), align=urwid.CENTER),
|
||||||
])
|
])
|
||||||
|
|
||||||
self.widget = urwid.Filler(intro)
|
self.widget = urwid.Filler(intro)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class GuideDisplayShortcuts():
|
|||||||
self.app = app
|
self.app = app
|
||||||
g = app.ui.glyphs
|
g = app.ui.glyphs
|
||||||
|
|
||||||
self.widget = urwid.AttrMap(urwid.Padding(urwid.Text(""), align="left"), "shortcutbar")
|
self.widget = urwid.AttrMap(urwid.Padding(urwid.Text(""), align=urwid.LEFT), "shortcutbar")
|
||||||
|
|
||||||
class ListEntry(urwid.Text):
|
class ListEntry(urwid.Text):
|
||||||
_selectable = True
|
_selectable = True
|
||||||
@@ -75,7 +75,7 @@ class GuideEntry(urwid.WidgetWrap):
|
|||||||
style = "topic_list_normal"
|
style = "topic_list_normal"
|
||||||
focus_style = "list_focus"
|
focus_style = "list_focus"
|
||||||
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def display_topic(self, event, topic):
|
def display_topic(self, event, topic):
|
||||||
markup = TOPICS[topic]
|
markup = TOPICS[topic]
|
||||||
@@ -125,12 +125,12 @@ class TopicList(urwid.WidgetWrap):
|
|||||||
highlight_offFocus="list_off_focus"
|
highlight_offFocus="list_off_focus"
|
||||||
)
|
)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.ilb, title="Topics"))
|
super().__init__(urwid.LineBox(self.ilb, title="Topics"))
|
||||||
|
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up" and (self.ilb.first_item_is_selected()):
|
if key == "up" and (self.ilb.first_item_is_selected()):
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
|
|
||||||
return super(TopicList, self).keypress(size, key)
|
return super(TopicList, self).keypress(size, key)
|
||||||
|
|
||||||
@@ -141,16 +141,16 @@ class GuideDisplay():
|
|||||||
self.app = app
|
self.app = app
|
||||||
g = self.app.ui.glyphs
|
g = self.app.ui.glyphs
|
||||||
|
|
||||||
topic_text = urwid.Text("\n No topic selected", align="left")
|
topic_text = urwid.Text("\n No topic selected", align=urwid.LEFT)
|
||||||
|
|
||||||
self.left_area = TopicList(self.app, self)
|
self.left_area = TopicList(self.app, self)
|
||||||
self.right_area = urwid.LineBox(urwid.Filler(topic_text, "top"))
|
self.right_area = urwid.LineBox(urwid.Filler(topic_text, urwid.TOP))
|
||||||
|
|
||||||
|
|
||||||
self.columns = urwid.Columns(
|
self.columns = urwid.Columns(
|
||||||
[
|
[
|
||||||
("weight", GuideDisplay.list_width, self.left_area),
|
(urwid.WEIGHT, GuideDisplay.list_width, self.left_area),
|
||||||
("weight", 1-GuideDisplay.list_width, self.right_area)
|
(urwid.WEIGHT, 1-GuideDisplay.list_width, self.right_area)
|
||||||
],
|
],
|
||||||
dividechars=0, focus_column=0
|
dividechars=0, focus_column=0
|
||||||
)
|
)
|
||||||
@@ -163,9 +163,8 @@ class GuideDisplay():
|
|||||||
entry.display_topic(entry.display_topic, entry.topic_name)
|
entry.display_topic(entry.display_topic, entry.topic_name)
|
||||||
|
|
||||||
def set_content_widgets(self, new_content):
|
def set_content_widgets(self, new_content):
|
||||||
options = self.columns.options(width_type="weight", width_amount=1-GuideDisplay.list_width)
|
options = self.columns.options(width_type=urwid.WEIGHT, width_amount=1-GuideDisplay.list_width, box_widget=True)
|
||||||
pile = urwid.Pile(new_content)
|
pile = urwid.Pile(new_content)
|
||||||
#content = urwid.LineBox(urwid.Filler(pile, "top"))
|
|
||||||
content = urwid.LineBox(urwid.AttrMap(ScrollBar(Scrollable(pile), thumb_char="\u2503", trough_char=" "), "scrollbar"))
|
content = urwid.LineBox(urwid.AttrMap(ScrollBar(Scrollable(pile), thumb_char="\u2503", trough_char=" "), "scrollbar"))
|
||||||
|
|
||||||
self.columns.contents[1] = (content, options)
|
self.columns.contents[1] = (content, options)
|
||||||
@@ -301,7 +300,7 @@ To learn how to host your own node, read the `*Hosting a Node`* section of this
|
|||||||
|
|
||||||
TOPIC_HOSTING = '''>Hosting a Node
|
TOPIC_HOSTING = '''>Hosting a Node
|
||||||
|
|
||||||
To host a node on the network, you must enable it in the configuration file, by setting `*enable_node`* directive to `*yes`*. You should also configure the other node-related parameters such as the node name and announce interval settings. Once node hosting has been enabled in the configuration, Nomad Network will start hosting your node as soon as the program is launched, and other peers on the network will be able to connect and interact with content on your node.
|
To host a node on the network, you must enable it in the configuration file, by setting the `*enable_node`* directive to `*yes`*. You should also configure the other node-related parameters such as the node name and announce interval settings. Once node hosting has been enabled in the configuration, Nomad Network will start hosting your node as soon as the program is launched, and other peers on the network will be able to connect and interact with content on your node.
|
||||||
|
|
||||||
By default, no content is defined, apart from a short placeholder home page. To learn how to add your own content, read on.
|
By default, no content is defined, apart from a short placeholder home page. To learn how to add your own content, read on.
|
||||||
|
|
||||||
@@ -311,9 +310,12 @@ All nodes on the network will automatically participate in a distributed message
|
|||||||
|
|
||||||
When Nomad Network is configured to host a node, by default it also configures itself as an LXMF Propagation Node, and automatically discovers and peers with other propagation nodes on the network. This process is completely automatic and requires no configuration from the node operator.
|
When Nomad Network is configured to host a node, by default it also configures itself as an LXMF Propagation Node, and automatically discovers and peers with other propagation nodes on the network. This process is completely automatic and requires no configuration from the node operator.
|
||||||
|
|
||||||
If there is already an abundance of Propagation Nodes on the network, or the operator simply wishes to host a pageserving-only node, Propagation Node hosting can be disabled in the configuration file.
|
`!However`!, if there is already an abundance of Propagation Nodes on the network, or the operator simply wishes to host a pageserving-only node, Propagation Node hosting can be disabled in the configuration file.
|
||||||
|
|
||||||
To view LXMF Propagation nodes that are currently peered with your node, go to the `![ Network ]`! part of the program and press `!Ctrl-P`!. In the list of peered Propagation Nodes, it is possible to break peering with a node by pressing `!Ctrl-X`!. It is also possible to request an immediate delivery sync of all unhandled messages for a node, by pressing `!Ctrl-R`!.
|
To view LXMF Propagation nodes that are currently peered with your node, go to the `![ Network ]`! part of the program and press `!Ctrl-P`!. In the list of peered Propagation Nodes, it is possible to:
|
||||||
|
|
||||||
|
- Immediately break peering with a node by pressing `!Ctrl-X`!
|
||||||
|
- Request an immediate delivery sync of all unhandled messages for a node, by pressing `!Ctrl-R`!
|
||||||
|
|
||||||
The distributed message store is resilient to intermittency, and will remain functional as long as at least one node remains on the network. Nodes that were offline for a time will automatically be synced up to date when they regain connectivity.
|
The distributed message store is resilient to intermittency, and will remain functional as long as at least one node remains on the network. Nodes that were offline for a time will automatically be synced up to date when they regain connectivity.
|
||||||
|
|
||||||
@@ -327,9 +329,9 @@ You can control how long a peer will cache your pages by including the cache hea
|
|||||||
|
|
||||||
>> Dynamic Pages
|
>> Dynamic Pages
|
||||||
|
|
||||||
You can use a preprocessor such as PHP, bash, Python (or whatever you prefer) to generate dynamic pages. To do so, just set executable permissions on the relevant page file, and be sure to include the interpreter at the beginning of the file, for example `!#!/usr/bin/python3`!.
|
You can use a preprocessor such as PHP, bash, Python (or whatever you prefer) to generate dynamic pages and fully interactive applications running over Nomad Network. To do so, just set executable permissions on the relevant page file, and be sure to include the interpreter at the beginning of the file, for example `!#!/usr/bin/python3`!.
|
||||||
|
|
||||||
Data from fields and link variables will be passed to these scipts or programs as environment variables, and can simply be read by any method for acessing such.
|
Data from fields and link variables will be passed to these scipts or programs as environment variables, and can simply be read by any method for accessing such.
|
||||||
|
|
||||||
In the `!examples`! directory, you can find various small examples for the use of this feature. The currently included examples are:
|
In the `!examples`! directory, you can find various small examples for the use of this feature. The currently included examples are:
|
||||||
|
|
||||||
@@ -398,7 +400,7 @@ You're currently located in the guide section of the program. I'm sorry I had to
|
|||||||
|
|
||||||
To get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color. If your terminal supports true-color, you can go to the `![ Config ]`! menu item, launch the editor and change the configuration.
|
To get the most out of Nomad Network, you will need a terminal that supports UTF-8 and at least 256 colors, ideally true-color. If your terminal supports true-color, you can go to the `![ Config ]`! menu item, launch the editor and change the configuration.
|
||||||
|
|
||||||
It is recommended to use a terminal size of at least 122x32. Nomad Network will work with smaller terminal sizes, but the interface might feel a bit cramped.
|
It is recommended to use a terminal size of at least 135x32. Nomad Network will work with smaller terminal sizes, but the interface might feel a bit cramped.
|
||||||
|
|
||||||
If you don't already have a Nerd Font installed (see https://www.nerdfonts.com/), I also highly recommend to do so, since it will greatly expand the amount of glyphs, icons and graphics that Nomad Network can use. Once you have your terminal set up with a Nerd Font, go to the `![ Config ]`! menu item and enable Nerd Fonts in the configuration instead of normal unicode glyphs.
|
If you don't already have a Nerd Font installed (see https://www.nerdfonts.com/), I also highly recommend to do so, since it will greatly expand the amount of glyphs, icons and graphics that Nomad Network can use. Once you have your terminal set up with a Nerd Font, go to the `![ Config ]`! menu item and enable Nerd Fonts in the configuration instead of normal unicode glyphs.
|
||||||
|
|
||||||
@@ -513,6 +515,12 @@ The number of minutes between each automatic sync. The default is equal to 6 hou
|
|||||||
On low-bandwidth networks, it can be useful to limit the amount of messages downloaded in each sync. The default is 8. Set to 0 to download all available messages every time a sync occurs.
|
On low-bandwidth networks, it can be useful to limit the amount of messages downloaded in each sync. The default is 8. Set to 0 to download all available messages every time a sync occurs.
|
||||||
<
|
<
|
||||||
|
|
||||||
|
>>>
|
||||||
|
`!max_accepted_size = 500`!
|
||||||
|
>>>>
|
||||||
|
The maximum accepted unpacked size for messages received directly from other peers, specified in kilobytes. Messages larger than this will be rejected before the transfer begins.
|
||||||
|
<
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
`!compact_announce_stream = yes`!
|
`!compact_announce_stream = yes`!
|
||||||
>>>>
|
>>>>
|
||||||
@@ -621,12 +629,24 @@ Determines how often, in minutes, your node is announced on the network. Default
|
|||||||
Determines where the node server will look for hosted pages. Must be a readable filesystem path.
|
Determines where the node server will look for hosted pages. Must be a readable filesystem path.
|
||||||
<
|
<
|
||||||
|
|
||||||
|
>>>
|
||||||
|
`!page_refresh_interval = 0`!
|
||||||
|
>>>>
|
||||||
|
Determines the interval in minutes for rescanning the hosted pages path. By default, this option is disabled, and the pages path will only be scanned on startup.
|
||||||
|
<
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
`!files_path = ~/.nomadnetwork/storage/files`!
|
`!files_path = ~/.nomadnetwork/storage/files`!
|
||||||
>>>>
|
>>>>
|
||||||
Determines where the node server will look for downloadable files. Must be a readable filesystem path.
|
Determines where the node server will look for downloadable files. Must be a readable filesystem path.
|
||||||
<
|
<
|
||||||
|
|
||||||
|
>>>
|
||||||
|
`!file_refresh_interval = 0`!
|
||||||
|
>>>>
|
||||||
|
Determines the interval in minutes for rescanning the hosted files path. By default, this option is disabled, and the files path will only be scanned on startup.
|
||||||
|
<
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
`!disable_propagation = no`!
|
`!disable_propagation = no`!
|
||||||
>>>>
|
>>>>
|
||||||
@@ -639,6 +659,12 @@ By default, when Nomad Network is hosting a node, it will also run an LXMF propa
|
|||||||
Configures the maximum amount of storage, in megabytes, that the LXMF Propagation Node will use to store messages.
|
Configures the maximum amount of storage, in megabytes, that the LXMF Propagation Node will use to store messages.
|
||||||
<
|
<
|
||||||
|
|
||||||
|
>>>
|
||||||
|
`!max_transfer_size = 256`!
|
||||||
|
>>>>
|
||||||
|
The maximum accepted transfer size per incoming propagation transfer, in kilobytes. This also sets the upper limit for the size of single messages accepted onto this propagation node. If a node wants to propagate a larger number of messages to this node, than what can fit within this limit, it will prioritise sending the smallest, newest messages first, and try with any remaining messages at a later point.
|
||||||
|
<
|
||||||
|
|
||||||
>>>
|
>>>
|
||||||
`!prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf`!
|
`!prioritise_destinations = 41d20c727598a3fbbdf9106133a3a0ed, d924b81822ca24e68e2effea99bcb8cf`!
|
||||||
>>>>
|
>>>>
|
||||||
@@ -757,7 +783,7 @@ The following line should contain a grayscale gradient bar:
|
|||||||
|
|
||||||
Unicode Glyphs : \u2713 \u2715 \u26a0 \u24c3 \u2193
|
Unicode Glyphs : \u2713 \u2715 \u26a0 \u24c3 \u2193
|
||||||
|
|
||||||
Nerd Font Glyphs : \uf484 \uf9c4 \uf719 \uf502 \uf415 \uf023 \uf06e
|
Nerd Font Glyphs : \uf484 \U000f04c5 \U000f0219 \U000f0002 \uf415 \uf023 \uf06e
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
@@ -1144,7 +1170,7 @@ To display literal content, for example source-code, or blocks of text that shou
|
|||||||
`=
|
`=
|
||||||
'''
|
'''
|
||||||
TOPIC_MARKUP += TOPIC_MARKUP.replace("`=", "\\`=") + "[ micron source for document goes here, we don't want infinite recursion now, do we? ]\n\\`="
|
TOPIC_MARKUP += TOPIC_MARKUP.replace("`=", "\\`=") + "[ micron source for document goes here, we don't want infinite recursion now, do we? ]\n\\`="
|
||||||
TOPIC_MARKUP += "\n`=\n\n>Closing Remarks\n\nIf you made it all the way here, you should be well equipped to write documents, pages and applications using micron and Nomad Network. Thank you for staying with me.\n\n`c\U0001F332\n"
|
TOPIC_MARKUP += "\n`=\n\n>Closing Remarks\n\nIf you made it all the way here, you should be well equipped to write documents, pages and applications using micron and Nomad Network. Thank you for staying with me.\n"
|
||||||
|
|
||||||
|
|
||||||
TOPICS = {
|
TOPICS = {
|
||||||
|
|||||||
@@ -10,12 +10,22 @@ class LogDisplayShortcuts():
|
|||||||
|
|
||||||
class LogDisplay():
|
class LogDisplay():
|
||||||
def __init__(self, app):
|
def __init__(self, app):
|
||||||
import urwid
|
|
||||||
self.app = app
|
self.app = app
|
||||||
self.log_term = LogTerminal(self.app)
|
self.log_term = None
|
||||||
|
|
||||||
self.shortcuts_display = LogDisplayShortcuts(self.app)
|
self.shortcuts_display = LogDisplayShortcuts(self.app)
|
||||||
self.widget = urwid.LineBox(self.log_term)
|
self.widget = None
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
if self.log_term == None:
|
||||||
|
self.log_term = LogTerminal(self.app)
|
||||||
|
self.widget = urwid.LineBox(self.log_term)
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
if self.log_term != None:
|
||||||
|
self.log_term.terminate()
|
||||||
|
self.log_term = None
|
||||||
|
self.widget = None
|
||||||
|
|
||||||
def shortcuts(self):
|
def shortcuts(self):
|
||||||
return self.shortcuts_display
|
return self.shortcuts_display
|
||||||
@@ -26,13 +36,17 @@ class LogTerminal(urwid.WidgetWrap):
|
|||||||
self.log_term = urwid.Terminal(
|
self.log_term = urwid.Terminal(
|
||||||
("tail", "-fn50", self.app.logfilepath),
|
("tail", "-fn50", self.app.logfilepath),
|
||||||
encoding='utf-8',
|
encoding='utf-8',
|
||||||
escape_sequence="up"
|
escape_sequence="up",
|
||||||
|
main_loop=self.app.ui.loop,
|
||||||
)
|
)
|
||||||
urwid.WidgetWrap.__init__(self, self.log_term)
|
super().__init__(self.log_term)
|
||||||
|
|
||||||
|
def terminate(self):
|
||||||
|
self.log_term.terminate()
|
||||||
|
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up":
|
if key == "up":
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
|
|
||||||
return super(LogTerminal, self).keypress(size, key)
|
return super(LogTerminal, self).keypress(size, key)
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import RNS
|
import RNS
|
||||||
import time
|
|
||||||
|
|
||||||
from .Network import *
|
from .Network import *
|
||||||
from .Conversations import *
|
from .Conversations import *
|
||||||
@@ -116,6 +115,7 @@ class MainDisplay():
|
|||||||
|
|
||||||
def show_log(self, user_data):
|
def show_log(self, user_data):
|
||||||
self.sub_displays.active_display = self.sub_displays.log_display
|
self.sub_displays.active_display = self.sub_displays.log_display
|
||||||
|
self.sub_displays.log_display.show()
|
||||||
self.update_active_sub_display()
|
self.update_active_sub_display()
|
||||||
|
|
||||||
def show_guide(self, user_data):
|
def show_guide(self, user_data):
|
||||||
@@ -125,6 +125,8 @@ class MainDisplay():
|
|||||||
def update_active_sub_display(self):
|
def update_active_sub_display(self):
|
||||||
self.frame.contents["body"] = (self.sub_displays.active().widget, None)
|
self.frame.contents["body"] = (self.sub_displays.active().widget, None)
|
||||||
self.update_active_shortcuts()
|
self.update_active_shortcuts()
|
||||||
|
if self.sub_displays.active_display != self.sub_displays.log_display:
|
||||||
|
self.sub_displays.log_display.kill()
|
||||||
|
|
||||||
def update_active_shortcuts(self):
|
def update_active_shortcuts(self):
|
||||||
self.frame.contents["footer"] = (self.sub_displays.active().shortcuts().widget, None)
|
self.frame.contents["footer"] = (self.sub_displays.active().shortcuts().widget, None)
|
||||||
@@ -155,7 +157,7 @@ class MainDisplay():
|
|||||||
class MenuColumns(urwid.Columns):
|
class MenuColumns(urwid.Columns):
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "tab" or key == "down":
|
if key == "tab" or key == "down":
|
||||||
self.handler.frame.set_focus("body")
|
self.handler.frame.focus_position = "body"
|
||||||
|
|
||||||
return super(MenuColumns, self).keypress(size, key)
|
return super(MenuColumns, self).keypress(size, key)
|
||||||
|
|
||||||
@@ -169,7 +171,7 @@ class MenuDisplay():
|
|||||||
|
|
||||||
self.menu_indicator = urwid.Text("")
|
self.menu_indicator = urwid.Text("")
|
||||||
|
|
||||||
menu_text = ("pack", self.menu_indicator)
|
menu_text = (urwid.PACK, self.menu_indicator)
|
||||||
button_network = (11, MenuButton("Network", on_press=handler.show_network))
|
button_network = (11, MenuButton("Network", on_press=handler.show_network))
|
||||||
button_conversations = (17, MenuButton("Conversations", on_press=handler.show_conversations))
|
button_conversations = (17, MenuButton("Conversations", on_press=handler.show_conversations))
|
||||||
button_directory = (13, MenuButton("Directory", on_press=handler.show_directory))
|
button_directory = (13, MenuButton("Directory", on_press=handler.show_directory))
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class MapDisplay():
|
|||||||
])
|
])
|
||||||
|
|
||||||
self.shortcuts_display = MapDisplayShortcuts(self.app)
|
self.shortcuts_display = MapDisplayShortcuts(self.app)
|
||||||
self.widget = urwid.Filler(pile, 'top')
|
self.widget = urwid.Filler(pile, urwid.TOP)
|
||||||
|
|
||||||
def shortcuts(self):
|
def shortcuts(self):
|
||||||
return self.shortcuts_display
|
return self.shortcuts_display
|
||||||
@@ -4,7 +4,6 @@ import random
|
|||||||
import time
|
import time
|
||||||
from urwid.util import is_mouse_press
|
from urwid.util import is_mouse_press
|
||||||
from urwid.text_layout import calc_coords
|
from urwid.text_layout import calc_coords
|
||||||
import re
|
|
||||||
|
|
||||||
DEFAULT_FG_DARK = "ddd"
|
DEFAULT_FG_DARK = "ddd"
|
||||||
DEFAULT_FG_LIGHT = "222"
|
DEFAULT_FG_LIGHT = "222"
|
||||||
@@ -162,7 +161,7 @@ def parse_line(line, state, url_delegate):
|
|||||||
else:
|
else:
|
||||||
tw = urwid.Text(o, align=state["align"])
|
tw = urwid.Text(o, align=state["align"])
|
||||||
|
|
||||||
widgets.append(("pack", tw))
|
widgets.append((urwid.PACK, tw))
|
||||||
else:
|
else:
|
||||||
if o["type"] == "field":
|
if o["type"] == "field":
|
||||||
fw = o["width"]
|
fw = o["width"]
|
||||||
@@ -608,7 +607,7 @@ class LinkSpec(urwid.AttrSpec):
|
|||||||
self.link_target = link_target
|
self.link_target = link_target
|
||||||
self.link_fields = None
|
self.link_fields = None
|
||||||
|
|
||||||
urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background)
|
super().__init__(orig_spec.foreground, orig_spec.background)
|
||||||
|
|
||||||
|
|
||||||
class LinkableText(urwid.Text):
|
class LinkableText(urwid.Text):
|
||||||
@@ -618,7 +617,7 @@ class LinkableText(urwid.Text):
|
|||||||
signals = ["click", "change"]
|
signals = ["click", "change"]
|
||||||
|
|
||||||
def __init__(self, text, align=None, cursor_position=0, delegate=None):
|
def __init__(self, text, align=None, cursor_position=0, delegate=None):
|
||||||
self.__super.__init__(text, align=align)
|
super().__init__(text, align=align)
|
||||||
self.delegate = delegate
|
self.delegate = delegate
|
||||||
self._cursor_position = 0
|
self._cursor_position = 0
|
||||||
self.key_timeout = 3
|
self.key_timeout = 3
|
||||||
@@ -729,7 +728,7 @@ class LinkableText(urwid.Text):
|
|||||||
|
|
||||||
def render(self, size, focus=False):
|
def render(self, size, focus=False):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
c = self.__super.render(size, focus)
|
c = super().render(size, focus)
|
||||||
|
|
||||||
if focus and (self.delegate == None or now < self.delegate.last_keypress+self.key_timeout):
|
if focus and (self.delegate == None or now < self.delegate.last_keypress+self.key_timeout):
|
||||||
c = urwid.CompositeCanvas(c)
|
c = urwid.CompositeCanvas(c)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class ListEntry(urwid.Text):
|
|||||||
class AnnounceInfo(urwid.WidgetWrap):
|
class AnnounceInfo(urwid.WidgetWrap):
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "esc":
|
if key == "esc":
|
||||||
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
|
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
|
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
|
||||||
else:
|
else:
|
||||||
return super(AnnounceInfo, self).keypress(size, key)
|
return super(AnnounceInfo, self).keypress(size, key)
|
||||||
@@ -115,7 +115,7 @@ class AnnounceInfo(urwid.WidgetWrap):
|
|||||||
style = "list_untrusted"
|
style = "list_untrusted"
|
||||||
|
|
||||||
def show_announce_stream(sender):
|
def show_announce_stream(sender):
|
||||||
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
|
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
|
self.parent.left_pile.contents[0] = (self.parent.announce_stream_display, options)
|
||||||
|
|
||||||
def connect(sender):
|
def connect(sender):
|
||||||
@@ -187,54 +187,66 @@ class AnnounceInfo(urwid.WidgetWrap):
|
|||||||
RNS.log("Error while setting active propagation node from announce. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
RNS.log("Error while setting active propagation node from announce. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
if is_node:
|
if is_node:
|
||||||
type_button = ("weight", 0.45, urwid.Button("Connect", on_press=connect))
|
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Connect", on_press=connect))
|
||||||
msg_button = ("weight", 0.45, urwid.Button("Msg Op", on_press=msg_op))
|
msg_button = (urwid.WEIGHT, 0.45, urwid.Button("Msg Op", on_press=msg_op))
|
||||||
save_button = ("weight", 0.45, urwid.Button("Save", on_press=save_node))
|
save_button = (urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=save_node))
|
||||||
elif is_pn:
|
elif is_pn:
|
||||||
type_button = ("weight", 0.45, urwid.Button("Use as default", on_press=use_pn))
|
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Use as default", on_press=use_pn))
|
||||||
save_button = None
|
save_button = None
|
||||||
else:
|
else:
|
||||||
type_button = ("weight", 0.45, urwid.Button("Converse", on_press=converse))
|
type_button = (urwid.WEIGHT, 0.45, urwid.Button("Converse", on_press=converse))
|
||||||
save_button = None
|
save_button = None
|
||||||
|
|
||||||
if is_node:
|
if is_node:
|
||||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button, ("weight", 0.1, urwid.Text("")), msg_button, ("weight", 0.1, urwid.Text("")), save_button])
|
button_columns = urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=show_announce_stream)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
type_button,
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
msg_button,
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
save_button,
|
||||||
|
])
|
||||||
else:
|
else:
|
||||||
button_columns = urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), type_button])
|
button_columns = urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Back", on_press=show_announce_stream)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
type_button,
|
||||||
|
])
|
||||||
|
|
||||||
pile_widgets = []
|
pile_widgets = []
|
||||||
|
|
||||||
if is_pn:
|
if is_pn:
|
||||||
pile_widgets = [
|
pile_widgets = [
|
||||||
urwid.Text("Time : "+ts_string, align="left"),
|
urwid.Text("Time : "+ts_string, align=urwid.LEFT),
|
||||||
urwid.Text("Addr : "+addr_str, align="left"),
|
urwid.Text("Addr : "+addr_str, align=urwid.LEFT),
|
||||||
urwid.Text("Type : "+type_string, align="left"),
|
urwid.Text("Type : "+type_string, align=urwid.LEFT),
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
button_columns
|
button_columns
|
||||||
]
|
]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pile_widgets = [
|
pile_widgets = [
|
||||||
urwid.Text("Time : "+ts_string, align="left"),
|
urwid.Text("Time : "+ts_string, align=urwid.LEFT),
|
||||||
urwid.Text("Addr : "+addr_str, align="left"),
|
urwid.Text("Addr : "+addr_str, align=urwid.LEFT),
|
||||||
urwid.Text("Type : "+type_string, align="left"),
|
urwid.Text("Type : "+type_string, align=urwid.LEFT),
|
||||||
urwid.Text("Name : "+display_str, align="left"),
|
urwid.Text("Name : "+display_str, align=urwid.LEFT),
|
||||||
urwid.Text(["Trust : ", (style, trust_str)], align="left"),
|
urwid.Text(["Trust : ", (style, trust_str)], align=urwid.LEFT),
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"),
|
urwid.Text(["Announce Data: \n", (data_style, data_str)], align=urwid.LEFT),
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
button_columns
|
button_columns
|
||||||
]
|
]
|
||||||
|
|
||||||
if is_node:
|
if is_node:
|
||||||
operator_entry = urwid.Text("Oprtr : "+op_str, align="left")
|
operator_entry = urwid.Text("Oprtr : "+op_str, align=urwid.LEFT)
|
||||||
pile_widgets.insert(4, operator_entry)
|
pile_widgets.insert(4, operator_entry)
|
||||||
|
|
||||||
pile = urwid.Pile(pile_widgets)
|
pile = urwid.Pile(pile_widgets)
|
||||||
|
|
||||||
self.display_widget = urwid.Filler(pile, valign="top", height="pack")
|
self.display_widget = urwid.Filler(pile, valign=urwid.TOP, height=urwid.PACK)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Announce Info"))
|
super().__init__(urwid.LineBox(self.display_widget, title="Announce Info"))
|
||||||
|
|
||||||
|
|
||||||
class AnnounceStreamEntry(urwid.WidgetWrap):
|
class AnnounceStreamEntry(urwid.WidgetWrap):
|
||||||
@@ -296,13 +308,13 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
|
|||||||
urwid.connect_signal(widget, "click", self.display_announce, announce)
|
urwid.connect_signal(widget, "click", self.display_announce, announce)
|
||||||
|
|
||||||
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def display_announce(self, event, announce):
|
def display_announce(self, event, announce):
|
||||||
try:
|
try:
|
||||||
parent = self.app.ui.main_display.sub_displays.network_display
|
parent = self.app.ui.main_display.sub_displays.network_display
|
||||||
info_widget = AnnounceInfo(announce, parent, self.app)
|
info_widget = AnnounceInfo(announce, parent, self.app)
|
||||||
options = parent.left_pile.options(height_type="weight", height_amount=1)
|
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
parent.left_pile.contents[0] = (info_widget, options)
|
parent.left_pile.contents[0] = (info_widget, options)
|
||||||
|
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
@@ -313,17 +325,21 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
|
|||||||
def close_req(sender):
|
def close_req(sender):
|
||||||
self.delegate.parent.close_list_dialogs()
|
self.delegate.parent.close_list_dialogs()
|
||||||
|
|
||||||
dialog_pile.contents[0] = (urwid.Text("\nKeys requested from network\n", align="center"), options)
|
dialog_pile.contents[0] = (urwid.Text("\nKeys requested from network\n", align=urwid.CENTER), options)
|
||||||
RNS.Transport.request_path(announce[1])
|
RNS.Transport.request_path(announce[1])
|
||||||
|
|
||||||
confirmed_button = urwid.Button("Request keys", on_press=confirmed)
|
confirmed_button = urwid.Button("Request keys", on_press=confirmed)
|
||||||
|
|
||||||
dialog_pile = urwid.Pile([
|
dialog_pile = urwid.Pile([
|
||||||
urwid.Text("The keys for the announced destination could not be recalled. You can wait for an announce to arrive, or request the keys from the network.\n", align="center"),
|
urwid.Text(
|
||||||
|
"The keys for the announced destination could not be recalled. "
|
||||||
|
"You can wait for an announce to arrive, or request the keys from the network.\n",
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
urwid.Columns([
|
urwid.Columns([
|
||||||
("weight", 0.45, confirmed_button),
|
(urwid.WEIGHT, 0.45, confirmed_button),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.45, urwid.Button("Close", on_press=dismiss_dialog)),
|
(urwid.WEIGHT, 0.45, urwid.Button("Close", on_press=dismiss_dialog)),
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -335,9 +351,18 @@ class AnnounceStreamEntry(urwid.WidgetWrap):
|
|||||||
dialog.delegate = self.delegate.parent
|
dialog.delegate = self.delegate.parent
|
||||||
bottom = self.delegate
|
bottom = self.delegate
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.delegate.parent.left_pile.options("weight", 1)
|
options = self.delegate.parent.left_pile.options(urwid.WEIGHT, 1)
|
||||||
self.delegate.parent.left_pile.contents[0] = (overlay, options)
|
self.delegate.parent.left_pile.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def timestamp(self):
|
def timestamp(self):
|
||||||
@@ -365,11 +390,11 @@ class AnnounceStream(urwid.WidgetWrap):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.display_widget = self.ilb
|
self.display_widget = self.ilb
|
||||||
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Announce Stream"))
|
super().__init__(urwid.LineBox(self.display_widget, title="Announce Stream"))
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "ctrl x":
|
elif key == "ctrl x":
|
||||||
self.delete_selected_entry()
|
self.delete_selected_entry()
|
||||||
|
|
||||||
@@ -464,7 +489,7 @@ class ListDialogLineBox(urwid.LineBox):
|
|||||||
class KnownNodeInfo(urwid.WidgetWrap):
|
class KnownNodeInfo(urwid.WidgetWrap):
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "esc":
|
if key == "esc":
|
||||||
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
|
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
|
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
|
||||||
else:
|
else:
|
||||||
return super(KnownNodeInfo, self).keypress(size, key)
|
return super(KnownNodeInfo, self).keypress(size, key)
|
||||||
@@ -559,7 +584,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
|||||||
op_str = "Unknown"
|
op_str = "Unknown"
|
||||||
|
|
||||||
def show_known_nodes(sender):
|
def show_known_nodes(sender):
|
||||||
options = self.parent.left_pile.options(height_type="weight", height_amount=1)
|
options = self.parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
|
self.parent.left_pile.contents[0] = (self.parent.known_nodes_display, options)
|
||||||
|
|
||||||
def connect(sender):
|
def connect(sender):
|
||||||
@@ -630,21 +655,21 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
|||||||
|
|
||||||
show_known_nodes(None)
|
show_known_nodes(None)
|
||||||
|
|
||||||
back_button = ("weight", 0.2, urwid.Button("Back", on_press=show_known_nodes))
|
back_button = (urwid.WEIGHT, 0.2, urwid.Button("Back", on_press=show_known_nodes))
|
||||||
connect_button = ("weight", 0.2, urwid.Button("Connect", on_press=connect))
|
connect_button = (urwid.WEIGHT, 0.2, urwid.Button("Connect", on_press=connect))
|
||||||
save_button = ("weight", 0.2, urwid.Button("Save", on_press=save_node))
|
save_button = (urwid.WEIGHT, 0.2, urwid.Button("Save", on_press=save_node))
|
||||||
msg_button = ("weight", 0.2, urwid.Button("Msg Op", on_press=msg_op))
|
msg_button = (urwid.WEIGHT, 0.2, urwid.Button("Msg Op", on_press=msg_op))
|
||||||
bdiv = ("weight", 0.02, urwid.Text(""))
|
bdiv = (urwid.WEIGHT, 0.02, urwid.Text(""))
|
||||||
|
|
||||||
button_columns = urwid.Columns([back_button, bdiv, connect_button, bdiv, msg_button, bdiv, save_button])
|
button_columns = urwid.Columns([back_button, bdiv, connect_button, bdiv, msg_button, bdiv, save_button])
|
||||||
|
|
||||||
pile_widgets = [
|
pile_widgets = [
|
||||||
urwid.Text("Type : "+type_string, align="left"),
|
urwid.Text("Type : "+type_string, align=urwid.LEFT),
|
||||||
e_name,
|
e_name,
|
||||||
urwid.Text("Node Addr : "+addr_str, align="left"),
|
urwid.Text("Node Addr : "+addr_str, align=urwid.LEFT),
|
||||||
e_sort,
|
e_sort,
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
urwid.Text(lxmf_addr_str, align="center"),
|
urwid.Text(lxmf_addr_str, align=urwid.CENTER),
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
propagation_node_checkbox,
|
propagation_node_checkbox,
|
||||||
connect_identify_checkbox,
|
connect_identify_checkbox,
|
||||||
@@ -656,7 +681,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
|||||||
button_columns
|
button_columns
|
||||||
]
|
]
|
||||||
|
|
||||||
operator_entry = urwid.Text("Operator : "+op_str, align="left")
|
operator_entry = urwid.Text("Operator : "+op_str, align=urwid.LEFT)
|
||||||
pile_widgets.insert(3, operator_entry)
|
pile_widgets.insert(3, operator_entry)
|
||||||
|
|
||||||
hops = RNS.Transport.hops_to(source_hash)
|
hops = RNS.Transport.hops_to(source_hash)
|
||||||
@@ -670,7 +695,7 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
|||||||
else:
|
else:
|
||||||
hops_str = "Unknown"
|
hops_str = "Unknown"
|
||||||
|
|
||||||
operator_entry = urwid.Text("Distance : "+hops_str, align="left")
|
operator_entry = urwid.Text("Distance : "+hops_str, align=urwid.LEFT)
|
||||||
pile_widgets.insert(4, operator_entry)
|
pile_widgets.insert(4, operator_entry)
|
||||||
|
|
||||||
pile = urwid.Pile(pile_widgets)
|
pile = urwid.Pile(pile_widgets)
|
||||||
@@ -679,9 +704,9 @@ class KnownNodeInfo(urwid.WidgetWrap):
|
|||||||
button_columns.focus_position = 0
|
button_columns.focus_position = 0
|
||||||
|
|
||||||
|
|
||||||
self.display_widget = urwid.Filler(pile, valign="top", height="pack")
|
self.display_widget = urwid.Filler(pile, valign=urwid.TOP, height=urwid.PACK)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Node Info"))
|
super().__init__(urwid.LineBox(self.display_widget, title="Node Info"))
|
||||||
|
|
||||||
|
|
||||||
# Yes, this is weird. There is a bug in Urwid/ILB that causes
|
# Yes, this is weird. There is a bug in Urwid/ILB that causes
|
||||||
@@ -694,9 +719,9 @@ class ExceptionHandlingListBox(IndicativeListBox):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if key == "up":
|
if key == "up":
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "down":
|
elif key == "down":
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.left_pile.set_focus(1)
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.left_pile.focus_position = 1
|
||||||
else:
|
else:
|
||||||
RNS.log("An error occurred while processing an interface event. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
RNS.log("An error occurred while processing an interface event. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
@@ -723,14 +748,23 @@ class KnownNodes(urwid.WidgetWrap):
|
|||||||
else:
|
else:
|
||||||
self.no_content = True
|
self.no_content = True
|
||||||
widget_style = "inactive_text"
|
widget_style = "inactive_text"
|
||||||
self.pile = urwid.Pile([urwid.Text(("warning_text", g["info"]+"\n"), align="center"), SelectText(("warning_text", "Currently, no nodes are saved\n\nCtrl+L to view the announce stream\n\n"), align="center")])
|
self.pile = urwid.Pile([
|
||||||
self.display_widget = urwid.Filler(self.pile, valign="top", height="pack")
|
urwid.Text(("warning_text", g["info"]+"\n"), align=urwid.CENTER),
|
||||||
|
SelectText(
|
||||||
|
(
|
||||||
|
"warning_text",
|
||||||
|
"Currently, no nodes are saved\n\nCtrl+L to view the announce stream\n\n",
|
||||||
|
),
|
||||||
|
align=urwid.CENTER,
|
||||||
|
),
|
||||||
|
])
|
||||||
|
self.display_widget = urwid.Filler(self.pile, valign=urwid.TOP, height=urwid.PACK)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Saved Nodes"), widget_style))
|
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title="Saved Nodes"), widget_style))
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "ctrl x":
|
elif key == "ctrl x":
|
||||||
self.delete_selected_entry()
|
self.delete_selected_entry()
|
||||||
|
|
||||||
@@ -757,27 +791,27 @@ class KnownNodes(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def show_info(sender):
|
def show_info(sender):
|
||||||
info_widget = KnownNodeInfo(source_hash)
|
info_widget = KnownNodeInfo(source_hash)
|
||||||
options = parent.left_pile.options(height_type="weight", height_amount=1)
|
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
parent.left_pile.contents[0] = (info_widget, options)
|
parent.left_pile.contents[0] = (info_widget, options)
|
||||||
|
|
||||||
|
|
||||||
dialog = ListDialogLineBox(
|
dialog = ListDialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Connect to node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align="center"),
|
urwid.Text("Connect to node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align=urwid.CENTER),
|
||||||
urwid.Columns([
|
urwid.Columns([
|
||||||
("weight", 0.45, urwid.Button("Yes", on_press=confirmed)),
|
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog)),
|
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
|
||||||
("weight", 0.1, urwid.Text("")),
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
("weight", 0.45, urwid.Button("Info", on_press=show_info))])
|
(urwid.WEIGHT, 0.45, urwid.Button("Info", on_press=show_info))])
|
||||||
]), title="?"
|
]), title="?"
|
||||||
)
|
)
|
||||||
dialog.delegate = self.delegate
|
dialog.delegate = self.delegate
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
|
||||||
|
|
||||||
options = self.delegate.left_pile.options("weight", 1)
|
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
|
||||||
self.delegate.left_pile.contents[0] = (overlay, options)
|
self.delegate.left_pile.contents[0] = (overlay, options)
|
||||||
|
|
||||||
def delete_selected_entry(self):
|
def delete_selected_entry(self):
|
||||||
@@ -796,16 +830,29 @@ class KnownNodes(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = ListDialogLineBox(
|
dialog = ListDialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("Delete Node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align="center"),
|
urwid.Text("Delete Node\n"+self.app.directory.simplest_display_str(source_hash)+"\n", align=urwid.CENTER),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Yes", on_press=confirmed)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("No", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Yes", on_press=confirmed)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("No", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
]), title="?"
|
]), title="?"
|
||||||
)
|
)
|
||||||
dialog.delegate = self.delegate
|
dialog.delegate = self.delegate
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(
|
||||||
|
dialog,
|
||||||
|
bottom,
|
||||||
|
align=urwid.CENTER,
|
||||||
|
width=urwid.RELATIVE_100,
|
||||||
|
valign=urwid.MIDDLE,
|
||||||
|
height=urwid.PACK,
|
||||||
|
left=2,
|
||||||
|
right=2,
|
||||||
|
)
|
||||||
|
|
||||||
options = self.delegate.left_pile.options("weight", 1)
|
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
|
||||||
self.delegate.left_pile.contents[0] = (overlay, options)
|
self.delegate.left_pile.contents[0] = (overlay, options)
|
||||||
|
|
||||||
|
|
||||||
@@ -869,7 +916,7 @@ class NodeEntry(urwid.WidgetWrap):
|
|||||||
|
|
||||||
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
||||||
self.display_widget.source_hash = source_hash
|
self.display_widget.source_hash = source_hash
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
|
|
||||||
class AnnounceTime(urwid.WidgetWrap):
|
class AnnounceTime(urwid.WidgetWrap):
|
||||||
@@ -880,7 +927,7 @@ class AnnounceTime(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_time()
|
self.update_time()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_time(self):
|
def update_time(self):
|
||||||
self.last_announce_string = "Never"
|
self.last_announce_string = "Never"
|
||||||
@@ -912,7 +959,7 @@ class NodeAnnounceTime(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_time()
|
self.update_time()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_time(self):
|
def update_time(self):
|
||||||
self.last_announce_string = "Never"
|
self.last_announce_string = "Never"
|
||||||
@@ -943,7 +990,7 @@ class NodeActiveConnections(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_stat()
|
self.update_stat()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_stat(self):
|
def update_stat(self):
|
||||||
self.stat_string = "None"
|
self.stat_string = "None"
|
||||||
@@ -974,7 +1021,7 @@ class NodeStorageStats(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_stat()
|
self.update_stat()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_stat(self):
|
def update_stat(self):
|
||||||
self.stat_string = "None"
|
self.stat_string = "None"
|
||||||
@@ -1017,7 +1064,7 @@ class NodeTotalConnections(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_stat()
|
self.update_stat()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_stat(self):
|
def update_stat(self):
|
||||||
self.stat_string = "None"
|
self.stat_string = "None"
|
||||||
@@ -1049,7 +1096,7 @@ class NodeTotalPages(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_stat()
|
self.update_stat()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_stat(self):
|
def update_stat(self):
|
||||||
self.stat_string = "None"
|
self.stat_string = "None"
|
||||||
@@ -1081,7 +1128,7 @@ class NodeTotalFiles(urwid.WidgetWrap):
|
|||||||
self.display_widget = urwid.Text("")
|
self.display_widget = urwid.Text("")
|
||||||
self.update_stat()
|
self.update_stat()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update_stat(self):
|
def update_stat(self):
|
||||||
self.stat_string = "None"
|
self.stat_string = "None"
|
||||||
@@ -1130,45 +1177,45 @@ class LocalPeer(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("\n\n\nSaved\n\n", align="center"),
|
urwid.Text("\n\n\nSaved\n\n", align=urwid.CENTER),
|
||||||
urwid.Button("OK", on_press=dismiss_dialog)
|
urwid.Button("OK", on_press=dismiss_dialog)
|
||||||
]), title=g["info"]
|
]), title=g["info"]
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
|
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
|
||||||
overlay = dialog
|
overlay = dialog
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.dialog_open = True
|
self.dialog_open = True
|
||||||
self.parent.left_pile.contents[1] = (overlay, options)
|
self.parent.left_pile.contents[1] = (overlay, options)
|
||||||
|
|
||||||
def announce_query(sender):
|
def announce_query(sender):
|
||||||
def dismiss_dialog(sender):
|
def dismiss_dialog(sender):
|
||||||
self.dialog_open = False
|
self.dialog_open = False
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
|
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
|
||||||
|
|
||||||
self.app.announce_now()
|
self.app.announce_now()
|
||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("\n\n\nAnnounce Sent\n\n\n", align="center"),
|
urwid.Text("\n\n\nAnnounce Sent\n\n\n", align=urwid.CENTER),
|
||||||
urwid.Button("OK", on_press=dismiss_dialog)
|
urwid.Button("OK", on_press=dismiss_dialog)
|
||||||
]), title=g["info"]
|
]), title=g["info"]
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
|
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
|
||||||
overlay = dialog
|
overlay = dialog
|
||||||
|
|
||||||
self.dialog_open = True
|
self.dialog_open = True
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (overlay, options)
|
self.parent.left_pile.contents[1] = (overlay, options)
|
||||||
|
|
||||||
def node_info_query(sender):
|
def node_info_query(sender):
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (self.parent.node_info_display, options)
|
self.parent.left_pile.contents[1] = (self.parent.node_info_display, options)
|
||||||
|
|
||||||
if LocalPeer.announce_timer == None:
|
if LocalPeer.announce_timer == None:
|
||||||
@@ -1189,11 +1236,15 @@ class LocalPeer(urwid.WidgetWrap):
|
|||||||
self.t_last_announce,
|
self.t_last_announce,
|
||||||
announce_button,
|
announce_button,
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
urwid.Columns([("weight", 0.45, urwid.Button("Save", on_press=save_query)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Node Info", on_press=node_info_query))])
|
urwid.Columns([
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Save", on_press=save_query)),
|
||||||
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("Node Info", on_press=node_info_query)),
|
||||||
|
])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.LineBox(self.display_widget, title="Local Peer Info"))
|
super().__init__(urwid.LineBox(self.display_widget, title="Local Peer Info"))
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.t_last_announce.start()
|
self.t_last_announce.start()
|
||||||
@@ -1217,7 +1268,7 @@ class NodeInfo(urwid.WidgetWrap):
|
|||||||
widget_style = ""
|
widget_style = ""
|
||||||
|
|
||||||
def show_peer_info(sender):
|
def show_peer_info(sender):
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
|
self.parent.left_pile.contents[1] = (LocalPeer(self.app, self.parent), options)
|
||||||
|
|
||||||
if self.app.enable_node:
|
if self.app.enable_node:
|
||||||
@@ -1241,25 +1292,25 @@ class NodeInfo(urwid.WidgetWrap):
|
|||||||
def announce_query(sender):
|
def announce_query(sender):
|
||||||
def dismiss_dialog(sender):
|
def dismiss_dialog(sender):
|
||||||
self.dialog_open = False
|
self.dialog_open = False
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (NodeInfo(self.app, self.parent), options)
|
self.parent.left_pile.contents[1] = (NodeInfo(self.app, self.parent), options)
|
||||||
|
|
||||||
self.app.node.announce()
|
self.app.node.announce()
|
||||||
|
|
||||||
dialog = DialogLineBox(
|
dialog = DialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("\n\n\nAnnounce Sent\n\n", align="center"),
|
urwid.Text("\n\n\nAnnounce Sent\n\n", align=urwid.CENTER),
|
||||||
urwid.Button("OK", on_press=dismiss_dialog)
|
urwid.Button("OK", on_press=dismiss_dialog)
|
||||||
]), title=g["info"]
|
]), title=g["info"]
|
||||||
)
|
)
|
||||||
dialog.delegate = self
|
dialog.delegate = self
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
#overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=4, right=4)
|
#overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=4, right=4)
|
||||||
overlay = dialog
|
overlay = dialog
|
||||||
|
|
||||||
self.dialog_open = True
|
self.dialog_open = True
|
||||||
options = self.parent.left_pile.options(height_type="pack", height_amount=None)
|
options = self.parent.left_pile.options(height_type=urwid.PACK, height_amount=None)
|
||||||
self.parent.left_pile.contents[1] = (overlay, options)
|
self.parent.left_pile.contents[1] = (overlay, options)
|
||||||
|
|
||||||
def connect_query(sender):
|
def connect_query(sender):
|
||||||
@@ -1308,7 +1359,7 @@ class NodeInfo(urwid.WidgetWrap):
|
|||||||
self.t_total_files.update_stat()
|
self.t_total_files.update_stat()
|
||||||
|
|
||||||
lxmf_addr_str = g["sent"]+" LXMF Propagation Node Address is "+RNS.prettyhexrep(RNS.Destination.hash_from_name_and_identity("lxmf.propagation", self.app.node.destination.identity))
|
lxmf_addr_str = g["sent"]+" LXMF Propagation Node Address is "+RNS.prettyhexrep(RNS.Destination.hash_from_name_and_identity("lxmf.propagation", self.app.node.destination.identity))
|
||||||
e_lxmf = urwid.Text(lxmf_addr_str, align="center")
|
e_lxmf = urwid.Text(lxmf_addr_str, align=urwid.CENTER)
|
||||||
|
|
||||||
announce_button = urwid.Button("Announce", on_press=announce_query)
|
announce_button = urwid.Button("Announce", on_press=announce_query)
|
||||||
connect_button = urwid.Button("Browse", on_press=connect_query)
|
connect_button = urwid.Button("Browse", on_press=connect_query)
|
||||||
@@ -1329,13 +1380,13 @@ class NodeInfo(urwid.WidgetWrap):
|
|||||||
self.t_total_files,
|
self.t_total_files,
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
urwid.Columns([
|
urwid.Columns([
|
||||||
("weight", 5, urwid.Button("Back", on_press=show_peer_info)),
|
(urwid.WEIGHT, 5, urwid.Button("Back", on_press=show_peer_info)),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 6, connect_button),
|
(urwid.WEIGHT, 6, connect_button),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 8, reset_button),
|
(urwid.WEIGHT, 8, reset_button),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 7, announce_button),
|
(urwid.WEIGHT, 7, announce_button),
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
@@ -1351,25 +1402,25 @@ class NodeInfo(urwid.WidgetWrap):
|
|||||||
self.t_total_files,
|
self.t_total_files,
|
||||||
urwid.Divider(g["divider1"]),
|
urwid.Divider(g["divider1"]),
|
||||||
urwid.Columns([
|
urwid.Columns([
|
||||||
("weight", 5, urwid.Button("Back", on_press=show_peer_info)),
|
(urwid.WEIGHT, 5, urwid.Button("Back", on_press=show_peer_info)),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 6, connect_button),
|
(urwid.WEIGHT, 6, connect_button),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 8, reset_button),
|
(urwid.WEIGHT, 8, reset_button),
|
||||||
("weight", 0.5, urwid.Text("")),
|
(urwid.WEIGHT, 0.5, urwid.Text("")),
|
||||||
("weight", 7, announce_button),
|
(urwid.WEIGHT, 7, announce_button),
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
pile = urwid.Pile([
|
pile = urwid.Pile([
|
||||||
urwid.Text("\n"+g["info"], align="center"),
|
urwid.Text("\n"+g["info"], align=urwid.CENTER),
|
||||||
urwid.Text("\nThis instance is not hosting a node\n\n", align="center"),
|
urwid.Text("\nThis instance is not hosting a node\n\n", align=urwid.CENTER),
|
||||||
urwid.Padding(urwid.Button("Back", on_press=show_peer_info), "center", "pack")
|
urwid.Padding(urwid.Button("Back", on_press=show_peer_info), urwid.CENTER, urwid.PACK)
|
||||||
])
|
])
|
||||||
|
|
||||||
self.display_widget = pile
|
self.display_widget = pile
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Local Node Info"), widget_style))
|
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title="Local Node Info"), widget_style))
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self.app.node != None:
|
if self.app.node != None:
|
||||||
@@ -1392,7 +1443,7 @@ class UpdatingText(urwid.WidgetWrap):
|
|||||||
self.append_text = append_text
|
self.append_text = append_text
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.value = self.value_method()
|
self.value = self.value_method()
|
||||||
@@ -1434,7 +1485,7 @@ class NetworkStats(urwid.WidgetWrap):
|
|||||||
|
|
||||||
self.display_widget = urwid.LineBox(pile, title="Network Stats")
|
self.display_widget = urwid.LineBox(pile, title="Network Stats")
|
||||||
|
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.w_heard_peers.start()
|
self.w_heard_peers.start()
|
||||||
@@ -1486,9 +1537,9 @@ class NetworkDisplay():
|
|||||||
|
|
||||||
self.list_display = 1
|
self.list_display = 1
|
||||||
self.left_pile = NetworkLeftPile([
|
self.left_pile = NetworkLeftPile([
|
||||||
("weight", 1, self.known_nodes_display),
|
(urwid.WEIGHT, 1, self.known_nodes_display),
|
||||||
# ("pack", self.network_stats_display),
|
# (urwid.PACK, self.network_stats_display),
|
||||||
("pack", self.local_peer_display),
|
(urwid.PACK, self.local_peer_display),
|
||||||
])
|
])
|
||||||
|
|
||||||
self.left_pile.parent = self
|
self.left_pile.parent = self
|
||||||
@@ -1499,10 +1550,10 @@ class NetworkDisplay():
|
|||||||
|
|
||||||
self.columns = urwid.Columns(
|
self.columns = urwid.Columns(
|
||||||
[
|
[
|
||||||
# ("weight", NetworkDisplay.list_width, self.left_area),
|
# (urwid.WEIGHT, NetworkDisplay.list_width, self.left_area),
|
||||||
# ("weight", self.right_area_width, self.right_area)
|
# (urwid.WEIGHT, self.right_area_width, self.right_area)
|
||||||
(NetworkDisplay.given_list_width, self.left_area),
|
(NetworkDisplay.given_list_width, self.left_area),
|
||||||
("weight", 1, self.right_area)
|
(urwid.WEIGHT, 1, self.right_area)
|
||||||
],
|
],
|
||||||
dividechars=0, focus_column=0
|
dividechars=0, focus_column=0
|
||||||
)
|
)
|
||||||
@@ -1512,11 +1563,11 @@ class NetworkDisplay():
|
|||||||
|
|
||||||
def toggle_list(self):
|
def toggle_list(self):
|
||||||
if self.list_display != 0:
|
if self.list_display != 0:
|
||||||
options = self.left_pile.options(height_type="weight", height_amount=1)
|
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.left_pile.contents[0] = (self.announce_stream_display, options)
|
self.left_pile.contents[0] = (self.announce_stream_display, options)
|
||||||
self.list_display = 0
|
self.list_display = 0
|
||||||
else:
|
else:
|
||||||
options = self.left_pile.options(height_type="weight", height_amount=1)
|
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.left_pile.contents[0] = (self.known_nodes_display, options)
|
self.left_pile.contents[0] = (self.known_nodes_display, options)
|
||||||
self.list_display = 1
|
self.list_display = 1
|
||||||
|
|
||||||
@@ -1531,7 +1582,7 @@ class NetworkDisplay():
|
|||||||
self.widget.contents[0] = (self.left_area, options)
|
self.widget.contents[0] = (self.left_area, options)
|
||||||
|
|
||||||
def show_peers(self):
|
def show_peers(self):
|
||||||
options = self.left_pile.options(height_type="weight", height_amount=1)
|
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.left_pile.contents[0] = (self.lxmf_peers_display, options)
|
self.left_pile.contents[0] = (self.lxmf_peers_display, options)
|
||||||
|
|
||||||
if self.list_display != 0:
|
if self.list_display != 0:
|
||||||
@@ -1548,7 +1599,7 @@ class NetworkDisplay():
|
|||||||
|
|
||||||
if selected_node_hash != None:
|
if selected_node_hash != None:
|
||||||
info_widget = KnownNodeInfo(selected_node_hash)
|
info_widget = KnownNodeInfo(selected_node_hash)
|
||||||
options = parent.left_pile.options(height_type="weight", height_amount=1)
|
options = parent.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
parent.left_pile.contents[0] = (info_widget, options)
|
parent.left_pile.contents[0] = (info_widget, options)
|
||||||
|
|
||||||
def focus_lists(self):
|
def focus_lists(self):
|
||||||
@@ -1567,10 +1618,10 @@ class NetworkDisplay():
|
|||||||
|
|
||||||
def close_list_dialogs(self):
|
def close_list_dialogs(self):
|
||||||
if self.list_display == 0:
|
if self.list_display == 0:
|
||||||
options = self.left_pile.options(height_type="weight", height_amount=1)
|
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.left_pile.contents[0] = (self.announce_stream_display, options)
|
self.left_pile.contents[0] = (self.announce_stream_display, options)
|
||||||
else:
|
else:
|
||||||
options = self.left_pile.options(height_type="weight", height_amount=1)
|
options = self.left_pile.options(height_type=urwid.WEIGHT, height_amount=1)
|
||||||
self.left_pile.contents[0] = (self.known_nodes_display, options)
|
self.left_pile.contents[0] = (self.known_nodes_display, options)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
@@ -1613,18 +1664,21 @@ class LXMFPeers(urwid.WidgetWrap):
|
|||||||
else:
|
else:
|
||||||
self.no_content = True
|
self.no_content = True
|
||||||
widget_style = "inactive_text"
|
widget_style = "inactive_text"
|
||||||
self.pile = urwid.Pile([urwid.Text(("warning_text", g["info"]+"\n"), align="center"), SelectText(("warning_text", "Currently, no LXMF nodes are peered\n\n"), align="center")])
|
self.pile = urwid.Pile([
|
||||||
self.display_widget = urwid.Filler(self.pile, valign="top", height="pack")
|
urwid.Text(("warning_text", g["info"]+"\n"), align=urwid.CENTER),
|
||||||
|
SelectText(("warning_text", "Currently, no LXMF nodes are peered\n\n"), align=urwid.CENTER),
|
||||||
|
])
|
||||||
|
self.display_widget = urwid.Filler(self.pile, valign=urwid.TOP, height=urwid.PACK)
|
||||||
|
|
||||||
if hasattr(self, "peer_list") and self.peer_list:
|
if hasattr(self, "peer_list") and self.peer_list:
|
||||||
pl = len(self.peer_list)
|
pl = len(self.peer_list)
|
||||||
else:
|
else:
|
||||||
pl = 0
|
pl = 0
|
||||||
urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title=f"LXMF Propagation Peers ({pl})"), widget_style))
|
super().__init__(urwid.AttrMap(urwid.LineBox(self.display_widget, title=f"LXMF Propagation Peers ({pl})"), widget_style))
|
||||||
|
|
||||||
def keypress(self, size, key):
|
def keypress(self, size, key):
|
||||||
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
if key == "up" and (self.no_content or self.ilb.first_item_is_selected()):
|
||||||
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
|
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.focus_position = "header"
|
||||||
elif key == "ctrl x":
|
elif key == "ctrl x":
|
||||||
self.delete_selected_entry()
|
self.delete_selected_entry()
|
||||||
elif key == "ctrl r":
|
elif key == "ctrl r":
|
||||||
@@ -1665,16 +1719,21 @@ class LXMFPeers(urwid.WidgetWrap):
|
|||||||
|
|
||||||
dialog = ListDialogLineBox(
|
dialog = ListDialogLineBox(
|
||||||
urwid.Pile([
|
urwid.Pile([
|
||||||
urwid.Text("A delivery sync of all unhandled LXMs was manually requested for the selected node\n", align="center"),
|
urwid.Text("A delivery sync of all unhandled LXMs was manually requested for the selected node\n", align=urwid.CENTER),
|
||||||
urwid.Columns([("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("OK", on_press=dismiss_dialog))])
|
urwid.Columns([
|
||||||
]), title="!"
|
(urwid.WEIGHT, 0.1, urwid.Text("")),
|
||||||
|
(urwid.WEIGHT, 0.45, urwid.Button("OK", on_press=dismiss_dialog)),
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
title="!",
|
||||||
|
|
||||||
)
|
)
|
||||||
dialog.delegate = self.delegate
|
dialog.delegate = self.delegate
|
||||||
bottom = self
|
bottom = self
|
||||||
|
|
||||||
overlay = urwid.Overlay(dialog, bottom, align="center", width=("relative", 100), valign="middle", height="pack", left=2, right=2)
|
overlay = urwid.Overlay(dialog, bottom, align=urwid.CENTER, width=urwid.RELATIVE_100, valign=urwid.MIDDLE, height=urwid.PACK, left=2, right=2)
|
||||||
|
|
||||||
options = self.delegate.left_pile.options("weight", 1)
|
options = self.delegate.left_pile.options(urwid.WEIGHT, 1)
|
||||||
self.delegate.left_pile.contents[0] = (overlay, options)
|
self.delegate.left_pile.contents[0] = (overlay, options)
|
||||||
|
|
||||||
|
|
||||||
@@ -1741,7 +1800,7 @@ class LXMFPeerEntry(urwid.WidgetWrap):
|
|||||||
widget = ListEntry(sym+" "+display_str+"\n "+alive_string+", last heard "+pretty_date(int(peer.last_heard))+"\n "+str(len(peer.unhandled_messages))+" unhandled LXMs, "+RNS.prettysize(peer.link_establishment_rate/8, "b")+"/s LER")
|
widget = ListEntry(sym+" "+display_str+"\n "+alive_string+", last heard "+pretty_date(int(peer.last_heard))+"\n "+str(len(peer.unhandled_messages))+" unhandled LXMs, "+RNS.prettysize(peer.link_establishment_rate/8, "b")+"/s LER")
|
||||||
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
self.display_widget = urwid.AttrMap(widget, style, focus_style)
|
||||||
self.display_widget.destination_hash = destination_hash
|
self.display_widget.destination_hash = destination_hash
|
||||||
urwid.WidgetWrap.__init__(self, self.display_widget)
|
super().__init__(self.display_widget)
|
||||||
|
|
||||||
|
|
||||||
def pretty_date(time=False):
|
def pretty_date(time=False):
|
||||||
|
|||||||
6
nomadnet/vendor/Scrollable.py
vendored
6
nomadnet/vendor/Scrollable.py
vendored
@@ -268,10 +268,10 @@ class Scrollable(urwid.WidgetDecoration):
|
|||||||
def _get_original_widget_size(self, size):
|
def _get_original_widget_size(self, size):
|
||||||
ow = self._original_widget
|
ow = self._original_widget
|
||||||
sizing = ow.sizing()
|
sizing = ow.sizing()
|
||||||
if FIXED in sizing:
|
if FLOW in sizing:
|
||||||
return ()
|
|
||||||
elif FLOW in sizing:
|
|
||||||
return (size[0],)
|
return (size[0],)
|
||||||
|
elif FIXED in sizing:
|
||||||
|
return ()
|
||||||
|
|
||||||
def get_scrollpos(self, size=None, focus=False):
|
def get_scrollpos(self, size=None, focus=False):
|
||||||
"""Current scrolling position
|
"""Current scrolling position
|
||||||
|
|||||||
@@ -269,11 +269,13 @@ class IndicativeListBox(urwid.WidgetWrap):
|
|||||||
|
|
||||||
# mousewheel up
|
# mousewheel up
|
||||||
elif button == 4.0:
|
elif button == 4.0:
|
||||||
was_handeled = self._pass_key_to_contained_listbox(modified_size, "page up")
|
# was_handeled = self._pass_key_to_contained_listbox(modified_size, "page up")
|
||||||
|
was_handeled = self._pass_key_to_contained_listbox(modified_size, "up")
|
||||||
|
|
||||||
# mousewheel down
|
# mousewheel down
|
||||||
elif button == 5.0:
|
elif button == 5.0:
|
||||||
was_handeled = self._pass_key_to_contained_listbox(modified_size, "page down")
|
# was_handeled = self._pass_key_to_contained_listbox(modified_size, "page down")
|
||||||
|
was_handeled = self._pass_key_to_contained_listbox(modified_size, "down")
|
||||||
|
|
||||||
focus_position_after_input = self.get_selected_position()
|
focus_position_after_input = self.get_selected_position()
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -30,6 +30,6 @@ setuptools.setup(
|
|||||||
entry_points= {
|
entry_points= {
|
||||||
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
|
'console_scripts': ['nomadnet=nomadnet.nomadnet:main']
|
||||||
},
|
},
|
||||||
install_requires=["rns>=0.6.2", "lxmf>=0.3.6", "urwid==2.1.2", "qrcode"],
|
install_requires=["rns>=0.7.5", "lxmf>=0.4.3", "urwid>=2.4.4", "qrcode"],
|
||||||
python_requires=">=3.6",
|
python_requires=">=3.6",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user