(owner: str, file_storage)
| 18567 | try: |
| 18568 | if int(r.get("has_voice") or 0): |
| 18569 | v = conn.execute("SELECT id, mime FROM discussion_voice WHERE msg_id=? ORDER BY id DESC LIMIT 1", (r["id"],)).fetchone() |
| 18570 | except Exception: |
| 18571 | v = None |
| 18572 | try: |
| 18573 | if int(r.get("has_file") or 0): |
| 18574 | f = conn.execute("SELECT id, filename, mime, size FROM discussion_files WHERE msg_id=? ORDER BY id DESC LIMIT 1", (r["id"],)).fetchone() |
| 18575 | except Exception: |
| 18576 | f = None |
| 18577 | |
| 18578 | try: |
| 18579 | body = aesgcm_decrypt_text(r["body_enc"]) |
| 18580 | except Exception: |
| 18581 | body = "[decrypt failed]" |
| 18582 | |
| 18583 | kind = ("voice" if v else ("file" if f else "text")) |
| 18584 | |
| 18585 | return { |
| 18586 | "id": int(r["id"]), |
| 18587 | "sender": r["sender"], |
| 18588 | "kind": kind, |
| 18589 | "body": body if kind == "text" else (body if body else ""), |
| 18590 | "created_at_local": _local_time_str(r["created_at"]), |
| 18591 | "created_at_utc": r["created_at"], |
| 18592 | "voice_id": v["id"] if v else None, |
| 18593 | "voice_mime": v["mime"] if v else "audio/webm", |
| 18594 | "file_id": f["id"] if f else None, |
| 18595 | "file_name": f["filename"] if f else None, |
| 18596 | "file_mime": f["mime"] if f else None, |
| 18597 | "file_size_h": human_size(int(f["size"])) if (f and f["size"] is not None) else "", |
| 18598 | "file_is_image": True if (f and (f["mime"] or "").startswith("image/")) else False, |
| 18599 | "file_is_video": True if (f and (f["mime"] or "").startswith("video/")) else False, |
| 18600 | "file_is_audio": True if (f and (f["mime"] or "").startswith("audio/")) else False, |
| 18601 | } |
| 18602 | |
| 18603 | |
| 18604 | def _render_discussion_row_html(m: Dict[str, Any], me: str) -> str: |
| 18605 | return render_template_string(_DISCUSS_ROW_TEMPLATE, m=m, me=me) |
| 18606 | |
| 18607 | |
| 18608 | @app.route("/discussion") |
| 18609 | @login_required |
| 18610 | def discussion(): |
| 18611 | _feature_tables_init() |
| 18612 | q_raw = (request.args.get("q") or "").strip() |
| 18613 | q = q_raw.lower() |
| 18614 | me = current_user() |
| 18615 | conn = db_connect() |
| 18616 | try: |
| 18617 | rows = conn.execute( |
| 18618 | "SELECT id, sender, body_enc, created_at, has_voice, has_file FROM discussion_messages ORDER BY id DESC LIMIT 300" |
| 18619 | ).fetchall() |
| 18620 | items = [] |
| 18621 | for r in rows: |
| 18622 | rr = dict(r) |
| 18623 | msg = _discussion_build_message_dict(conn, rr, me) |
| 18624 | # server-side filter for initial page render |
| 18625 | if q: |
| 18626 | hay = f"{msg.get('sender','')} {msg.get('body','')}".lower() |
no test coverage detected