ANetBBS Changelog
Versions are internal build numbers. Public releases are tagged
separately. Current release: v1.0b2.58 (July 2026). Full release: August 1 2026.
v1.0a2.142 — BBS Directory: correct EtherTerm XML parser (June 2026)
- Both TelnetBBSGuide and IPTIA use the same EtherTerm
dialdirectory.xml
format:<BBS name="..." ip="..." port="..." protocol="TELNET" />.
Switched from ElementTree (fails on unescaped&in BBS names) and
failed CSV/pipe parsers to a single regex-based_parse_etherterm_xml()
shared by both sources. Parses 1,075 TelnetBBSGuide entries and 1,810
IPTIA entries correctly. TelnetBBSGuide is fetched as a monthly ZIP;
dialdirectory.xmlis extracted from inside it.
v1.0a2.141 — BBS Directory: correct TelnetBBSGuide + IPTIA formats (June 2026)
- TelnetBBSGuide: rewritten from CSV to ZIP parser. Monthly file URL
constructed dynamically (ibbs{MM}{YYYY}.zip); falls back to previous
month if current month returns 404. Extracts the text file from inside
the ZIP and parses pipe-delimited rows with flexible column detection. - IPTIA: rewritten from CSV to XML parser. Fetches
dialdirectory.xmland parses withxml.etree.ElementTree, trying
common tag names for name/address/port/sysop/location/software/web/description. - Both parsers handle unknown field names gracefully; exceptions are caught
and return 0 instead of crashing the background thread.
v1.0a2.140 — BBS Directory CSV parser fixes (June 2026)
- IPTIA parser crash —
csv.DictReaderproduces aNonekey when a CSV
header row has a trailing comma.k.strip()onNoneraisedAttributeError.
Both parsers now filterif k is not None. Fixed inweb/peers.py. - Parser exceptions no longer crash background thread —
parser(text)and
the DB insert block are now each wrapped in try/except so a malformed CSV
silently returns 0 instead of killing the refresh thread. - TelnetBBSGuide URL updated to
/bbs/list/full/csv/; both external URLs
are now overridable viaTELNETBBSGUIDE_CSV_URLandIPTIA_CSV_URLin.env.
v1.0a2.139 — Fix 500 on BBS Directory (missing PeerBbs columns) (June 2026)
- Hotfix:
PeerBbsmodel was missing the new columns (is_approved,
telnet_port,web_url,location,software,submitted_by_user_id)
added in v1.0a2.138. SQLAlchemy raisedInvalidRequestErroron
filter_by(is_approved=True)because the attribute wasn't defined in
the model class._ensure_columnadds them to the DB but the ORM also
needs them in the model. Fixed inmodels.py.
v1.0a2.138 — Enhanced BBS Directory: TelnetBBSGuide + IPTIA tabs (June 2026)
- Three-tab BBS Directory — Local (existing peers + user self-submission
with sysop approval), TelnetBBSGuide (CSV fetched + cached every 6h),
IPTIA (same pattern). Each entry shows name, sysop, location, software,
description, and Telnet/Web connect buttons. Admin panel handles pending
approvals and manual external refresh. Newexternal_bbs_cachetable;
new columns onpeer_bbsesvia_ensure_column.
v1.0a2.137 — Session crash fix; nginx MRC auto-repair (June 2026)
-
Session crash on early disconnect —
UnboundLocalErrorinsession.start()
finallyblock when a connection exited before completing login (bot gate, failed
login, all nodes full)._hb_task = Nonewas inside the outertry; moved it
before thetryalongsidepresence = None.core/session.py. -
nginx MRC auto-repair —
update.shnow detects and inserts the missing
location /mrcws+location = /mrc-auth-checknginx blocks if absent.
Without them web MRC WebSocket connections returned 404 from gunicorn.
v1.0a2.136 — Security questions at terminal registration; sysop profile field control (June 2026)
-
Sysop profile field control — new
BuiltinFieldConfigmodel lets sysops
enable/disable each built-in profile field (Display Name, Bio, Location, Website,
Forum Signature, FTN Tagline, Date of Birth, Show Email Option) from
/admin/custom-fields. Disabled fields are hidden from both the profile edit
form and the public profile view. Defaults to all enabled. Custom fields
(add/edit/delete) remain on the same page. -
Security questions on terminal registration — new users registering via
telnet/SSH now complete the same 3 password-recovery security Q&A as web
registration. Questions are presented numbered; user picks 3 different ones
and enters answers. Answers saved viaUserSecurityAnswer(same table/hashing
as web). Implemented in_collect_security_questions()incore/session.py;
save_security_answers()added toUserManager.
v1.0a2.135 — Duplicate email DoS fix; case-insensitive usernames (June 2026)
- DoS crash fix — registering with a duplicate email caused an unhandled
IntegrityErrorthat terminated the BBS session. Addedemail_exists()and
username_exists()pre-checks in the registration loop; user is re-prompted
with a clear message instead of crashing.create_user()now returns a result
code string and catchesIntegrityErroras defense-in-depth. - Case-insensitive usernames — all username lookups (registration, login,
get_user, web form validation) now usefunc.lower()soStingRayand
stingrayare treated as the same account. Existing usernames unchanged.
v1.0a2.134 — MRC terminal fixes; Custom User Fields; User ID # (June 2026)
- MRC PAUSED indicator —
\x1b[1;37;43mbold white on orange (was invisible reverse-video in SyncTERM) - MRC char count — top-right of status bar shows remaining chars (140 - typed); cyan > 15, yellow ≤ 15, red if over
- MRC
/tDM local echo — after sending DM, client echoes[DM -> target] messagein pink - MRC tab autocomplete case fix — old code doubled wrong-case prefix; now deletes from start and re-inserts full canonical-case name
- MRC status bar live update —
_draw_status_line()called after every keypress, backspace, and Ctrl+U - Custom User Fields — new
UserField+UserFieldValuemodels; admin CRUD at/admin/custom-fields; field types: text/textarea/url/number/select; shown on public profile and admin user-manage page - User ID # —
user.id(auto-increment PK) displayed in admin users list and public profile page
v1.0a2.132 — ANEdit: CP437 char fix (■/·); slash /commands replace F-keys (June 2026)
- CP437 fix — title bar used
●/○(not in CP437), displayed as?on
SSH/telnet terminals. Replaced with■(CP437 0xFE, modified) and·(clean).
Also fixed em-dash—in flash messages and box titles. - Slash /commands — F-keys are unreliable over SSH. ANEdit now intercepts
/
typed at column 0 and reads a short command:/?or/help= help,/t= theme,
/m= mark,/cc= color picker,/find,/replace,/undo,/redo,/save,
/send,/q= abort. Unknown commands fall back to inserting the text. F-keys
retained as secondary bindings. Hint bar and help overlay updated.
v1.0a2.131 — ANEdit wired into message boards, PMs, echomail; board/thread coloring (June 2026)
- ANEdit now used for all message composition —
_post_compose,_send_pm,
and_compose_echomailall launch the full ANEdit screen editor instead of the
old line-by-line prompt. Reply flow pre-loads the parent post as>quoted text
and pre-fillsRe: subject. - Thread list coloring — board message list now uses full ANSI color: yellow
numbers, cyan reply count, white subject, green author, grey timestamp. Clears
screen and shows the board-name banner. - Thread reader coloring — post header shows yellow [OP]/grey [Reply N] tags,
cyan subject, green author. Quoted lines (>) rendered in grey. Footer + prompt
added.
v1.0a2.130 — ANEdit terminal message editor; security questions on registration (June 2026)
- ANEdit — new full-featured 79×23 ANSI message editor (
features/anedit.py).
Undo/redo (60 levels), block mark/cut/copy/paste, find & replace-all, smart
word-wrap, live word/char count, three color themes (F9), help overlay (F1),
Mystic |XX color-code picker (F4), draft auto-save every 30 s with recovery on
next entry. Entry point:await launch_anedit(session, quote, subject, username). - Security questions at registration — new users must now complete all 3
password-reset security questions during signup.RegisterFormextended with 3
SelectField+StringFieldpairs with duplicate-question validation. Answers
saved viaUserSecurityAnswerbefore commit.
v1.0a2.129 — IRC ESC exit fix; docs sidebar; bulletins; chat.ans; read/write security (June 2026)
- IRC startup ESC exit — ESC from startup screen now correctly exits IRC. Root
cause:run()loop condition checkednot self.bmswhich is always False (list
always has ≥1 bookmark). Fixed by having_startup_loop()return a boolean and
run()breaking onTrue. - Docs sidebar spacing — increased padding to 12px/16px, font-size 0.92rem,
line-height 1.6, min-width 250px (prior fix landed in local files but was not
in the v1.0a2.125 tarball that was deployed).
v1.0a2.126 — bug fixes: bulletins, docs sidebar, chat.ans, read/write security (June 2026)
- Bulletins HTML linefeed — swapped bulletin view default from
<pre>to
markdown (withnl2br);\r\nfrom telnet input now renders as<br>instead
of blank lines. Raw view still accessible via toggle button. - chat.ans display codes —
chat.pynow passeschat.ansthrough
display_codes.apply()before writing, so Synchronet @-codes and Mystic |XX
colors embedded in the ANSI screen are rendered correctly. - Docs sidebar spacing —
py-1→py-2,0.85rem→0.875rem,
line-height: 1.3→1.5; sidebar page list no longer cramped on long names. - Separate read/write access levels —
BoardandFileAreanow have a
min_write_levelcolumn (NULL = inherit read level). Admin UI updated with
side-by-side fields.web/boards.pyandbbs_ui.pyenforce write level on
post creation and file upload respectively. Auto-migrated on startup.
v1.0a2.125 — ANetIRC v7: pure-Python asyncio IRC client (June 2026)
Complete rewrite of ANetIRC. Drops the C binary + PTY bridge entirely. The new
anetirc2.py runs as a native asyncio coroutine inside the BBS session.
- TLS fixed —
asyncio.open_connection(ssl=ssl_ctx)is non-blocking; the
old C client's blocking TLS handshake caused hard lockups on SSL servers. - Cross-arch — no binary; works on x86-64, ARM, any Python 3.10+ platform.
- SASL PLAIN — full
CAP LS 302→CAP REQ :sasl→AUTHENTICATE PLAIN
state machine. Password field (7th pipe field) triggers SASL; no password = no
SASL (plain nick/user registration). - Startup manager — inline field editing per bookmark (Tab/Up/Down to move
between fields, Enter to confirm), TLS toggle (Space), theme cycle (T), save
(A), delete (D). Three color themes: Cyan/Green/Amber. - Word-wrap — lines break at word boundaries; continuation lines indent to
align with message text. Adapts to any terminal width. - Scrollback — PgUp/PgDn, 800 display rows, 2000 stored lines.
- Tab completion — completes nick from users panel; cycles on repeated Tab.
- Command history — Up/Down arrows recall previous input lines.
- mIRC color — incoming color codes stripped; CTCP ACTION rendered as
* nick action. - Backward-compatible — same bookmark config format, same entry point
(launch_anetirc_telnet). C binary kept in tarball for reference/revert.