Support actor update

This commit is contained in:
Thomas Sileo 2019-09-08 16:55:24 +02:00
parent cc89b0b584
commit 7f4be2cbc2
7 changed files with 55 additions and 5 deletions

View file

@ -22,10 +22,13 @@
- Compatible with [Mastodon](https://joinmastodon.org/) and others ([Pleroma](https://pleroma.social/), Misskey, Plume, PixelFed, Hubzilla...) - Compatible with [Mastodon](https://joinmastodon.org/) and others ([Pleroma](https://pleroma.social/), Misskey, Plume, PixelFed, Hubzilla...)
- Exposes your outbox as a basic microblog - Exposes your outbox as a basic microblog
- Support all content types from the Fediverse (`Note`, `Article`, `Page`, `Video`, `Image`, `Question`...) - Support all content types from the Fediverse (`Note`, `Article`, `Page`, `Video`, `Image`, `Question`...)
- Markdown support
- Server-side code syntax highlighting
- Comes with an admin UI with notifications and the stream of people you follow - Comes with an admin UI with notifications and the stream of people you follow
- Private "bookmark" support - Private "bookmark" support
- List support - List support
- Allows you to attach files to your notes - Allows you to attach files to your notes
- Custom emojus
- Cares about your privacy - Cares about your privacy
- The image upload endpoint strips EXIF meta data before storing the file - The image upload endpoint strips EXIF meta data before storing the file
- Every attachment/media is cached (or proxied) by the server - Every attachment/media is cached (or proxied) by the server

View file

@ -25,6 +25,7 @@ from core.activitypub import _actor_hash
from core.activitypub import _add_answers_to_question from core.activitypub import _add_answers_to_question
from core.activitypub import _cache_actor_icon from core.activitypub import _cache_actor_icon
from core.activitypub import is_from_outbox from core.activitypub import is_from_outbox
from core.activitypub import new_context
from core.activitypub import post_to_outbox from core.activitypub import post_to_outbox
from core.activitypub import save_reply from core.activitypub import save_reply
from core.activitypub import update_cached_actor from core.activitypub import update_cached_actor
@ -47,6 +48,7 @@ from core.shared import _Response
from core.shared import back from core.shared import back
from core.shared import p from core.shared import p
from core.tasks import Tasks from core.tasks import Tasks
from utils import now
from utils import opengraph from utils import opengraph
from utils.media import is_video from utils.media import is_video
from utils.webmentions import discover_webmention_endpoint from utils.webmentions import discover_webmention_endpoint
@ -102,6 +104,28 @@ def task_update_question() -> _Response:
return "" return ""
@blueprint.route("/task/send_actor_update", methods=["POST"])
def task_send_actor_update() -> _Response:
task = p.parse(flask.request)
app.logger.info(f"task={task!r}")
try:
update = ap.Update(
actor=MY_PERSON.id,
object=MY_PERSON.to_dict(),
to=[MY_PERSON.followers],
cc=[ap.AS_PUBLIC],
published=now(),
context=new_context(),
)
post_to_outbox(update)
except Exception as err:
app.logger.exception(f"failed to send actor update")
raise TaskError() from err
return ""
@blueprint.route("/task/fetch_og_meta", methods=["POST"]) @blueprint.route("/task/fetch_og_meta", methods=["POST"])
def task_fetch_og_meta() -> _Response: def task_fetch_og_meta() -> _Response:
task = p.parse(flask.request) task = p.parse(flask.request)

View file

@ -69,6 +69,7 @@ with open(os.path.join(KEY_DIR, "me.yml")) as f:
ICON_URL = conf["icon_url"] ICON_URL = conf["icon_url"]
PASS = conf["pass"] PASS = conf["pass"]
PROFILE_METADATA = conf.get("profile_metadata", {})
HIDE_FOLLOWING = conf.get("hide_following", True) HIDE_FOLLOWING = conf.get("hide_following", True)
# Theme-related config # Theme-related config
@ -130,8 +131,8 @@ def _admin_jwt_token() -> str:
ADMIN_API_KEY = get_secret_key("admin_api_key", _admin_jwt_token) ADMIN_API_KEY = get_secret_key("admin_api_key", _admin_jwt_token)
attachments = [] attachments = []
if conf.get("profile_metadata"): if PROFILE_METADATA:
for key, value in conf["profile_metadata"].items(): for key, value in PROFILE_METADATA.items():
attachments.append( attachments.append(
{"type": "PropertyValue", "name": key, "value": linkify(value)} {"type": "PropertyValue", "name": key, "value": linkify(value)}
) )
@ -176,7 +177,7 @@ BLACKLIST = conf.get("blacklist", [])
DISABLE_WEBMENTIONS = conf.get("disable_webmentions", False) DISABLE_WEBMENTIONS = conf.get("disable_webmentions", False)
# By default, we keep 14 of inbox data ; outbox is kept forever (along with bookmarked stuff, outbox replies, liked...) # By default, we keep 14 of inbox data ; outbox is kept forever (along with bookmarked stuff, outbox replies, liked...)
DAYS_TO_KEEP = 14 DAYS_TO_KEEP = int(conf.get("days_to_keep", 14))
# Load custom emojis (stored in static/emojis) # Load custom emojis (stored in static/emojis)
_load_emojis(ROOT_DIR, BASE_URL) _load_emojis(ROOT_DIR, BASE_URL)

View file

@ -78,7 +78,7 @@ def _answer_key(choice: str) -> str:
return h.hexdigest() return h.hexdigest()
def _actor_hash(actor: ap.ActivityType) -> str: def _actor_hash(actor: ap.ActivityType, local: bool = False) -> str:
"""Used to know when to update the meta actor cache, like an "actor version".""" """Used to know when to update the meta actor cache, like an "actor version"."""
h = hashlib.new("sha1") h = hashlib.new("sha1")
h.update(actor.id.encode()) h.update(actor.id.encode())
@ -91,6 +91,12 @@ def _actor_hash(actor: ap.ActivityType) -> str:
h.update(key.key_id().encode()) h.update(key.key_id().encode())
if isinstance(actor.icon, dict) and "url" in actor.icon: if isinstance(actor.icon, dict) and "url" in actor.icon:
h.update(actor.icon["url"].encode()) h.update(actor.icon["url"].encode())
if local:
# The local hash helps us detect when to send an Update
for item in actor.attachment:
h.update(item["name"].encode())
h.update(item["value"].encode())
h.update(("1" if actor.manuallyApprovesFollowers else "0").encode())
return h.hexdigest() return h.hexdigest()

View file

@ -8,8 +8,8 @@ from typing import Set
from little_boxes import activitypub as ap from little_boxes import activitypub as ap
from poussetaches import PousseTaches from poussetaches import PousseTaches
from config import MEDIA_CACHE
from config import DISABLE_WEBMENTIONS from config import DISABLE_WEBMENTIONS
from config import MEDIA_CACHE
from utils import parse_datetime from utils import parse_datetime
p = PousseTaches( p = PousseTaches(
@ -102,6 +102,10 @@ class Tasks:
def finish_post_to_outbox(iri: str) -> None: def finish_post_to_outbox(iri: str) -> None:
p.push(iri, "/task/finish_post_to_outbox") p.push(iri, "/task/finish_post_to_outbox")
@staticmethod
def send_actor_update() -> None:
p.push({}, "/task/send_actor_update", delay=2)
@staticmethod @staticmethod
def update_question_outbox(iri: str, open_for: int) -> None: def update_question_outbox(iri: str, open_for: int) -> None:
p.push( p.push(

View file

@ -11,6 +11,16 @@
<div class="p-note summary"> <div class="p-note summary">
{{ config.SUMMARY | safe }} {{ config.SUMMARY | safe }}
{% if config.PROFILE_METADATA %}
<dl>
{% for item in config.ME.attachment %}
{% if item.type == "PropertyValue" %}
<dt>{{item.name | safe }}</dt><dd>{{ item.value | safe }}</dd>
{% endif %}
{% endfor %}
</dl>
{% endif %}
</div> </div>
</div> </div>

View file

@ -21,6 +21,8 @@
width: 25px; width: 25px;
height: 25px; height: 25px;
} }
dt:after {content: ": ";}
dt, dd { font-size: 0.9em; }
{{ highlight_css }} {{ highlight_css }}
</style> </style>
{% block header %}{% endblock %} {% block header %}{% endblock %}