mirror of
https://git.sr.ht/~tsileo/microblog.pub
synced 2024-12-22 05:04:27 +00:00
Boostrap stream customization (API may change)
This commit is contained in:
parent
bd065446bf
commit
2cc4eda143
3 changed files with 73 additions and 4 deletions
22
app/boxes.py
22
app/boxes.py
|
@ -32,6 +32,8 @@ from app.config import BLOCKED_SERVERS
|
||||||
from app.config import ID
|
from app.config import ID
|
||||||
from app.config import MANUALLY_APPROVES_FOLLOWERS
|
from app.config import MANUALLY_APPROVES_FOLLOWERS
|
||||||
from app.config import set_moved_to
|
from app.config import set_moved_to
|
||||||
|
from app.config import stream_visibility_callback
|
||||||
|
from app.customization import ObjectInfo
|
||||||
from app.database import AsyncSession
|
from app.database import AsyncSession
|
||||||
from app.outgoing_activities import new_outgoing_activity
|
from app.outgoing_activities import new_outgoing_activity
|
||||||
from app.source import dedup_tags
|
from app.source import dedup_tags
|
||||||
|
@ -1881,16 +1883,30 @@ async def _process_note_object(
|
||||||
|
|
||||||
is_from_following = ro.actor.ap_id in {f.ap_actor_id for f in following}
|
is_from_following = ro.actor.ap_id in {f.ap_actor_id for f in following}
|
||||||
is_reply = bool(ro.in_reply_to)
|
is_reply = bool(ro.in_reply_to)
|
||||||
is_local_reply = (
|
is_local_reply = bool(
|
||||||
ro.in_reply_to
|
ro.in_reply_to
|
||||||
and ro.in_reply_to.startswith(BASE_URL)
|
and ro.in_reply_to.startswith(BASE_URL)
|
||||||
and ro.content # Hide votes from Question
|
and ro.content # Hide votes from Question
|
||||||
)
|
)
|
||||||
is_mention = False
|
is_mention = False
|
||||||
|
hashtags = []
|
||||||
tags = ro.ap_object.get("tag", [])
|
tags = ro.ap_object.get("tag", [])
|
||||||
for tag in ap.as_list(tags):
|
for tag in ap.as_list(tags):
|
||||||
if tag.get("name") == LOCAL_ACTOR.handle or tag.get("href") == LOCAL_ACTOR.url:
|
if tag.get("name") == LOCAL_ACTOR.handle or tag.get("href") == LOCAL_ACTOR.url:
|
||||||
is_mention = True
|
is_mention = True
|
||||||
|
if tag.get("type") == "Hashtag":
|
||||||
|
if tag_name := tag.get("name"):
|
||||||
|
hashtags.append(tag_name)
|
||||||
|
|
||||||
|
object_info = ObjectInfo(
|
||||||
|
is_reply=is_reply,
|
||||||
|
is_local_reply=is_local_reply,
|
||||||
|
is_mention=is_mention,
|
||||||
|
is_from_following=is_from_following,
|
||||||
|
hashtags=hashtags,
|
||||||
|
actor_handle=ro.actor.handle,
|
||||||
|
remote_object=ro,
|
||||||
|
)
|
||||||
|
|
||||||
inbox_object = models.InboxObject(
|
inbox_object = models.InboxObject(
|
||||||
server=urlparse(ro.ap_id).hostname,
|
server=urlparse(ro.ap_id).hostname,
|
||||||
|
@ -1908,9 +1924,7 @@ async def _process_note_object(
|
||||||
activity_object_ap_id=ro.activity_object_ap_id,
|
activity_object_ap_id=ro.activity_object_ap_id,
|
||||||
og_meta=await opengraph.og_meta_from_note(db_session, ro),
|
og_meta=await opengraph.og_meta_from_note(db_session, ro),
|
||||||
# Hide replies from the stream
|
# Hide replies from the stream
|
||||||
is_hidden_from_stream=not (
|
is_hidden_from_stream=not stream_visibility_callback(object_info),
|
||||||
(not is_reply and is_from_following) or is_mention or is_local_reply
|
|
||||||
),
|
|
||||||
# We may already have some replies in DB
|
# We may already have some replies in DB
|
||||||
replies_count=await _get_replies_count(db_session, ro.ap_id),
|
replies_count=await _get_replies_count(db_session, ro.ap_id),
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,6 +16,8 @@ from loguru import logger
|
||||||
from mistletoe import markdown # type: ignore
|
from mistletoe import markdown # type: ignore
|
||||||
|
|
||||||
from app.customization import _CUSTOM_ROUTES
|
from app.customization import _CUSTOM_ROUTES
|
||||||
|
from app.customization import _StreamVisibilityCallback
|
||||||
|
from app.customization import default_stream_visibility_callback
|
||||||
from app.utils.emoji import _load_emojis
|
from app.utils.emoji import _load_emojis
|
||||||
from app.utils.version import get_version_commit
|
from app.utils.version import get_version_commit
|
||||||
|
|
||||||
|
@ -262,3 +264,14 @@ def verify_csrf_token(
|
||||||
|
|
||||||
def hmac_sha256() -> hmac.HMAC:
|
def hmac_sha256() -> hmac.HMAC:
|
||||||
return hmac.new(CONFIG.secret.encode(), digestmod=hashlib.sha256)
|
return hmac.new(CONFIG.secret.encode(), digestmod=hashlib.sha256)
|
||||||
|
|
||||||
|
|
||||||
|
stream_visibility_callback: _StreamVisibilityCallback
|
||||||
|
try:
|
||||||
|
from data.stream import ( # type: ignore # noqa: F401, E501
|
||||||
|
custom_stream_visibility_callback,
|
||||||
|
)
|
||||||
|
|
||||||
|
stream_visibility_callback = custom_stream_visibility_callback
|
||||||
|
except ImportError:
|
||||||
|
stream_visibility_callback = default_stream_visibility_callback
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from fastapi import Request
|
from fastapi import Request
|
||||||
|
from loguru import logger
|
||||||
from starlette.responses import JSONResponse
|
from starlette.responses import JSONResponse
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from app.ap_object import RemoteObject
|
||||||
|
|
||||||
|
|
||||||
_DATA_DIR = Path().parent.resolve() / "data"
|
_DATA_DIR = Path().parent.resolve() / "data"
|
||||||
_Handler = Callable[..., Any]
|
_Handler = Callable[..., Any]
|
||||||
|
|
||||||
|
@ -110,3 +117,38 @@ def get_custom_router() -> APIRouter | None:
|
||||||
router.add_api_route(path, handler.handler)
|
router.add_api_route(path, handler.handler)
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ObjectInfo:
|
||||||
|
# Is it a reply?
|
||||||
|
is_reply: bool
|
||||||
|
|
||||||
|
# Is it a reply to an outbox object
|
||||||
|
is_local_reply: bool
|
||||||
|
|
||||||
|
# Is the object mentioning the local actor
|
||||||
|
is_mention: bool
|
||||||
|
|
||||||
|
# Is it from someone the local actor is following
|
||||||
|
is_from_following: bool
|
||||||
|
|
||||||
|
# List of hashtags, e.g. #microblogpub
|
||||||
|
hashtags: list[str]
|
||||||
|
|
||||||
|
# @dev@microblog.pub
|
||||||
|
actor_handle: str
|
||||||
|
|
||||||
|
remote_object: "RemoteObject"
|
||||||
|
|
||||||
|
|
||||||
|
_StreamVisibilityCallback = Callable[[ObjectInfo], bool]
|
||||||
|
|
||||||
|
|
||||||
|
def default_stream_visibility_callback(object_info: ObjectInfo) -> bool:
|
||||||
|
logger.info(f"{object_info=}")
|
||||||
|
return (
|
||||||
|
(not object_info.is_reply and object_info.is_from_following)
|
||||||
|
or object_info.is_mention
|
||||||
|
or object_info.is_local_reply
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue