Git Product home page Git Product logo

nomadnet's Issues

Openning editor does not work

I am using this software in alacritty and when I click < Open editor > in config tab, it blinks and nothing happens.

I have set neovim as my default editor.

Terminal Colors Modified Upon Exit

I've never seen this before but here is what my terminal colors look like normally:
20220709-14:32:07-screenshot
And this is what they look like after exiting nomadnet via Ctrl-q:
20220709-14:32:17-screenshot
I know I can just exit and create a new terminal, but I assume that's not desired behavior, so I thought I'd report it.

File downloading directory incorrect.

When attempting to download a file from NomadNet, I get the following error:

[2023-11-29 08:29:05] [Error] An error occurred while handling file response. The contained exception was: [Errno 2] No such file or directory: '/home/<user>/Downloads/RNodeFirmware/1.67/release.json'

This is a download error that attempts to place the file's entire path into the download directory. I see two options:

  1. This is intended behavior, but requires os.makedirs(path, exists_ok=True)
  2. This is unintended behavior and the intended path is ~/Downloads/release.json

I don't believe the first is intended. so I will look into making the system function as in situation 2.

Saving local node / None node name crashes NomadNet on startup.

I can't replicate, but at least two users have this issue. I have sanitized some logs I got from the first one:

[2023-11-01 19:34:58] [Notice] Configuration loaded from /home/USER/.nomadnetwork/config
[2023-11-01 19:34:58] [Notice] Loaded Primary Identity <afd485357681ba476c691867e73ed7c3> from /home/USER/.nomadnetwork/storage/identity
[2023-11-01 19:34:58] [Notice] LXMF Router ready to receive on: <65a51cba8e694ebb372a1c2a9661721d>
[2023-11-01 19:34:58] [Info] Selecting <680e5f305c2f07b006dfa9544635c707> as default LXMF propagation node
[2023-11-01 19:34:58] [Info] Starting user interface...
[2023-11-01 19:34:58] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-11-01 19:34:58] [Error] Type  : <class 'TypeError'>
[2023-11-01 19:34:58] [Error] Value : '<' not supported between instances of 'NoneType' and 'str'
[2023-11-01 19:34:58] [Error] Trace : 
  File "/home/USER/.local/bin/nomadnet", line 8, in <module>
    sys.exit(main())
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main
    program_setup(configarg, rnsconfigarg, daemon, console)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
    app = nomadnet.NomadNetworkApp(
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 376, in __init__
    nomadnet.ui.spawn(self.uimode)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/__init__.py", line 29, in spawn
    return TextUI()
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 180, in __init__
    self.main_display = Main.MainDisplay(self, self.app)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Main.py", line 91, in __init__
    self.sub_displays = SubDisplays(self.app)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Main.py", line 16, in __init__
    self.network_display = NetworkDisplay(self.app)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Network.py", line 1478, in __init__
    self.known_nodes_display = KnownNodes(self.app)
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Network.py", line 707, in __init__
    self.node_list = app.directory.known_nodes()
  File "/home/USER/.local/lib/python3.10/site-packages/nomadnet/Directory.py", line 338, in known_nodes
    node_list.sort(key = lambda e: (e.sort_rank if e.sort_rank != None else 2^32, DirectoryEntry.TRUSTED-e.trust_level, e.display_name))

This appears to be a sorting error in sort_rank, and presents similarly to a concat error with strings. Since I can't replicate, I can't test, but I have attempted to add error handling for this situation.

Improve scrolling behaviour on pages

The scrolling behaviour is inconsistent when using page-up/down together with arrow keys. The cursor should follow page position set by page-up/down.

Bug: Nasty hang on macOS

I've been experiencing hangs on exiting nomadnet on macOS when the Auto Interface is enabled. It does eventually exit, and the duration of the hang seems to have a direct relationship with the duration of the nomadnet session.

Worst of all, during this hang, the macOS networking stack seems to freeze. Browsers, ssh sessions, everything stops communicating until the issue clears. Fortunately, disabling the Auto Interface cleared it right up.

One other thing to note is I often have both Wi-Fi and ethernet connected to the same network. I've not had any problems previously, as the OS uses interface priority to pick which interface to use. But with broadcasting I can understand that might create unique challenges.

I'll try to collect more data.

Allow saving of node reached through link

Feature request.

It appears there's no way to save or open the info menu for a server that you've reached through a link. Is it possible to add the server to a list or otherwise directly save or access its menu without waiting for an announce?

If not, can a method be added?

Hosted page and file refresh not working as expected

It appears to me that the hosted page and file refresh intervals are not working as expected in the newly released NomadNet version 0.4.3.

Is far as I can tell they are refreshed continuously all the time. If my observation is wrong please ignore my rather spontaneous solution which I have not tested in any way.

In the Node.py file, starting at line 230, I would suggest to update self.last_page_refresh and self.last_file_refresh to the current time.

if self.page_refresh_interval > 0:
    if now > self.last_page_refresh + self.page_refresh_interval*60:
        self.last_page_refresh = time.time()
        self.register_pages()
                    
if self.file_refresh_interval > 0:
    if now > self.last_file_refresh + self.file_refresh_interval*60:
        self.last_file_refresh = time.time()
        self.register_files()

Since I could not find the two new options in a newly created NomadNet config file, I would suggest to add the following lines to the NomadNetworkApp.py file, after line 1051.

# Automatic rescan interval of the pages directory in minutes.
# Default: int = 0 (no rescan)
page_refresh_interval = 0

# Automatic rescan interval of the files directory in minutes.
# Default: int = 0 (no rescan)
file_refresh_interval = 0

Unknown identity string causes message to not be sent

I'm not sure why but after contacting, or being contacted by, an address with an unknown identity string, the message does not send even after the identity string is received.

I hit Ctrl+d and the message just stays inside the input box.

I have to delete the conversation and then add it back for it to work.

Exec format error while processing page request

Hi Mark,

actually I am using a custom location for the nomad config and storage files.
While processing a request for the index.mu page I see the following error in the log:

[Verbose] Incoming link request <39890900244f18b6d778> accepted
[Verbose] Peer connected to <nomadnetwork.node.436796059edc9fa3684c/eeda32d48d3603a6c16e>
[Debug] Handling request <a124d8f4efadfe22807f> for: /page/index.mu
[Verbose] Page request <a124d8f4efadfe22807f> for: /page/index.mu
[Verbose] Serving page: /home/bsb/.nomadnetwork/paulchen/storage/pages/index.mu
[Error] Error occurred while handling request <a124d8f4efadfe22807f> for: /page/index.mu
[Error] The contained exception was: [Errno 8] Exec format error: '/home/bsb/.nomadnetwork/paulchen/storage/pages/index.mu'

The file is there and can be read.
Renaming it gives the info that the node is serving pages but index.mu is not yet available.
It contains nothing else than just 'HelloWorld' and is stored as a UTF-8 file.

Any clue what might be wrong here causing that error.
I did already run out of ideas what to try...

Cheers
Stephan

Nerd Font glyphs removed / replaced

Describe the Bug
Some Nerd Font glyphs have been removed / replaced

To Reproduce
Use any recent Nerd Font (using IosevkaTerm Nerd Font here)

Expected Behavior
Expecting correct glyphs to display

Logs & Screenshots
Screenshot 2024-05-05 131743

System Information

  • OS and version
    • MX Linux 6.4.0-1mx-ahs-amd64
  • Terminal
    • alacritty
  • Python version
    • 3.11.2
  • Program version
    • nomadnet 0.4.8

Additional context
It looks as though (at least in the display test) that a couple glyphs in Nerd Fonts have been removed or replaced. One of the glyphs looks to be the Chinese character for "Dragon", and another just shows a box.

Old characters in Display Test:
\uf719 Document (box)
\uf9c4 Speedometer

Suggested replacements:
\uf0219 Document
\uf04c5 Speedometer

Unhandled exception trying to save a propagation node hash on announce stream page

In version Client 0.3.8 I tried pressing Ctrl-S on a propagation node and got the following:

[2023-09-27 16:01:06] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-09-27 16:01:06] [Error] Type : <class 'TypeError'>
[2023-09-27 16:01:06] [Error] Value : 'NoneType' object is not iterable
[2023-09-27 16:01:06] [Error] Trace :
File "/home/bangel/.local/bin/nomadnet", line 8, in
sys.exit(main())
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main
program_setup(configarg, rnsconfigarg, daemon, console)
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
app = nomadnet.NomadNetworkApp(
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 363, in init
nomadnet.ui.spawn(self.uimode)
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/ui/init.py", line 29, in spawn
return TextUI()
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 211, in init
self.loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 287, in run
self._run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 385, in _run
self.event_loop.run()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 790, in run
self._loop()
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 827, in _loop
self._watch_filesfd
File "/usr/lib/python3/dist-packages/urwid/raw_display.py", line 416, in
wrapper = lambda: self.parse_input(
File "/usr/lib/python3/dist-packages/urwid/raw_display.py", line 515, in parse_input
callback(processed, processed_codes)
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 412, in _update
self.process_input(keys)
File "/usr/lib/python3/dist-packages/urwid/main_loop.py", line 513, in process_input
k = self._topmost_widget.keypress(self.screen_size, k)
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Main.py", line 83, in keypress
return super(MainFrame, self).keypress(size, key)
File "/usr/lib/python3/dist-packages/urwid/container.py", line 1135, in keypress
return self.body.keypress( (maxcol, remaining), key )
File "/usr/lib/python3/dist-packages/urwid/container.py", line 2316, in keypress
key = w.keypress((mc,) + size[1:], key)
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Network.py", line 1419, in keypress
self.parent.browser.save_node_dialog()
File "/home/bangel/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Browser.py", line 665, in save_node_dialog
urwid.Text("Save connected node"+disp_str+" "+RNS.prettyhexrep(self.destination_hash)+" to Known Nodes?\n"),
File "/home/bangel/.local/lib/python3.10/site-packages/RNS/init.py", line 160, in prettyhexrep
hexrep = "<"+delimiter.join("{:02x}".format(c) for c in data)+">"

Nomadnet does not save 'saved' nodes as expected

Don't know if this just happens on my side only.
But as soon as the nomadnet process is killed by server shutdown oder container shutdown, all 'saved' node definitions considered saved with the UI button '< Save >' are usually gone when the app comes up again.
Same 'usually' happens with the announcement stream.

'Usually' means that sometime those data are persisted as expected.
In the earlier versions of nn I was able to save those data by using 'Quit' on the UI and restarting nn again.
The actual 0.2.1 with rns 0.3.11 seem not to do so any longer every time I press 'Quit'.

I would love to see nomadnet writing the saved nodes list to disk everytime I press 'Save' after editing node details.
To persist the actual annoucement stream every time a new announcement arrives would be a nice thing too.
The latter is important to not miss any incoming announcement that may be saved as a saved node later.

Same with the demon mode of nn.
It looks like running nn as demon and then starting up another nn client with GUI does not deliver the announcement stream seen by the runing demon instance to the newly started nn client.
So having nn or rns persisting the announcement stream for any (nn) client to see would be a nice thing as well.
Maybe that was intent anyhow because sometimes it is showing up as expected, but most of the time it is not.

Both, the saved nodes list and the announcement stream are showing quite an unpredictable behaviour with regard to persistence on my side. As long as I have no clue how these lists should behave, I can't tell if this is a bug or not.

I run rns and nn in demon mode prestarted in the background.
Additionally I launch NN with the exact same config and storage folder the demon is using.

pls adv.

Cheers
Stephan

Feature Request: CGI-style interface for script pages

I've been having a blast scripting pages for nomadnet. I'd love to see a few CGI-like features for scripts:

  • query string
  • request metadata like request id and sender address (if that's available)
  • host node information like address

These things, especially query string, would allow for more interactive content.

Reticulum config editing

Because the NomadNet config is the only one editable from inside NomadNet itself, it leads to confusion when interfaces are added to that file instead of Reticulum's config file.

Crash on Android/Termux when trying to browse

NomadNet crashes on Android/Termux when trying to browse a page. It seems to be an urwid issue.

System:
Google Pixel 6a
GrapheneOS 2023101100
Android Version 14
Termux Version 0.118.0
Reticulum Version 0.6.2
NomadNet Version 0.3.9

[2023-10-11 19:23:33] [Notice] Configuration loaded from /data/data/com.termux/files/home/.nomadnetwork/config
[2023-10-11 19:23:33] [Notice] Loaded Primary Identity <xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> from /data/data/com.termux/files/home/.nomadnetwork/storage/identity
[2023-10-11 19:23:33] [Notice] LXMF Router ready to receive on: <xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
[2023-10-11 19:23:33] [Notice] LXMF Propagation Node started on: <xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
[2023-10-11 19:23:33] [Info] Selecting <xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx> as default LXMF propagation node
[2023-10-11 19:23:33] [Info] Starting user interface...
[2023-10-11 19:23:41] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-10-11 19:23:41] [Error] Type  : <class 'AssertionError'>
[2023-10-11 19:23:41] [Error] Value : 
[2023-10-11 19:23:41] [Error] Trace : 
  File "/data/data/com.termux/files/usr/bin/nomadnet", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/nomadnet/nomadnet.py", line 51, in main
    program_setup(configarg, rnsconfigarg, daemon, console)
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
    app = nomadnet.NomadNetworkApp(
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/nomadnet/NomadNetworkApp.py", line 363, in __init__
    nomadnet.ui.spawn(self.uimode)
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/nomadnet/ui/__init__.py", line 29, in spawn
    return TextUI()
           ^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/nomadnet/ui/TextUI.py", line 211, in __init__
    self.loop.run()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 818, in _loop
    self._entering_idle()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 779, in _entering_idle
    callback()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 574, in entering_idle
    self.draw_screen()
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/main_loop.py", line 589, in draw_screen
    self.screen.draw_screen(self.screen_size, canvas)
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/raw_display.py", line 778, in draw_screen
    for row in r.content():
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/canvas.py", line 601, in content
    yield shard_body_row(sbody)
          ^^^^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/canvas.py", line 833, in shard_body_row
    row.extend(next(content_iter))
               ^^^^^^^^^^^^^^^^^^
  File "/data/data/com.termux/files/usr/lib/python3.11/site-packages/urwid/canvas.py", line 415, in content
    assert trim_left >= 0 and trim_left < maxcol
                              ^^^^^^^^^^^^^^^^^^
'''  

Use standard config location

Right now is config file in ~/.nomadnetwork/config. It would be nice to add ability to move it to ~/.config/nomadnetwork/config or /etc/nomadnetwork/config.

In standard way software looks for config in this order:

  1. ~/.config/nomadnetwork/config
  2. ~/.nomadnetwork/config
  3. /etc/nomadnetwork/config
  4. loads defaults

It would be nice to implement this order so it will stop cluttering home dir.

Selecting what interface to use in config file

Not sure if to post this to either the Reticulum repository, or this one. Anyways, I want to use UDP broadcast to set up a network of nodes with NomadNet. However, all of my nodes have more than one interface. The first interface being how I ssh into the machines/how they connect to the internet. The machines all then have an extra interface (eth1) that operates as a LAN between them. Is there a way in the .reticulum/config file to select the interface to use the default UDP broadcast on?

I tried looking at the code to see what the deal is, but I'm in over my head. I tried using NomadNet with the default configuration with the UDP interface on, but it wasn't working between nodes that all shared a network on the second interface. I could get the TCP server/client method working, but I still want to figure out how to use the UDP broadcast one.

Thanks.

Vim keybinding

It is missed opportunity to not implement vim keybindings. The target group of this software will definitely find it useful.

Nomadnet shuts down after large message transmit/recieve, possible python issue?

Hi! I have two identical setups on Lenovo T430 laptops, with Nomadnet 0.4.6, Linux Mint 21.2 Cinnamon OS, with a LilyGO T3 v1.6.1 on 433MHz. The LoRa config is the default from the manual, with the frequency set to the 433 band.

I have had no issues with short message conversations over LoRA.

However I tried sending larger chunks of text, of larger than approximately 1000words, message is sent, but nomadnet shuts down. It restarts without issue, and displays the transmitted message. However it keeps intermittently shutting down when receiving messages, no matter how big payload there is on that message. This continues until the whole system is rebooted. This is the logfile output, it seems to involve python:

[2024-02-10 12:45:29] [Error] An unhandled exception occurred, the details of which will be dumped below [2024-02-10 12:45:29] [Error] Type : <class 'AttributeError'> [2024-02-10 12:45:29] [Error] An error occurred in the external delivery callback for <LXMessage dc42dfffbc199edcd7bffe5262aeb1e705ba7babd0082fe466ee2bd87511a702> [2024-02-10 12:45:29] [Error] Value : 'Text' object has no attribute '_cache_translation' [2024-02-10 12:45:29] [Error] Trace : File "/home/nomad/.local/bin/nomadnet", line 8, in <module> sys.exit(main()) File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main program_setup(configarg, rnsconfigarg, daemon, console) File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup app = nomadnet.NomadNetworkApp( File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 378, in __init__ nomadnet.ui.spawn(self.uimode) File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/ui/__init__.py", line 29, in spawn return TextUI() File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 211, in __init__ self.loop.run() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/main_loop.py", line 343, in run self._run() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/main_loop.py", line 445, in _run self.event_loop.run() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/select_loop.py", line 182, in run self._loop() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/select_loop.py", line 218, in _loop self._entering_idle() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/select_loop.py", line 171, in _entering_idle callback() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/main_loop.py", line 652, in entering_idle self.draw_screen() File "/home/nomad/.local/lib/python3.10/site-packages/urwid/event_loop/main_loop.py", line 669, in draw_screen canvas = self._topmost_widget.render(self.screen_size, focus=True) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/frame.py", line 408, in render body = self.body.render((maxcol, maxrow - ftrim - htrim), focus and self.focus_part == "body") File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/columns.py", line 938, in render w.render(w_size, focus=focus and self.focus_position == i), File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 718, in render canv = get_delegate(self).render(size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 718, in render canv = get_delegate(self).render(size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/pile.py", line 817, in render canv = w.render(w_size, focus=focus and item_focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/columns.py", line 938, in render w.render(w_size, focus=focus and self.focus_position == i), File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/frame.py", line 408, in render body = self.body.render((maxcol, maxrow - ftrim - htrim), focus and self.focus_part == "body") File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 112, in cached_render canv = fn(self, size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/nomadnet/vendor/additional_urwid_widgets/widgets/indicative_listbox.py", line 109, in render middle, top, bottom = self._listbox.calculate_visible(modified_size, focus=focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/listbox.py", line 476, in calculate_visible p_rows = prev.rows((maxcol,)) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 181, in cached_rows return fn(self, size, focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/pile.py", line 852, in rows return sum(self.get_item_rows(size, focus)) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/pile.py", line 760, in get_item_rows rows_numbers.append(w.rows((maxcol,), focus=focused)) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/widget.py", line 181, in cached_rows return fn(self, size, focus) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/text.py", line 281, in rows return len(self.get_line_translation(maxcol)) File "/home/nomad/.local/lib/python3.10/site-packages/urwid/widget/text.py", line 300, in get_line_translation return self._cache_translation

Bug: Trusted nodes reset every few power-offs

Every few shutdowns my list of trusted nodes is reset.
This has happened to conversations as well once, but to trusted nodes twice.

The first time, I had added several propagation nodes. After powering off the computer and powering it back on, the nodes disappeared from my trusted list.

My OS is Debian 11 with Kicksecure.

Crash on announce receive handler

One of my NomadNet programs crashes every few days to few weeks. I just caught the log:

[2023-08-09 14:17:37] [Extra] Valid announce for <a6ff59611bb0f4674db719e94885e7ae> 2 hops away, received via <445853aca89b5d92d02dd2f727896a35> on LocalInterface[37428]
[2023-08-09 14:17:37] [Debug] Destination <a6ff59611bb0f4674db719e94885e7ae> is now 2 hops away via <445853aca89b5d92d02dd2f727896a35> on LocalInterface[37428]
[2023-08-09 14:17:37] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-08-09 14:17:37] [Error] Error while processing external announce callback.
[2023-08-09 14:17:37] [Error] Type  : <class 'AttributeError'>
[2023-08-09 14:17:37] [Error] The contained exception was:
[2023-08-09 14:17:37] [Error] Value : 'ListEntry' object has no attribute '_cache_translation'
[2023-08-09 14:17:38] [Error] Trace :
  File "/home/faragher/.local/bin/nomadnet", line 8, in <module>
    sys.exit(main())
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main
    program_setup(configarg, rnsconfigarg, daemon, console)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
    app = nomadnet.NomadNetworkApp(
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 362, in __init__
    nomadnet.ui.spawn(self.uimode)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/__init__.py", line 29, in spawn
    return TextUI()
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 207, in __init__
    self.loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 818, in _loop
    self._entering_idle()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 779, in _entering_idle
    callback()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 574, in entering_idle
    self.draw_screen()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 588, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1089, in render
    body = self.body.render((maxcol, maxrow-ftrim-htrim),
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2130, in render
    canv = w.render(sub_size,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 1761, in render
    canv = get_delegate(self).render(size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1565, in render
    canv = w.render((maxcol, rows), focus=focus and item_focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2130, in render
    canv = w.render(sub_size,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/decoration.py", line 819, in render
    canv = self._original_widget.render((maxcol,maxrow-top-bottom),focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/vendor/additional_urwid_widgets/widgets/indicative_listbox.py", line 109, in render
    middle, top, bottom = self._listbox.calculate_visible(modified_size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/listbox.py", line 389, in calculate_visible
    n_rows = next.rows( (maxcol,) )
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 205, in cached_rows
    return fn(self, size, focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 1019, in rows
    return len(self.get_line_translation(maxcol))
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 1035, in get_line_translation
    return self._cache_translation

[2023-08-09 14:17:38] [Verbose] Saving directory...
[2023-08-09 14:17:38] [Verbose] Nomad Network Client exiting now
[2023-08-09 14:17:38] [Debug] Saved 26 peers to storage

It appears it's attempting to call _cache_translation on a list, which may be an error handling problem in NomadNet or an implementation problem in urwid.

Instance is running over SSH and has not had its size changed since NN startup.

NomadNet stops logging after localnode disconnect/reconnect

Full Disclosure: I've just started experimenting w/ Reticulum, NomadNet and Rnodes in the last couple days and am still learning.

Using an Ubuntu machine with rnsd and nomadnet packages from yesterday.

I restarted my local rnsd this morning after switching Rnode hardware. Nomadnet client on same machinereported the LocalInterface socket was closed, then logged Reconnected after I restarted rnsd. No other log messages in the client nor in the file after that.

I'm also not seeing any new announcements in the Network tab but was able to announce my node and also create a connection with someone elses node.

[Bug] Hangs after "Loaded Transport Identity From storage"

Just installed NomadNet with pipx on win10 under python 3.11.4
after configuring and launching with nomadnet -t it ends up hanging without any response to input(cant ctrl-c/ctrl-d for example)

[2023-08-28 20:42:56] [Debug] Started shared instance interface: Shared Instance[37428]
[2023-08-28 20:42:56] [Extra] Cleaning resource and packet caches...
[2023-08-28 20:42:56] [Verbose] Bringing up system interfaces...
[2023-08-28 20:42:56] [Debug] Establishing TCP connection for TCPInterface[RNS Testnet Dublin/dublin.connect.reticulum.network:4965]...
[2023-08-28 20:42:56] [Debug] TCP connection for TCPInterface[RNS Testnet Dublin/dublin.connect.reticulum.network:4965] established
[2023-08-28 20:42:56] [Debug] Establishing TCP connection for TCPInterface[RNS Testnet BetweenTheBorders/betweentheborders.com:4242]...
[2023-08-28 20:42:56] [Debug] TCP connection for TCPInterface[RNS Testnet BetweenTheBorders/betweentheborders.com:4242] established
[2023-08-28 20:42:56] [Verbose] System interfaces are ready
[2023-08-28 20:42:56] [Verbose] Configuration loaded from C:\Users\Wissotsky/.reticulum/config
[2023-08-28 20:42:56] [Verbose] Loaded 4 known destination from storage
[2023-08-28 20:42:56] [Verbose] Loaded Transport Identity from storage

Tried with both Alacritty and Windows Terminal but its the same exact behaviour

Request Failed on serving pages

On attempting to access pages from another local node, I get "Request failed" after everything seeming to function until "Request sent, awaiting response."

I can occasionally get index.mu, but none of the other pages will load. All have 644 permissions (except the Python script, which is 755) and seem to function when browsed from the source machine. LXMF works as intended, the system seems stable, and problems persist with both the autointerface and the Dublin hub. Direct file access (hash:/file/filename.ext) also fails.

Logs reveal nothing on either system (server at log level 4, client at 6, I don't think it's wise to cycle the main node to change the log level). I am uncertain if the pages serve properly to others, but can't get a node on an outside net to test.

Both nodes are on a subnet, and 4242 is routed to the main node. Both are configured to be propagation nodes.

Announce stream appears frozen from 12MAY (9 days ago) and logs from the 16th. Pages served increments properly. RNStatus as expected. Using server to browse client page worked flawlessly the first time, and now has similar "Request Failed" message. Client serving pages at log level 6 reports nothing at time of serving.

Please advise on how to find logs or similar information to determine the issue.

Server: (pip version)
NN v0.3.5
RNS v0.4.9

Client:
NN v0.3.5
RNS v0.5.3

Unable to use UI

I have installed and configured NomadNet using "pip3 install nomadnet" on two different PCs. Installation of RNS, LXMF, and NomadNet appear to be correct. After execution of 'nomadnet' (Log = 7), I get the following terminal stream and nothing else:
"nomadnet
[2021-05-26 17:53:23] [Notice] Configuration loaded from /home/curt/.reticulum/config
[2021-05-26 17:53:23] [Debug] Started shared instance interface: Shared Instance [37428]
[2021-05-26 17:53:23] [Notice] Skipping disabled interface "TCP Server Interface"
[2021-05-26 17:53:23] [Notice] Skipping disabled interface "TCP Client Interface"
[2021-05-26 17:53:23] [Notice] Skipping disabled interface "RNode LoRa Interface"
[2021-05-26 17:53:23] [Notice] Skipping disabled interface "Packet Radio KISS Interface"
[2021-05-26 17:53:23] [Notice] Skipping disabled interface "Packet Radio AX.25 KISS Interface"
[2021-05-26 17:53:23] [Verbose] Loaded 4 known destination from storage
[2021-05-26 17:53:23] [Verbose] Loaded Transport Identity from storage"

I was expecting the UI to appear, but it does not. Although documented in the READ.ME file, is the UI implemented in Nomad Network Client 0.0.5? Any help would be greatly appreciated.
Thanks for your time and consideration.

NomadNet pages crash NomadNet

Looking at AOSN's new weather radar pages produced a tremendous amount of problems, from slow traffic to failed links. However, for a time it was crashing NomadNet entirely in ways that seemed to be parsing failures. The entire stack had to be restarted to solve this issue.

Pertinent logs:

[2023-07-05 17:17:31] [Debug] Browser handling link to: 24878ea1f8b5b9f89c7a55789d38993b:/file/Z_QABA00KWBC040845_C_KWIN_20230704204538_011668-3-RADALLAK.GIF
[2023-07-05 17:17:32] [Extra] Valid announce for <f52f60ddf26e95b2ee40ce9a659c81bf> 2 hops away, received via <445853aca89b5d92d02dd2f727896a35> on LocalInterface[37428]
[2023-07-05 17:17:32] [Debug] Destination <f52f60ddf26e95b2ee40ce9a659c81bf> is now 2 hops away via <445853aca89b5d92d02dd2f727896a35> on LocalInterface[37428]
[2023-07-05 17:17:36] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-07-05 17:17:36] [Error] Type  : <class 'AssertionError'>
[2023-07-05 17:17:36] [Error] Value : rows, render mismatch
[2023-07-05 17:17:36] [Error] Trace :
  File "/home/faragher/.local/bin/nomadnet", line 8, in <module>
    sys.exit(main())
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main
    program_setup(configarg, rnsconfigarg, daemon, console)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
    app = nomadnet.NomadNetworkApp(
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 362, in __init__
    nomadnet.ui.spawn(self.uimode)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/__init__.py", line 29, in spawn
    return TextUI()
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 207, in __init__
    self.loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 818, in _loop
    self._entering_idle()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 779, in _entering_idle
    callback()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 574, in entering_idle
    self.draw_screen()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 588, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1089, in render
    body = self.body.render((maxcol, maxrow-ftrim-htrim),
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2130, in render
    canv = w.render(sub_size,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/decoration.py", line 226, in render
    canv = self._original_widget.render(size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 1761, in render
    canv = get_delegate(self).render(size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1565, in render
    canv = w.render((maxcol, rows), focus=focus and item_focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2130, in render
    canv = w.render(sub_size,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1103, in render
    assert foot.rows() == frows, "rows, render mismatch"

[2023-07-05 17:17:36] [Verbose] Saving directory...
[2023-07-05 17:17:36] [Verbose] Nomad Network Client exiting now

[2023-07-05 17:20:31] [Debug] Browser handling link to: 24878ea1f8b5b9f89c7a55789d38993b:/page/weather.mu
[2023-07-05 17:20:31] [Debug] Found 7e09f27c3210918390c8e5315dd5beca668d99a71e7b2bfdb7dc4d6a68334a30_1688634621.5443652 in cache.
[2023-07-05 17:20:31] [Debug] Returning cached page
[2023-07-05 17:20:51] [Debug] Removed /home/faragher/.nomadnetwork/storage/cache/7e09f27c3210918390c8e5315dd5beca668d99a71e7b2bfdb7dc4d6a68334a30_1688634621.5443652 from cache.
[2023-07-05 17:20:51] [Extra] Registering link <9425ea25d26dfadb8c5487263157cecd>
[2023-07-05 17:20:51] [Debug] Link request <9425ea25d26dfadb8c5487263157cecd> sent to <nomadnetwork.node.3cd8ff0b961ff82883300acbe60a427c/24878ea1f8b5b9f89c7a55789d38993b>
[2023-07-05 17:20:51] [Extra] Activating link <9425ea25d26dfadb8c5487263157cecd>
[2023-07-05 17:20:51] [Verbose] Link <9425ea25d26dfadb8c5487263157cecd> established with <nomadnetwork.node.3cd8ff0b961ff82883300acbe60a427c/24878ea1f8b5b9f89c7a55789d38993b>, RTT is 0.265s
[2023-07-05 17:20:52] [Error] An unhandled exception occurred, the details of which will be dumped below
[2023-07-05 17:20:52] [Verbose] Validating link request <587bcfa354d6608b6518c372dc29a780>
[2023-07-05 17:20:52] [Error] Type  : <class 'IndexError'>
[2023-07-05 17:20:52] [Error] Value : list index out of range
[2023-07-05 17:20:52] [Extra] Registering link <587bcfa354d6608b6518c372dc29a780>
[2023-07-05 17:20:52] [Verbose] Incoming link request <587bcfa354d6608b6518c372dc29a780> accepted
[2023-07-05 17:20:52] [Error] Trace :
  File "/home/faragher/.local/bin/nomadnet", line 8, in <module>
    sys.exit(main())
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 51, in main
    program_setup(configarg, rnsconfigarg, daemon, console)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/nomadnet.py", line 11, in program_setup
    app = nomadnet.NomadNetworkApp(
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/NomadNetworkApp.py", line 362, in __init__
    nomadnet.ui.spawn(self.uimode)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/__init__.py", line 29, in spawn
    return TextUI()
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/TextUI.py", line 207, in __init__
    self.loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 827, in _loop
    self._watch_files[fd]()
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/raw_display.py", line 416, in <lambda>
    wrapper = lambda: self.parse_input(
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/raw_display.py", line 515, in parse_input
    callback(processed, processed_codes)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 412, in _update
    self.process_input(keys)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/main_loop.py", line 509, in process_input
    if self._topmost_widget.mouse_event(self.screen_size,
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/textui/Main.py", line 75, in mouse_event
    return super(MainFrame, self).mouse_event(size, event, button, col, row, focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1175, in mouse_event
    return self.body.mouse_event( (maxcol, maxrow-htrim-ftrim),
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2246, in mouse_event
    return w.mouse_event((end - x,) + size[1:], event, button,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1725, in mouse_event
    return w.mouse_event(tsize, event, button, col, row-wrow,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 2246, in mouse_event
    return w.mouse_event((end - x,) + size[1:], event, button,
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1175, in mouse_event
    return self.body.mouse_event( (maxcol, maxrow-htrim-ftrim),
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/vendor/Scrollable.py", line 455, in mouse_event
    handled = ow.mouse_event(ow_size, event, button, col, row, focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/vendor/Scrollable.py", line 215, in mouse_event
    return ow.mouse_event(ow_size, event, button, col, row, focus)
  File "/home/faragher/.local/lib/python3.10/site-packages/urwid/container.py", line 1725, in mouse_event
    return w.mouse_event(tsize, event, button, col, row-wrow,
  File "/home/faragher/.local/lib/python3.10/site-packages/nomadnet/ui/textui/MicronParser.py", line 775, in mouse_event
    line_offset = translation[y][0][1]

[2023-07-05 17:20:52] [Verbose] Saving directory...
[2023-07-05 17:20:52] [Verbose] Nomad Network Client exiting now

It looks like either a general UI issue or that NomadNet crashes if the terminal window's size is changed. I'm not certain.

There were also a huge number of link issues that have produced absolutely no logged errors. I think we generally need to look at the robustness of the link code.

Also, how do I increase log length? Unless the logs cycle at application start, these appear to be too short to keep enough data at debug logging levels.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.