• AI Generated Usenet Client in Python

    From street@3:633/10 to All on Fri Dec 19 20:54:33 2025
    AI Generated Usenet Client in Python

    If you have any improvements to this or helpful ideas I would like to see the m.

    https://github.com/alt-magick/Newsgroup-Client-/

    #!/usr/bin/env python3
    import nntplib
    import sys
    import termios
    import tty
    import re
    import quopri
    import base64
    from email.message import EmailMessage
    import os
    import tempfile
    import subprocess

    # ================= USER CONFIG ===
    ==============
    NNTP_SERVER = "usnews.blocknews.net"
    NNTP_PORT = 563
    USERNAME = ""
    PASSWORD = ""
    PAGE_LINES = 12
    MAX_ARTICLES_LIST = 200
    MAX_REPLY_SCAN = 300
    START_GROUP = "alt.test"
    SHOW_REPLY_COUNT = False
    SHOW_REPLY_COUNT_MAIN = True
    # =========================
    =====================

    RE_REPLY = re.compile(r"^(re|fwd):", re.IGNORECASE)
    CLEAN_RE = re.compile(r"[- - -]")

    # ---------- STATUS LINE ----------
    STATUS_LINE = ""

    def set_status(msg):
    global STATUS_LINE
    STATUS_LINE = msg

    def show_status():
    global STATUS_LINE
    if STATUS_LINE:
    print(f"
    [{STATUS_LINE}]")
    STATUS_LINE = ""

    # ---------- RAW KEY INPUT ----------
    def get_key():
    fd = sys.stdin.fileno()
    old = termios.tcgetattr(fd)
    try:
    tty.setraw(fd)
    return sys.stdin.read(1)
    finally:
    termios.tcsetattr(fd, termios.TCSADRAIN, old)

    def prompt(text):
    sys.stdout.write(text)
    sys.stdout.flush()
    return sys.stdin.readline().strip()

    # ---------- HARD-CODED PAGER ----------
    def paged_print(lines):
    i = 0
    total = len(lines)
    while i < total:
    end = min(i + PAGE_LINES, total)
    for line in lines[i:end]:
    print(line)
    i = end
    if i >= total:
    break
    print("
    --- ENTER = next page | SPACE = skip ---")
    if get_key() == " ":
    break

    # ---------- BODY DECODER ----------
    def decode_body_line(line_bytes):
    s = line_bytes.decode("utf-8", errors="replace")
    s = CLEAN_RE.sub("", s)
    if "=" in s:
    try:
    s = quopri.decodestring(s).decode("utf-8", errors="replace")
    except Exception:
    pass
    if re.fullmatch(r"[A-Za-z0-9+/=\s]+", s) and len(s.strip()) > 20:
    try:
    s = base64.b64decode(s, validate=True).decode("utf-8", errors ="replace")
    except Exception:
    pass
    return s

    # ---------- POST BODY EDITOR ----------
    def edit_body(initial=""):
    editor = os.environ.get("EDITOR", "nano")
    fd, path = tempfile.mkstemp(suffix=".txt")
    try:
    with os.fdopen(fd, "w") as f:
    f.write(initial)
    subprocess.call([editor, path])
    with open(path, "r") as f:
    return f.read()
    finally:
    os.unlink(path)