{% extends "base.html" %} {% block title %}Hub Management — {{ config.BBS_NAME }}{% endblock %} {% block content %}

Hub Management

Manage downstream BinkP nodes and QWK nodes connected to this BBS as a hub.

{{ binkp_nodes|length }}
BinkP Nodes
{{ qwk_nodes|length }}
QWK Nodes
{{ pending_hold }}
Hold Queue (pending)
Hub Mode
Generation & Distribution
{% if gen_tab == 'nodelist' %}

Publishes the ANotherNetwork nodelist into the ANN.FILES.NODELIST file area, replacing the prior copy, so peers can pull it like any other file-echo entry (BinkP/FTP/web).

{% if nodelist_event %} {% if nodelist_event.row.last_output %} {% endif %}
Schedule {{ nodelist_event.schedule_human }} {% if not nodelist_event.row.is_enabled %}disabled{% endif %} — edit schedule
Last run {% if nodelist_event.row.last_run_at %} {{ nodelist_event.row.last_run_at.strftime('%Y-%m-%d %H:%M UTC') }} {% if nodelist_event.row.last_status == 'ok' %}ok {% else %}{{ nodelist_event.row.last_status }}{% endif %} {% else %} never {% endif %}
Last output{{ nodelist_event.row.last_output }}
{% else %}
No nodelist-generation event found — enable REGISTRY_MODE_ENABLED and restart to seed it.
{% endif %}
{% elif gen_tab == 'qwk' %}

QWK packets are already built fresh automatically every time a node's FTP client connects or hits the download URL — nothing to schedule. Use "Preview" to build and download a packet on demand for testing; this does not mark messages as sent, so the node's real next download is unaffected.

{% if qwk_nodes %} {% for node in qwk_nodes %} {% endfor %}
Packet IDNameStatus
{{ node.packet_id }} {{ node.name }} {% if node.is_active %}active {% else %}inactive{% endif %} Preview
{% else %}
No QWK nodes registered yet.
{% endif %} {% elif gen_tab == 'tic' %}

Files uploaded to any ANN.FILES.* area are automatically queued for TIC distribution to subscribed peers — no manual step needed. This shows the outbound queue's current state; delivery happens on the next BinkP poll per peer.

{{ hatch_pending }}
Pending
{{ hatch_failed }}
Failed
{% elif gen_tab == 'join' %}

Lets anyone apply to join your network from a public web page — read the rules, download the full infopack, check a box confirming they read the rules, then submit. Applications land in Join Requests for you to review.


Infopack
{% if join_cfg.infopack_filename %}

Current: {{ join_cfg.infopack_original_filename }} ({{ join_cfg.infopack_size }} bytes, uploaded {{ join_cfg.infopack_uploaded_at.strftime('%Y-%m-%d %H:%M UTC') if join_cfg.infopack_uploaded_at else '?' }}) — download

{% if join_txt_members %}
{% endif %} {% if join_cfg.rules_text %}
Rules preview (from {{ join_cfg.rules_member_name }})
{{ join_cfg.rules_text }}
{% endif %} {% else %}

No infopack uploaded yet.

{% endif %}
{% endif %}
BinkP Nodes
{% if binkp_nodes %} {% for node in binkp_nodes %} {% endfor %}
AddressNameStatusLast Seen
{{ node.ftn_address }} {{ node.name }} {% if node.is_active %}active {% else %}inactive{% endif %} {% if node.last_seen_at %}{{ node.last_seen_at.strftime('%Y-%m-%d %H:%M') }}{% else %}—{% endif %}
{% else %}
No BinkP nodes registered yet.
{% endif %}
QWK Nodes
{% if qwk_nodes %} {% for node in qwk_nodes %} {% endfor %}
Packet IDNameStatusLast Poll
{{ node.packet_id }} {{ node.name }} {% if node.is_active %}active {% else %}inactive{% endif %} {% if node.last_poll_at %}{{ node.last_poll_at.strftime('%Y-%m-%d %H:%M') }}{% else %}—{% endif %}
{% else %}
No QWK nodes registered yet.
{% endif %}
{% endblock %}