Lists support (draft)

This commit is contained in:
Thomas Sileo 2019-07-22 20:32:35 +02:00
parent cbd7fc6446
commit fe4ea02cb0
4 changed files with 195 additions and 1 deletions

104
app.py
View file

@ -1578,6 +1578,14 @@ def admin_new():
) )
@app.route("/admin/lists", methods=["GET"])
@login_required
def admin_lists():
lists = list(DB.lists.find())
return render_template("lists.html", lists=lists)
@app.route("/admin/notifications") @app.route("/admin/notifications")
@login_required @login_required
def admin_notifications(): def admin_notifications():
@ -1895,6 +1903,34 @@ def admin_stream():
) )
@app.route("/admin/list/<name>")
@login_required
def admin_list(name):
list_ = DB.lists.find_one({"name": name})
if not list_:
abort(404)
q = {
"meta.stream": True,
"meta.deleted": False,
"meta.actor_id": {"$in": list_["members"]},
}
tpl = "stream.html"
if request.args.get("debug"):
tpl = "stream_debug.html"
if request.args.get("debug_inbox"):
q = {}
inbox_data, older_than, newer_than = paginated_query(
DB.activities, q, limit=int(request.args.get("limit", 25))
)
return render_template(
tpl, inbox_data=inbox_data, older_than=older_than, newer_than=newer_than
)
@app.route("/admin/bookmarks") @app.route("/admin/bookmarks")
@login_required @login_required
def admin_bookmarks(): def admin_bookmarks():
@ -2073,6 +2109,72 @@ def api_debug():
) )
@app.route("/api/new_list", methods=["POST"])
@api_required
def api_new_list():
name = _user_api_arg("name")
if not name:
raise ValueError("missing name")
if not DB.lists.find_one({"name": name}):
DB.lists.insert_one({"name": name, "members": []})
return _user_api_response(name=name)
@app.route("/api/delete_list", methods=["POST"])
@api_required
def api_delete_list():
name = _user_api_arg("name")
if not name:
raise ValueError("missing name")
if not DB.lists.find_one({"name": name}):
abort(404)
DB.lists.delete_one({"name": name})
return _user_api_response()
@app.route("/api/add_to_list", methods=["POST"])
@api_required
def api_add_to_list():
list_name = _user_api_arg("list_name")
if not list_name:
raise ValueError("missing list_name")
if not DB.lists.find_one({"name": list_name}):
raise ValueError(f"list {list_name} does not exist")
actor_id = _user_api_arg("actor_id")
if not actor_id:
raise ValueError("missing actor_id")
DB.lists.update_one({"name": list_name}, {"$addToSet": {"members": actor_id}})
return _user_api_response()
@app.route("/api/remove_from_list", methods=["POST"])
@api_required
def api_remove_from_list():
list_name = _user_api_arg("list_name")
if not list_name:
raise ValueError("missing list_name")
if not DB.lists.find_one({"name": list_name}):
raise ValueError(f"list {list_name} does not exist")
actor_id = _user_api_arg("actor_id")
if not actor_id:
raise ValueError("missing actor_id")
DB.lists.update_one({"name": list_name}, {"$pull": {"members": actor_id}})
return _user_api_response()
@app.route("/api/new_note", methods=["POST"]) @app.route("/api/new_note", methods=["POST"])
@api_required @api_required
def api_new_note(): def api_new_note():
@ -2322,11 +2424,13 @@ def following():
for doc in following for doc in following
if "remote_id" in doc and "object" in doc.get("meta", {}) if "remote_id" in doc and "object" in doc.get("meta", {})
] ]
lists = list(DB.lists.find())
return render_template( return render_template(
"following.html", "following.html",
following_data=following, following_data=following,
older_than=older_than, older_than=older_than,
newer_than=newer_than, newer_than=newer_than,
lists=lists,
) )

View file

@ -11,12 +11,40 @@
{% for (follow_id, follow) in following_data %} {% for (follow_id, follow) in following_data %}
{% if session.logged_in %} {% if session.logged_in %}
<div style="margin-left:90px;padding-bottom:5px;margin-bottom:15px;display:inline-block;"> <div style="margin-left:90px;padding-bottom:5px;margin-bottom:15px;display:inline-block;">
<form action="/api/undo" class="action-form" method="POST"> <form action="/api/undo" class="action-form" method="post">
<input type="hidden" name="redirect" value="{{ request.path }}"/> <input type="hidden" name="redirect" value="{{ request.path }}"/>
<input type="hidden" name="id" value="{{ follow_id }}"/> <input type="hidden" name="id" value="{{ follow_id }}"/>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<button type="submit" class="bar-item">unfollow</button> <button type="submit" class="bar-item">unfollow</button>
</form> </form>
<form action="/api/add_to_list" class="action-form" method="post">
<input type="hidden" name="redirect" value="{{ request.path }}"/>
<input type="hidden" name="actor_id" value="{{ follow.id }}"/>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<select name="list_name" style="float:left;">
<option></option>
{% for l in lists %}
{% if follow.id not in l.members %}
<option value="{{l.name}}">{{l.name}}</option>
{% endif %}
{% endfor %}
</select>
<button type="submit" class="bar-item">add to list</button>
</form>
{% for l in lists %}
{% if follow.id in l.members %}
<form action="/api/remove_from_list" class="action-form" method="post">
<input type="hidden" name="redirect" value="{{ request.path }}"/>
<input type="hidden" name="actor_id" value="{{ follow.id }}"/>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<button type="submit" class="bar-item">remove from {{ l.name }}</button>
</form>
{% endif %}
{% endfor %}
</div> </div>
{% endif %} {% endif %}

View file

@ -28,6 +28,7 @@
<li class="left"><a href="/admin/new"{% if request.path == "/admin/new" %} class="selected" {% endif %}>New</a></li> <li class="left"><a href="/admin/new"{% if request.path == "/admin/new" %} class="selected" {% endif %}>New</a></li>
<li class="left"><a href="/admin/stream"{% if request.path == "/admin/stream" %} class="selected" {% endif %}>Stream</a></li> <li class="left"><a href="/admin/stream"{% if request.path == "/admin/stream" %} class="selected" {% endif %}>Stream</a></li>
<li class="left"><a href="/admin/notifications"{% if request.path == "/admin/notifications" %} class="selected" {% endif %}>Notifications</a></li> <li class="left"><a href="/admin/notifications"{% if request.path == "/admin/notifications" %} class="selected" {% endif %}>Notifications</a></li>
<li class="left"><a href="/admin/lists"{% if request.path == url_for('admin_lists') %} class="selected" {% endif %}>Lists</a></li>
<li class="left"><a href="/admin/bookmarks"{% if request.path == "/admin/bookmarks" %} class="selected" {% endif %}>Bookmarks</a></li> <li class="left"><a href="/admin/bookmarks"{% if request.path == "/admin/bookmarks" %} class="selected" {% endif %}>Bookmarks</a></li>
<li class="left"><a href="/admin/lookup"{% if request.path == "/admin/lookup" %} class="selected" {% endif %}>Lookup</a></li> <li class="left"><a href="/admin/lookup"{% if request.path == "/admin/lookup" %} class="selected" {% endif %}>Lookup</a></li>
<li class="left"><a href="/admin/logout">Logout</a></li> <li class="left"><a href="/admin/logout">Logout</a></li>

61
templates/lists.html Normal file
View file

@ -0,0 +1,61 @@
{% extends "layout.html" %}
{% import 'utils.html' as utils %}
{% block title %}Lists - {{ config.NAME }}{% endblock %}
{% block headers %}
{% endblock %}
{% block content %}
<div id="container">
{% include "header.html" %}
<div id="following">
<h2>New List</h2>
<form action="/api/new_list" method="POST">
<input type="hidden" name="redirect" value="{{ url_for('admin_lists') }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<input type="text" name="name" placeholder="My list">
<input type="submit" value="Create">
</form>
<h2>Lists</h2>
<p>Manage list members in the <a href="{{ url_for('following') }}">Following section</a></p>
<ul>
{% for l in lists %}
<li><a href="{{url_for('admin_list', name=l.name)}}">{{ l.name }}</a></li>
{% endfor %}
</ul>
<h2>Manage lists</h2>
{% for l in lists %}
<h3><a href="{{url_for("admin_list", name=l.name)}}">{{ l.name }}</a> <small style="font-weight:normal">{{ l.members | length }} members</small></h3>
<form action="/api/delete_list" method="post">
<input type="hidden" name="redirect" value="{{ request.path }}"/>
<input type="hidden" name="name" value="{{ l.name }}"/>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<button type="submit" class="bar-item">delete list</button>
</form>
<div style="clear:both;padding-top:30px;">
{% for member in l.members %}
<div style="margin-left:90px;padding-bottom:5px;margin-bottom:15px;display:inline-block;">
<form action="/api/remove_from_list" class="action-form" method="post">
<input type="hidden" name="redirect" value="{{ request.path }}"/>
<input type="hidden" name="actor_id" value="{{ member }}"/>
<input type="hidden" name="list_name" value="{{ l.name }}"/>
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
<button type="submit" class="bar-item">remove from {{ l.name }}</button>
</form>
</div>
<div style="height: 100px;">
{{ utils.display_actor_inline(member | get_actor, size=80) }}
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}