forked from retoor/devplacepy
feat: add online presence tracking with last_seen column and configurable timeout
Add `last_seen` column to users table with index, implement `set_last_seen` and `get_online_users` database functions, expose presence config env vars (`PRESENCE_TIMEOUT_SECONDS`, `PRESENCE_ONLINE_LIMIT`, `PRESENCE_ONLINE_MARGIN_SECONDS`), include `last_seen` in follow list responses, and update profile docs to mention online indicator.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from .core import dataset, logging, Path, or_, defaultdict, datetime, timedelta, timezone, TTLCache, DATABASE_URL, DEFAULT_CORRECTION_PROMPT, DEFAULT_MODIFIER_PROMPT, INTERNAL_GATEWAY_URL, ensure_data_dirs, logger, db
|
||||
from .core import refresh_snapshot, _local_cache_versions, _cache_version_cache, _cache_state_ready, _ensure_cache_state, get_cache_version, bump_cache_version, sync_local_cache, _index, _drop_index, _uid_index, get_table, _in_clause, _now_iso
|
||||
from .settings import _settings_cache, get_setting, get_int_setting, set_setting, clear_settings_cache, internal_gateway_key
|
||||
from .users import get_users_by_uids, _admins_cache, invalidate_admins_cache, get_admin_uids, set_user_timezone, get_primary_admin_uid, search_users_by_username
|
||||
from .users import get_users_by_uids, _admins_cache, invalidate_admins_cache, get_admin_uids, set_user_timezone, set_last_seen, get_online_users, get_primary_admin_uid, search_users_by_username
|
||||
from .relations import _relations_cache, get_user_relations, get_blocked_uids, get_muted_uids, get_silenced_uids, invalidate_user_relations
|
||||
from .pagination import PAGE_SIZE, paginate, interleave_by_author, paginate_diverse, get_user_post_count, build_pagination
|
||||
from .soft_delete import SOFT_DELETE_TABLES, ensure_soft_delete_columns, soft_delete, soft_delete_in, restore, purge, list_deleted, count_deleted, restore_event, purge_event
|
||||
@@ -66,6 +66,8 @@ __all__ = [
|
||||
"invalidate_admins_cache",
|
||||
"get_admin_uids",
|
||||
"set_user_timezone",
|
||||
"set_last_seen",
|
||||
"get_online_users",
|
||||
"get_primary_admin_uid",
|
||||
"search_users_by_username",
|
||||
"_relations_cache",
|
||||
|
||||
@@ -45,6 +45,7 @@ def get_follow_list(
|
||||
"uid": person["uid"],
|
||||
"username": person["username"],
|
||||
"bio": (person.get("bio") or "")[:140],
|
||||
"last_seen": person.get("last_seen"),
|
||||
"followed_at": row.get("created_at"),
|
||||
}
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ def init_db():
|
||||
_index(db, "users", "idx_users_email", ["email"])
|
||||
_index(db, "users", "idx_users_api_key", ["api_key"])
|
||||
_index(db, "users", "idx_users_role", ["role", "created_at"])
|
||||
_index(db, "users", "idx_users_last_seen", ["last_seen"])
|
||||
_index(db, "posts", "idx_posts_user_uid", ["user_uid"])
|
||||
_index(db, "posts", "idx_posts_created_at", ["created_at"])
|
||||
_index(db, "posts", "idx_posts_topic", ["topic"])
|
||||
@@ -1117,6 +1118,8 @@ def backfill_api_keys() -> int:
|
||||
users.create_column_by_example("timezone", "")
|
||||
if not users.has_column("avatar_seed"):
|
||||
users.create_column_by_example("avatar_seed", "")
|
||||
if not users.has_column("last_seen"):
|
||||
users.create_column_by_example("last_seen", "")
|
||||
with db:
|
||||
db.query(
|
||||
"UPDATE users SET ai_modifier_enabled = 1 WHERE ai_modifier_enabled IS NULL"
|
||||
|
||||
@@ -47,6 +47,30 @@ def set_user_timezone(user_uid: str, tz_name: str) -> None:
|
||||
users.update({"uid": user_uid, "timezone": tz_name}, ["uid"])
|
||||
|
||||
|
||||
def set_last_seen(user_uid: str, iso: str) -> None:
|
||||
if "users" not in db.tables or not user_uid or not iso:
|
||||
return
|
||||
users = db["users"]
|
||||
if not users.has_column("last_seen"):
|
||||
users.create_column_by_example("last_seen", "")
|
||||
users.update({"uid": user_uid, "last_seen": iso}, ["uid"])
|
||||
|
||||
|
||||
def get_online_users(cutoff_iso: str, limit: int = 30) -> list:
|
||||
if "users" not in db.tables:
|
||||
return []
|
||||
users = db["users"]
|
||||
if "last_seen" not in users.columns:
|
||||
return []
|
||||
return list(
|
||||
users.find(
|
||||
last_seen={">=": cutoff_iso},
|
||||
order_by=["username"],
|
||||
_limit=limit,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_primary_admin_uid():
|
||||
sync_local_cache("admins", _admins_cache)
|
||||
cached = _admins_cache.get("primary")
|
||||
|
||||
Reference in New Issue
Block a user