No root nodes found.
-{% endif %}
+
+
+
+{# --- PEOPLE WAITING ON US --- #}
+
+
people waiting on us {% if pending_requests %}{{ pending_requests|length }}{% endif %}
+ {% if pending_requests %}
+
these people chose us over disqus. don't leave them hanging.
+ {% for req in pending_requests %}
+
+ {% endfor %}
+ {% else %}
+
everyone's taken care of. nice work.
+ {% endif %}
+
+
+{# --- MODERATION QUEUE --- #}
+
+
needs a human eye {% if held_nodes %}{{ held_nodes|length }}{% endif %}
+ {% if held_nodes %}
+
held for moderation. approve the good stuff, kill the noise.
+ {% for node in held_nodes[:15] %}
+
+ {% endfor %}
+ {% if held_nodes|length > 15 %}
...and {{ held_nodes|length - 15 }} more
{% endif %}
+ {% else %}
+
queue is clean. the community is behaving.
+ {% endif %}
+
+
+{# --- SPAM FLAGGED --- #}
+
+
spam filter catches {% if spam_flagged %}{{ spam_flagged|length }}{% endif %}
+ {% if spam_flagged %}
+
machine learning flagged these but didn't kill them. your call.
+ {% for node in spam_flagged[:10] %}
+
+ {% endfor %}
+ {% else %}
+
nothing suspicious right now.
+ {% endif %}
+
+
+{# --- NEW HUMANS --- #}
+
+
new humans this week {% if new_users %}{{ new_users|length }}{% endif %}
+ {% if new_users %}
+ {% for user in new_users[:20] %}
+
+
{{ user.name }}
+
— {{ user.email }}{% if user.verified %} (verified){% else %} (unverified){% endif %}
+
+ {% endfor %}
+ {% if new_users|length > 20 %}
...and {{ new_users|length - 20 }} more
{% endif %}
+ {% else %}
+
quiet week. that's okay.
+ {% endif %}
+
+
+{# --- MOST ALIVE NAMESPACES --- #}
+
+
most alive namespaces (last 30 days)
+ {% if active_namespaces %}
+
+ {% for ns_name, ns_id, count in active_namespaces %}
+
+ {% endfor %}
+
+ {% else %}
+
no thread activity in the last 30 days.
+ {% endif %}
+
+
+{# --- RECENT THREADS --- #}
+
+
recent threads
+ {% if nodes %}
+ {%- for node in nodes %}
+
+
+ {% if node.user %}{{ snippets.user_link(node.user) }}{% endif %}
+ {{ node.human_changed_timestamp }}
+ {% if node.namespace %} in {{ node.namespace.name }}{% endif %}
+
+
+ {% if node.has_uri -%}
+
{{ node.uri.data }}
+ {% else -%}
+
{{ node.title }}
+ {% endif -%}
+
{{ node.stats["root"]["visible_count"] }} remarks
+
+ {% endfor -%}
+ {% else %}
+
no threads yet. we're early.
+ {% endif %}
+
+
+
{%- endblock -%}
diff --git a/remarkbox/views/authenticated/topsecret.py b/remarkbox/views/authenticated/topsecret.py
index 197cf01..2d6220b 100644
--- a/remarkbox/views/authenticated/topsecret.py
+++ b/remarkbox/views/authenticated/topsecret.py
@@ -1,6 +1,10 @@
+import time
+
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
+from sqlalchemy import func, or_
+
from remarkbox.models import (
get_topsecret_namespace_requests,
get_topsecret_notifications,
@@ -9,8 +13,12 @@ from remarkbox.models import (
get_topsecret_nodes,
)
from remarkbox.models.user import get_user_by_email, User
+from remarkbox.models.node import Node
+from remarkbox.models.namespace import Namespace
+from remarkbox.models.namespace_request import NamespaceRequest
from remarkbox.models.sudo_otp import verify_sudo_otp
+from remarkbox.lib import timestamp_to_ago_string
from remarkbox.lib.sudo import request_sudo_otp
from remarkbox.views import super_fly_required
@@ -66,10 +74,84 @@ def topsecret_notifications(request):
@view_config(route_name="topsecret", renderer="topsecret-dashboard.j2")
@super_fly_required
-def topsecret_roots(request):
+def topsecret_dashboard(request):
+ db = request.dbsession
+ now_ms = int(time.time() * 1000)
+ seven_days_ms = 7 * 24 * 60 * 60 * 1000
+ thirty_days_ms = 30 * 24 * 60 * 60 * 1000
+
+ # --- Totals ---
+ total_users = db.query(func.count(User.id)).scalar()
+ total_namespaces = db.query(func.count(Namespace.id)).scalar()
+ total_nodes = db.query(func.count(Node.id)).scalar()
+
+ # --- People waiting on us ---
+ pending_requests = (
+ db.query(NamespaceRequest)
+ .filter(NamespaceRequest.verified == False)
+ .order_by(NamespaceRequest.created_timestamp.asc())
+ .all()
+ )
+
+ # --- New humans (last 7 days) ---
+ new_users = (
+ db.query(User)
+ .filter(User.created > now_ms - seven_days_ms, User.disabled == False)
+ .order_by(User.created.desc())
+ .all()
+ )
+
+ # --- Moderation queue ---
+ held_nodes = (
+ db.query(Node)
+ .filter(
+ or_(Node.approved == False, Node.approved.is_(None)),
+ Node.disabled == False,
+ )
+ .order_by(Node.created.desc())
+ .limit(50)
+ .all()
+ )
+
+ # --- Flagged by spam filter but not killed ---
+ spam_flagged = (
+ db.query(Node)
+ .filter(Node.spam_score >= 0.5, Node.disabled == False)
+ .order_by(Node.spam_score.desc())
+ .limit(50)
+ .all()
+ )
+
+ # --- Most active namespaces (last 30 days) ---
+ active_namespaces = (
+ db.query(
+ Namespace.name,
+ Namespace.id,
+ func.count(Node.id).label("node_count"),
+ )
+ .join(Node, Node.namespace_id == Namespace.id)
+ .filter(Node.created > now_ms - thirty_days_ms)
+ .group_by(Namespace.id)
+ .order_by(func.count(Node.id).desc())
+ .limit(20)
+ .all()
+ )
+
+ # --- Recent root nodes ---
+ recent_roots = get_topsecret_roots(db).limit(50)
+
return {
- "nodes": get_topsecret_roots(request.dbsession).limit(1000),
- "the_title": "topsecret dashboard",
+ "the_title": "topsecret",
+ "total_users": total_users,
+ "total_namespaces": total_namespaces,
+ "total_nodes": total_nodes,
+ "pending_requests": pending_requests,
+ "new_users": new_users,
+ "held_nodes": held_nodes,
+ "spam_flagged": spam_flagged,
+ "active_namespaces": active_namespaces,
+ "nodes": recent_roots,
+ "ago": timestamp_to_ago_string,
}