forked from genewildish/Mainline
feat: introduce a 'code' mode to display source code lines, add new font assets, and include dedicated tests for code fetching.
This commit is contained in:
@@ -272,11 +272,10 @@ def main():
|
|||||||
time.sleep(0.07)
|
time.sleep(0.07)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
_subtitle = (
|
_subtitle = {
|
||||||
"literary consciousness stream"
|
"poetry": "literary consciousness stream",
|
||||||
if config.MODE == "poetry"
|
"code": "source consciousness stream",
|
||||||
else "digital consciousness stream"
|
}.get(config.MODE, "digital consciousness stream")
|
||||||
)
|
|
||||||
print(f" {W_DIM}v0.1 · {_subtitle}{RST}")
|
print(f" {W_DIM}v0.1 · {_subtitle}{RST}")
|
||||||
print(f" {W_GHOST}{'─' * (w - 4)}{RST}")
|
print(f" {W_GHOST}{'─' * (w - 4)}{RST}")
|
||||||
print()
|
print()
|
||||||
@@ -297,6 +296,14 @@ def main():
|
|||||||
)
|
)
|
||||||
print(f" {G_DIM}>{RST} {G_MID}{len(items)} STANZAS ACQUIRED{RST}")
|
print(f" {G_DIM}>{RST} {G_MID}{len(items)} STANZAS ACQUIRED{RST}")
|
||||||
save_cache(items)
|
save_cache(items)
|
||||||
|
elif config.MODE == "code":
|
||||||
|
from engine.fetch_code import fetch_code
|
||||||
|
slow_print(" > INITIALIZING SOURCE ARRAY...\n")
|
||||||
|
time.sleep(0.2)
|
||||||
|
print()
|
||||||
|
items, line_count, _ = fetch_code()
|
||||||
|
print()
|
||||||
|
print(f" {G_DIM}>{RST} {G_MID}{line_count} LINES ACQUIRED{RST}")
|
||||||
else:
|
else:
|
||||||
slow_print(" > INITIALIZING FEED ARRAY...\n")
|
slow_print(" > INITIALIZING FEED ARRAY...\n")
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|||||||
@@ -57,7 +57,11 @@ def list_repo_font_files():
|
|||||||
HEADLINE_LIMIT = 1000
|
HEADLINE_LIMIT = 1000
|
||||||
FEED_TIMEOUT = 10
|
FEED_TIMEOUT = 10
|
||||||
MIC_THRESHOLD_DB = 50 # dB above which glitches intensify
|
MIC_THRESHOLD_DB = 50 # dB above which glitches intensify
|
||||||
MODE = "poetry" if "--poetry" in sys.argv or "-p" in sys.argv else "news"
|
MODE = (
|
||||||
|
"poetry" if "--poetry" in sys.argv or "-p" in sys.argv
|
||||||
|
else "code" if "--code" in sys.argv
|
||||||
|
else "news"
|
||||||
|
)
|
||||||
FIREHOSE = "--firehose" in sys.argv
|
FIREHOSE = "--firehose" in sys.argv
|
||||||
|
|
||||||
# ─── NTFY MESSAGE QUEUE ──────────────────────────────────
|
# ─── NTFY MESSAGE QUEUE ──────────────────────────────────
|
||||||
|
|||||||
67
engine/fetch_code.py
Normal file
67
engine/fetch_code.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
"""
|
||||||
|
Source code feed — reads engine/*.py and emits non-blank, non-comment lines
|
||||||
|
as scroll items. Used by --code mode.
|
||||||
|
Depends on: nothing (stdlib only).
|
||||||
|
"""
|
||||||
|
|
||||||
|
import ast
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
_ENGINE_DIR = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
|
||||||
|
def _scope_map(source: str) -> dict[int, str]:
|
||||||
|
"""Return {line_number: scope_label} for every line in source.
|
||||||
|
|
||||||
|
Nodes are sorted by range size descending so inner scopes overwrite
|
||||||
|
outer ones, guaranteeing the narrowest enclosing scope wins.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
tree = ast.parse(source)
|
||||||
|
except SyntaxError:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
nodes = []
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
|
||||||
|
end = getattr(node, "end_lineno", node.lineno)
|
||||||
|
span = end - node.lineno
|
||||||
|
nodes.append((span, node))
|
||||||
|
|
||||||
|
# Largest range first → inner scopes overwrite on second pass
|
||||||
|
nodes.sort(key=lambda x: x[0], reverse=True)
|
||||||
|
|
||||||
|
scope = {}
|
||||||
|
for _, node in nodes:
|
||||||
|
end = getattr(node, "end_lineno", node.lineno)
|
||||||
|
if isinstance(node, ast.ClassDef):
|
||||||
|
label = node.name
|
||||||
|
else:
|
||||||
|
label = f"{node.name}()"
|
||||||
|
for ln in range(node.lineno, end + 1):
|
||||||
|
scope[ln] = label
|
||||||
|
|
||||||
|
return scope
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_code():
|
||||||
|
"""Read engine/*.py and return (items, line_count, 0).
|
||||||
|
|
||||||
|
Each item is (text, src, ts) where:
|
||||||
|
text = the code line (rstripped, indentation preserved)
|
||||||
|
src = enclosing function/class name, e.g. 'stream()' or '<module>'
|
||||||
|
ts = dotted module path, e.g. 'engine.scroll'
|
||||||
|
"""
|
||||||
|
items = []
|
||||||
|
for path in sorted(_ENGINE_DIR.glob("*.py")):
|
||||||
|
module = f"engine.{path.stem}"
|
||||||
|
source = path.read_text(encoding="utf-8")
|
||||||
|
scope = _scope_map(source)
|
||||||
|
for lineno, raw in enumerate(source.splitlines(), start=1):
|
||||||
|
stripped = raw.strip()
|
||||||
|
if not stripped or stripped.startswith("#"):
|
||||||
|
continue
|
||||||
|
label = scope.get(lineno, "<module>")
|
||||||
|
items.append((raw.rstrip(), label, module))
|
||||||
|
|
||||||
|
return items, len(items), 0
|
||||||
BIN
fonts/Kapiler.otf
Normal file
BIN
fonts/Kapiler.otf
Normal file
Binary file not shown.
BIN
fonts/Kapiler.ttf
Normal file
BIN
fonts/Kapiler.ttf
Normal file
Binary file not shown.
35
tests/test_fetch_code.py
Normal file
35
tests/test_fetch_code.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
from engine.fetch_code import fetch_code
|
||||||
|
|
||||||
|
|
||||||
|
def test_return_shape():
|
||||||
|
items, line_count, ignored = fetch_code()
|
||||||
|
assert isinstance(items, list)
|
||||||
|
assert line_count == len(items)
|
||||||
|
assert ignored == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_items_are_tuples():
|
||||||
|
items, _, _ = fetch_code()
|
||||||
|
assert items, "expected at least one code line"
|
||||||
|
for item in items:
|
||||||
|
assert isinstance(item, tuple) and len(item) == 3
|
||||||
|
text, src, ts = item
|
||||||
|
assert isinstance(text, str)
|
||||||
|
assert isinstance(src, str)
|
||||||
|
assert isinstance(ts, str)
|
||||||
|
|
||||||
|
|
||||||
|
def test_blank_and_comment_lines_excluded():
|
||||||
|
items, _, _ = fetch_code()
|
||||||
|
for text, _, _ in items:
|
||||||
|
assert text.strip(), "blank line should have been filtered"
|
||||||
|
assert not text.strip().startswith("#"), "comment line should have been filtered"
|
||||||
|
|
||||||
|
|
||||||
|
def test_module_path_format():
|
||||||
|
items, _, _ = fetch_code()
|
||||||
|
pattern = re.compile(r"^engine\.\w+$")
|
||||||
|
for _, _, ts in items:
|
||||||
|
assert pattern.match(ts), f"unexpected module path: {ts!r}"
|
||||||
Reference in New Issue
Block a user