More work on post visibility

This commit is contained in:
Thomas Sileo 2019-07-15 23:08:12 +02:00
parent 866979309c
commit 8e977a2b14
9 changed files with 59 additions and 38 deletions

View file

@ -124,6 +124,9 @@ class MicroblogPubBackend(Backend):
object_id = activity.get_object_id() object_id = activity.get_object_id()
except ValueError: except ValueError:
pass pass
object_visibility = None
if object_id:
object_visibility = ap.get_visibility(activity.get_object())
actor_id = activity.get_actor().id actor_id = activity.get_actor().id
@ -141,6 +144,7 @@ class MicroblogPubBackend(Backend):
"visibility": visibility.name, "visibility": visibility.name,
"actor_id": actor_id, "actor_id": actor_id,
"object_id": object_id, "object_id": object_id,
"object_visibility": object_visibility.name,
"poll_answer": False, "poll_answer": False,
}, },
} }
@ -670,7 +674,7 @@ def gen_feed():
fg.logo(ME.get("icon", {}).get("url")) fg.logo(ME.get("icon", {}).get("url"))
fg.language("en") fg.language("en")
for item in DB.activities.find( for item in DB.activities.find(
{"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False}, limit=10 {"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False, "meta.public": True}, limit=10
).sort("_id", -1): ).sort("_id", -1):
fe = fg.add_entry() fe = fg.add_entry()
fe.id(item["activity"]["object"].get("url")) fe.id(item["activity"]["object"].get("url"))
@ -684,7 +688,7 @@ def json_feed(path: str) -> Dict[str, Any]:
"""JSON Feed (https://jsonfeed.org/) document.""" """JSON Feed (https://jsonfeed.org/) document."""
data = [] data = []
for item in DB.activities.find( for item in DB.activities.find(
{"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False}, limit=10 {"box": Box.OUTBOX.value, "type": "Create", "meta.deleted": False, "meta.public": True}, limit=10
).sort("_id", -1): ).sort("_id", -1):
data.append( data.append(
{ {

17
app.py
View file

@ -247,6 +247,16 @@ def _get_file_url(url, size, kind):
return url return url
@app.template_filter()
def visibility(v: str) -> str:
return ap.Visibility[v].value.lower()
@app.template_filter()
def visibility_is_public(v: str) -> bool:
return v in [ap.Visibility.PUBLIC.name, ap.Visibility.UNLISTED.name]
@app.template_filter() @app.template_filter()
def emojify(text): def emojify(text):
return emoji_unicode.replace( return emoji_unicode.replace(
@ -1691,6 +1701,10 @@ def api_delete():
def api_boost(): def api_boost():
note = _user_api_get_note() note = _user_api_get_note()
# Ensures the note visibility allow us to build an Announce (in respect to the post visibility)
if ap.get_visibility(note) not in [ap.Visibility.PUBLIC, ap.VISIBILITY.UNLISTED]:
abort(400)
announce = note.build_announce(MY_PERSON) announce = note.build_announce(MY_PERSON)
announce_id = post_to_outbox(announce) announce_id = post_to_outbox(announce)
@ -1841,6 +1855,7 @@ def admin_bookmarks():
@app.route("/inbox", methods=["GET", "POST"]) # noqa: C901 @app.route("/inbox", methods=["GET", "POST"]) # noqa: C901
def inbox(): def inbox():
# GET /inbox
if request.method == "GET": if request.method == "GET":
if not is_api_request(): if not is_api_request():
abort(404) abort(404)
@ -1859,6 +1874,7 @@ def inbox():
) )
) )
# POST/ inbox
try: try:
data = request.get_json(force=True) data = request.get_json(force=True)
except Exception: except Exception:
@ -3125,6 +3141,7 @@ def task_fetch_remote_question():
} }
) )
remote_question = get_backend().fetch_iri(iri, no_cache=True) remote_question = get_backend().fetch_iri(iri, no_cache=True)
# FIXME(tsileo): compute and set `meta.object_visiblity` (also update utils.py to do it)
if ( if (
local_question local_question
and ( and (

View file

@ -104,4 +104,5 @@ class _1_MetaMigrationt(Migration):
set_meta["meta.server"] = urlparse(data["remote_id"]).netloc set_meta["meta.server"] = urlparse(data["remote_id"]).netloc
logger.info(f"meta={set_meta}\n") logger.info(f"meta={set_meta}\n")
if set_meta:
DB.activities.update_one({"_id": data["_id"]}, {"$set": set_meta}) DB.activities.update_one({"_id": data["_id"]}, {"$set": set_meta})

View file

@ -270,19 +270,20 @@ a:hover {
float: left; float: left;
border-radius:2px; border-radius:2px;
} }
.bar-icon {
background: $background-color;
padding: 5px;
color: $color-light;
margin-right: 10px;
float: left;
border: none;
}
.bar-item:hover { .bar-item:hover {
background: $primary-color; background: $primary-color;
color: $background-color; color: $background-color;
} }
.bar-item-no-border {
color: $color-light;
background: inherit;
cursor: default;
}
.bar-item-no-border:hover {
color: $color-light;
background: inherit;
cursor: default;
}
button.bar-item { button.bar-item {
border: 0 border: 0
} }

View file

@ -53,7 +53,7 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if item.meta.object %} {% if item.meta.object %}
{{ utils.display_note(item.meta.object, ui=False, meta={'actor': item.meta.object_actor}) }} {{ utils.display_note(item.meta.object, ui=False, meta=item.meta) }}
{% endif %} {% endif %}
{% elif item | has_type('Create') %} {% elif item | has_type('Create') %}
{{ utils.display_note(item.activity.object, meta=item.meta, no_color=True) }} {{ utils.display_note(item.activity.object, meta=item.meta, no_color=True) }}

View file

@ -6,13 +6,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{% block title %}{{ config.NAME }}{% endblock %}'s microblog</title> <title>{% block title %}{{ config.NAME }}{% endblock %}'s microblog</title>
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous"> <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" integrity="sha384-nn4HPE8lTHyVtfCBi5yW9d20FjT8BJwUXyWZT9InLYax14RDjBj46LmSztkmNP9w" crossorigin="anonymous">
<link rel="stylesheet" href="/static/css/feathericon.min.css">
<link rel="authorization_endpoint" href="{{ config.ID }}/indieauth"> <link rel="authorization_endpoint" href="{{ config.ID }}/indieauth">
<link rel="token_endpoint" href="{{ config.ID }}/token"> <link rel="token_endpoint" href="{{ config.ID }}/token">
{% if not request.args.get("older_than") and not request.args.get("previous_than") %}<link rel="canonical" href="https://{{ config.DOMAIN }}{{ request.path }}">{% endif %} {% if not request.args.get("older_than") and not request.args.get("previous_than") %}<link rel="canonical" href="https://{{ config.DOMAIN }}{{ request.path }}">{% endif %}
{% block links %}{% endblock %} {% block links %}{% endblock %}
{% if config.THEME_COLOR %}<meta name="theme-color" content="{{ config.THEME_COLOR }}">{% endif %} {% if config.THEME_COLOR %}<meta name="theme-color" content="{{ config.THEME_COLOR }}">{% endif %}
<style>{{ config.CSS | safe }} <style>{{ config.CSS | safe }}
.icon { color: #555; }
.emoji { .emoji {
width: 20px; width: 20px;
} }

View file

@ -20,7 +20,7 @@
{% endif %} {% endif %}
{% if item.meta.object %} {% if item.meta.object %}
{{ utils.display_note(item.meta.object, meta={'actor': item.meta.object_actor}) }} {{ utils.display_note(item.meta.object, meta=item.meta) }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View file

@ -18,7 +18,7 @@
<p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover"><a style="color:#808080;" href="{{ boost_actor.url | get_url }}">{{ boost_actor.name or boost_actor.preferredUsername }}</a> boosted</span></p> <p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover"><a style="color:#808080;" href="{{ boost_actor.url | get_url }}">{{ boost_actor.name or boost_actor.preferredUsername }}</a> boosted</span></p>
{% endif %} {% endif %}
{% if item.meta.object %} {% if item.meta.object %}
{{ utils.display_note(item.meta.object, ui=True) }} {{ utils.display_note(item.meta.object, ui=True, meta=item.meta) }}
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -26,7 +26,7 @@
{% set boost_actor = item.meta.actor %} {% set boost_actor = item.meta.actor %}
<p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover"><a style="color:#808080;" href="{{ boost_actor.url | get_url }}">{{ boost_actor.name or boost_actor.preferredUsername }}</a> liked</span></p> <p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover"><a style="color:#808080;" href="{{ boost_actor.url | get_url }}">{{ boost_actor.name or boost_actor.preferredUsername }}</a> liked</span></p>
{% if item.meta.object %} {% if item.meta.object %}
{{ utils.display_note(item.meta.object, ui=False, meta={'actor': item.meta.object_actor}) }} {{ utils.display_note(item.meta.object, ui=False, meta=item.meta) }}
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -58,7 +58,7 @@
{% if item | has_type('question_ended') %} {% if item | has_type('question_ended') %}
<p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover">poll ended</span></p> <p style="margin-left:70px;padding-bottom:5px;display:inline-block;"><span class="bar-item-no-hover">poll ended</span></p>
{{ utils.display_note(item.activity) }} {{ utils.display_note(item.activity, meta={"object_visibility": "PUBLIC"}) }}
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -17,7 +17,9 @@
{% macro display_note(obj, perma=False, ui=False, likes=[], shares=[], meta={}, no_color=False) -%} {% macro display_note(obj, perma=False, ui=False, likes=[], shares=[], meta={}, no_color=False) -%}
{% if meta.actor %} {% if meta.object_actor %}
{% set actor = meta.object_actor %}
{% elif meta.actor %}
{% set actor = meta.actor %} {% set actor = meta.actor %}
{% else %} {% else %}
{% set actor = obj.attributedTo | get_actor %} {% set actor = obj.attributedTo | get_actor %}
@ -51,12 +53,11 @@
<div class="note-wrapper"> <div class="note-wrapper">
<div style="clear:both;height:20px;"> <div style="clear:both;height:20px;">
<a href="{{ actor | url_or_id | get_url }}" style="margin:0;text-decoration:none;margin: 0;text-decoration: none;display: block;width: 80%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;float: left;" class="no-hover"><strong>{{ actor.name or actor.preferredUsername }}</strong> <a href="{{ actor | url_or_id | get_url }}" style="margin:0;text-decoration:none;margin: 0;text-decoration: none;display: block;width: 75%;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;float: left;" class="no-hover"><strong>{{ actor.name or actor.preferredUsername }}</strong>
<span class="l">@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor.preferredUsername }}</span>{% else %}{{ actor.preferredUsername }}{% endif %}@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor | url_or_id | get_url | domain }}</span>{% else %}{{ actor | url_or_id | get_url | domain }}{% endif %}</span></a> <span class="l">@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor.preferredUsername }}</span>{% else %}{{ actor.preferredUsername }}{% endif %}@{% if not no_color and obj.id | is_from_outbox %}<span class="pcolor">{{ actor | url_or_id | get_url | domain }}</span>{% else %}{{ actor | url_or_id | get_url | domain }}{% endif %}</span></a>
{% if not perma %} {% if not perma %}
<span style="float:right;width: 20%;text-align: right;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;display: block;"> <span style="float:right;width: 25%;text-align: right;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;display: block;">
<i class="fe fe-unlock" title="Public" style="font-size:1em;padding-right:5px;"></i>
<a rel="noopener" class="u-url u-uid note-permalink l" href="{{ obj | url_or_id | get_url }}"> <a rel="noopener" class="u-url u-uid note-permalink l" href="{{ obj | url_or_id | get_url }}">
<time class="dt-published" title="{{ obj.published }}" datetime="{{ obj.published }}">{{ obj.published | format_timeago }}</time></a> <time class="dt-published" title="{{ obj.published }}" datetime="{{ obj.published }}">{{ obj.published | format_timeago }}</time></a>
</span> </span>
@ -164,27 +165,21 @@
<div class="bottom-bar"> <div class="bottom-bar">
{% if perma %} {% if perma %}
<span class="perma-item" style="float:left;padding:5px;">{{ obj.published | format_time }}</span> <span class="perma-item" style="float:left;padding:5px;">{{ obj.published | format_time }}</span>
{% if not (obj.id | is_from_outbox) %}
<a class="bar-icon" href="{{ obj | url_or_id | get_url }}">
<i class="fe fe-link-external"></i>
</a>
{% endif %}
{% else %}
<a class="bar-icon" style="font-size:1.5em;" href="{{ obj | url_or_id | get_url }}">
<i class="fe fe-link-external"></i>
</a>
{% endif %} {% endif %}
{% if meta.count_reply and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_reply }}</strong> replies</a> {% if meta.count_reply and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_reply }}</strong> replies</a>
{% elif meta.count_reply and session.logged_in %} {% elif meta.count_reply and session.logged_in %}
<a class="bar-item" href="/admin/thread?oid={{aid}}"><strong>{{ meta.count_reply }}</strong> replies</a>{% endif %} <a class="bar-item" href="/admin/thread?oid={{aid}}"><strong>{{ meta.count_reply }}</strong> replies</a>{% endif %}
{% if not perma and meta.count_boost and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_boost }}</strong> boosts</a>{% endif %} {% if not perma and meta.count_boost and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_boost }}</strong> boosts</a>{% endif %}
{% if not perma and meta.count_like and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_like }}</strong> likes</a>{% endif %} {% if not perma and meta.count_like and obj.id | is_from_outbox %}<a class ="bar-item" href="{{ obj.url | get_url }}"><strong>{{ meta.count_like }}</strong> likes</a>{% endif %}
{% if session.logged_in %} {% if session.logged_in %}
{% if ui%} {% if ui%}
<a class="bar-item" href="/admin/new?reply={{ aid }}">reply</a>
{% if meta.object_visibility | visibility_is_public %}
{% if meta.boosted %} {% if meta.boosted %}
<form action="/api/undo" class="action-form" method="POST"> <form action="/api/undo" class="action-form" method="POST">
<input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="redirect" value="{{ redir }}">
@ -197,11 +192,10 @@
<input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="redirect" value="{{ redir }}">
<input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="id" value="{{ obj.id }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button type="submit" class="bar-icon" style="font-size:1.5em;"> <button type="submit" class="bar-item">boost</button>
<i class="fe fe-share" title="Public"></i>
</button>
</form> </form>
{% endif %} {% endif %}
{% endif %}
{% if meta.liked %} {% if meta.liked %}
<form action="/api/undo" class="action-form" method="POST"> <form action="/api/undo" class="action-form" method="POST">
@ -244,7 +238,7 @@
<input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="redirect" value="{{ redir }}">
<input type="hidden" name="id" value="{{ obj.id }}"> <input type="hidden" name="id" value="{{ obj.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">delete</button> <button type="submit" class="bar-item" onclick="return confirm('Confirm the delete action?');">delete</button>
</form> </form>
{% if meta.pinned %} {% if meta.pinned %}
<form action="/api/note/unpin" class="action-form" method="POST"> <form action="/api/note/unpin" class="action-form" method="POST">
@ -267,12 +261,16 @@
<input type="hidden" name="redirect" value="{{ redir }}"> <input type="hidden" name="redirect" value="{{ redir }}">
<input type="hidden" name="actor" value="{{ actor.id }}"> <input type="hidden" name="actor" value="{{ actor.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">block</button> <button type="submit" class="bar-item" onclick="return confirm('Confirm the block action?');">block</button>
</form> </form>
{% endif %} {% endif %}
<a class="bar-item" href="/admin/new?reply={{ aid }}">reply</a>
{% endif %} {% endif %}
<a class="bar-item" href="{{ obj | url_or_id | get_url }}">permalink</a>
{% if session.logged_in %}
<a class="bar-item bar-item-no-border">{{ meta.object_visibility | visibility }}</a>
{% endif %}
</div> </div>