forked from retoor/devplacepy
refactor: split database.py into package (ref.md 3.2)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
from .core import db, get_table
|
||||
from .relations import get_blocked_uids
|
||||
|
||||
|
||||
PAGE_SIZE = 25
|
||||
|
||||
|
||||
def paginate(
|
||||
table,
|
||||
*clauses,
|
||||
before=None,
|
||||
order=None,
|
||||
cursor_field="created_at",
|
||||
viewer_uid=None,
|
||||
**filters,
|
||||
):
|
||||
order = order or ["-" + cursor_field]
|
||||
clauses = list(clauses)
|
||||
if table.has_column("deleted_at") and "deleted_at" not in filters:
|
||||
clauses.append(table.table.columns.deleted_at.is_(None))
|
||||
if viewer_uid and table.has_column("user_uid"):
|
||||
blocked = get_blocked_uids(viewer_uid)
|
||||
if blocked:
|
||||
clauses.append(table.table.columns.user_uid.notin_(blocked))
|
||||
if before:
|
||||
clauses.append(table.table.columns[cursor_field] < before)
|
||||
rows = list(table.find(*clauses, **filters, order_by=order, _limit=PAGE_SIZE + 1))
|
||||
has_more = len(rows) > PAGE_SIZE
|
||||
rows = rows[:PAGE_SIZE]
|
||||
next_cursor = rows[-1][cursor_field] if has_more and rows else None
|
||||
return rows, next_cursor
|
||||
|
||||
|
||||
def interleave_by_author(rows, uid_key="user_uid"):
|
||||
remaining = list(rows)
|
||||
spread = []
|
||||
last_owner = object()
|
||||
while remaining:
|
||||
pick = next(
|
||||
(
|
||||
index
|
||||
for index, row in enumerate(remaining)
|
||||
if row.get(uid_key) != last_owner
|
||||
),
|
||||
0,
|
||||
)
|
||||
row = remaining.pop(pick)
|
||||
spread.append(row)
|
||||
last_owner = row.get(uid_key)
|
||||
return spread
|
||||
|
||||
|
||||
def paginate_diverse(
|
||||
table,
|
||||
*clauses,
|
||||
before=None,
|
||||
order=None,
|
||||
cursor_field="created_at",
|
||||
uid_key="user_uid",
|
||||
viewer_uid=None,
|
||||
**filters,
|
||||
):
|
||||
rows, next_cursor = paginate(
|
||||
table,
|
||||
*clauses,
|
||||
before=before,
|
||||
order=order,
|
||||
cursor_field=cursor_field,
|
||||
viewer_uid=viewer_uid,
|
||||
**filters,
|
||||
)
|
||||
return interleave_by_author(rows, uid_key=uid_key), next_cursor
|
||||
|
||||
|
||||
def get_user_post_count(user_uid: str) -> int:
|
||||
if "posts" not in db.tables:
|
||||
return 0
|
||||
return get_table("posts").count(user_uid=user_uid, deleted_at=None)
|
||||
|
||||
|
||||
def build_pagination(page, total, per_page=25):
|
||||
total_pages = max(1, __import__("math").ceil(total / per_page))
|
||||
page = max(1, min(page, total_pages))
|
||||
return {
|
||||
"page": page,
|
||||
"per_page": per_page,
|
||||
"total": total,
|
||||
"total_pages": total_pages,
|
||||
"has_prev": page > 1,
|
||||
"has_next": page < total_pages,
|
||||
"prev_page": page - 1,
|
||||
"next_page": page + 1,
|
||||
}
|
||||
Reference in New Issue
Block a user