Cull a bunch of unused functions

This commit is contained in:
Jack Kingsman
2026-03-12 18:12:27 -07:00
parent 74c13d194c
commit 358589bd66
10 changed files with 22 additions and 990 deletions
-9
View File
@@ -158,15 +158,8 @@ app/
- `GET /contacts`
- `GET /contacts/analytics` — unified keyed-or-name analytics payload
- `GET /contacts/repeaters/advert-paths` — recent advert paths for all contacts
- `GET /contacts/name-detail` — name-only activity summary for unresolved channel senders
- `GET /contacts/{public_key}`
- `GET /contacts/{public_key}/detail` — comprehensive contact profile (stats, name history, paths, nearest repeaters)
- `GET /contacts/{public_key}/advert-paths` — recent advert paths for one contact
- `POST /contacts`
- `DELETE /contacts/{public_key}`
- `POST /contacts/sync`
- `POST /contacts/{public_key}/add-to-radio`
- `POST /contacts/{public_key}/remove-from-radio`
- `POST /contacts/{public_key}/mark-read`
- `POST /contacts/{public_key}/command`
- `POST /contacts/{public_key}/routing-override`
@@ -184,10 +177,8 @@ app/
### Channels
- `GET /channels`
- `GET /channels/{key}/detail`
- `GET /channels/{key}`
- `POST /channels`
- `DELETE /channels/{key}`
- `POST /channels/sync`
- `POST /channels/{key}/flood-scope-override`
- `POST /channels/{key}/mark-read`
+1 -41
View File
@@ -1,16 +1,12 @@
import logging
from hashlib import sha256
from fastapi import APIRouter, HTTPException, Query
from meshcore import EventType
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field
from app.dependencies import require_connected
from app.models import Channel, ChannelDetail, ChannelMessageCounts, ChannelTopSender
from app.radio_sync import upsert_channel_from_radio_slot
from app.region_scope import normalize_region_scope
from app.repository import ChannelRepository, MessageRepository
from app.services.radio_runtime import radio_runtime as radio_manager
from app.websocket import broadcast_event
logger = logging.getLogger(__name__)
@@ -59,15 +55,6 @@ async def get_channel_detail(key: str) -> ChannelDetail:
)
@router.get("/{key}", response_model=Channel)
async def get_channel(key: str) -> Channel:
"""Get a specific channel by key (32-char hex string)."""
channel = await ChannelRepository.get_by_key(key)
if not channel:
raise HTTPException(status_code=404, detail="Channel not found")
return channel
@router.post("", response_model=Channel)
async def create_channel(request: CreateChannelRequest) -> Channel:
"""Create a channel in the database.
@@ -110,33 +97,6 @@ async def create_channel(request: CreateChannelRequest) -> Channel:
return stored
@router.post("/sync")
async def sync_channels_from_radio(max_channels: int = Query(default=40, ge=1, le=40)) -> dict:
"""Sync channels from the radio to the database."""
require_connected()
logger.info("Syncing channels from radio (checking %d slots)", max_channels)
count = 0
async with radio_manager.radio_operation("sync_channels_from_radio") as mc:
for idx in range(max_channels):
result = await mc.commands.get_channel(idx)
if result.type == EventType.CHANNEL_INFO:
key_hex = await upsert_channel_from_radio_slot(result.payload, on_radio=True)
if key_hex is not None:
count += 1
stored = await ChannelRepository.get_by_key(key_hex)
if stored is not None:
_broadcast_channel_update(stored)
logger.debug(
"Synced channel %s: %s", key_hex, result.payload.get("channel_name")
)
logger.info("Synced %d channels from radio", count)
return {"synced": count}
@router.post("/{key}/mark-read")
async def mark_channel_read(key: str) -> dict:
"""Mark a channel as read (update last_read_at timestamp)."""
-155
View File
@@ -8,14 +8,11 @@ from app.dependencies import require_connected
from app.models import (
Contact,
ContactActiveRoom,
ContactAdvertPath,
ContactAdvertPathSummary,
ContactAnalytics,
ContactDetail,
ContactRoutingOverrideRequest,
ContactUpsert,
CreateContactRequest,
NameOnlyContactDetail,
NearestRepeater,
TraceResponse,
)
@@ -325,158 +322,6 @@ async def create_contact(
return stored
@router.get("/{public_key}/detail", response_model=ContactDetail)
async def get_contact_detail(public_key: str) -> ContactDetail:
"""Get comprehensive contact profile data.
Returns contact info, name history, message counts, most active rooms,
advertisement paths, advert frequency, and nearest repeaters.
"""
contact = await _resolve_contact_or_404(public_key)
analytics = await _build_keyed_contact_analytics(contact)
assert analytics.contact is not None
return ContactDetail(
contact=analytics.contact,
name_history=analytics.name_history,
dm_message_count=analytics.dm_message_count,
channel_message_count=analytics.channel_message_count,
most_active_rooms=analytics.most_active_rooms,
advert_paths=analytics.advert_paths,
advert_frequency=analytics.advert_frequency,
nearest_repeaters=analytics.nearest_repeaters,
)
@router.get("/name-detail", response_model=NameOnlyContactDetail)
async def get_name_only_contact_detail(
name: str = Query(min_length=1, max_length=200),
) -> NameOnlyContactDetail:
"""Get channel activity summary for a sender name without a resolved key."""
normalized_name = name.strip()
if not normalized_name:
raise HTTPException(status_code=400, detail="name is required")
analytics = await _build_name_only_contact_analytics(normalized_name)
return NameOnlyContactDetail(
name=analytics.name,
channel_message_count=analytics.channel_message_count,
most_active_rooms=analytics.most_active_rooms,
)
@router.get("/{public_key}", response_model=Contact)
async def get_contact(public_key: str) -> Contact:
"""Get a specific contact by public key or prefix."""
return await _resolve_contact_or_404(public_key)
@router.get("/{public_key}/advert-paths", response_model=list[ContactAdvertPath])
async def get_contact_advert_paths(
public_key: str,
limit: int = Query(default=10, ge=1, le=50),
) -> list[ContactAdvertPath]:
"""List recent unique advert paths for a contact."""
contact = await _resolve_contact_or_404(public_key)
return await ContactAdvertPathRepository.get_recent_for_contact(contact.public_key, limit)
@router.post("/sync")
async def sync_contacts_from_radio() -> dict:
"""Sync contacts from the radio to the database."""
require_connected()
logger.info("Syncing contacts from radio")
async with radio_manager.radio_operation("sync_contacts_from_radio") as mc:
result = await mc.commands.get_contacts()
if result.type == EventType.ERROR:
raise HTTPException(status_code=500, detail=f"Failed to get contacts: {result.payload}")
contacts = result.payload
count = 0
synced_keys: list[str] = []
for public_key, contact_data in contacts.items():
lower_key = public_key.lower()
await ContactRepository.upsert(
ContactUpsert.from_radio_dict(lower_key, contact_data, on_radio=True)
)
promoted_keys = await promote_prefix_contacts_for_contact(
public_key=lower_key,
log=logger,
)
synced_keys.append(lower_key)
await reconcile_contact_messages(
public_key=lower_key,
contact_name=contact_data.get("adv_name"),
log=logger,
)
stored = await ContactRepository.get_by_key(lower_key)
if stored is not None:
await _broadcast_contact_update(stored)
await _broadcast_contact_resolution(promoted_keys, stored)
count += 1
# Clear on_radio for contacts not found on the radio
await ContactRepository.clear_on_radio_except(synced_keys)
logger.info("Synced %d contacts from radio", count)
return {"synced": count}
@router.post("/{public_key}/remove-from-radio")
async def remove_contact_from_radio(public_key: str) -> dict:
"""Remove a contact from the radio (keeps it in database)."""
require_connected()
contact = await _resolve_contact_or_404(public_key)
async with radio_manager.radio_operation("remove_contact_from_radio") as mc:
# Get the contact from radio
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if not radio_contact:
# Already not on radio
await ContactRepository.set_on_radio(contact.public_key, False)
return {"status": "ok", "message": "Contact was not on radio"}
logger.info("Removing contact %s from radio", contact.public_key[:12])
result = await mc.commands.remove_contact(radio_contact)
if result.type == EventType.ERROR:
raise HTTPException(
status_code=500, detail=f"Failed to remove contact: {result.payload}"
)
await ContactRepository.set_on_radio(contact.public_key, False)
return {"status": "ok"}
@router.post("/{public_key}/add-to-radio")
async def add_contact_to_radio(public_key: str) -> dict:
"""Add a contact from the database to the radio."""
require_connected()
contact = await _resolve_contact_or_404(public_key, "Contact not found in database")
async with radio_manager.radio_operation("add_contact_to_radio") as mc:
# Check if already on radio
radio_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if radio_contact:
await ContactRepository.set_on_radio(contact.public_key, True)
return {"status": "ok", "message": "Contact already on radio"}
logger.info("Adding contact %s to radio", contact.public_key[:12])
result = await mc.commands.add_contact(contact.to_radio_dict())
if result.type == EventType.ERROR:
raise HTTPException(status_code=500, detail=f"Failed to add contact: {result.payload}")
await ContactRepository.set_on_radio(contact.public_key, True)
return {"status": "ok"}
@router.post("/{public_key}/mark-read")
async def mark_contact_read(public_key: str) -> dict:
"""Mark a contact conversation as read (update last_read_at timestamp)."""