Allow to replace URL dynamically (for Nitter, Teddit...)

main
Thomas Sileo 2022-08-04 07:31:18 +02:00
parent 4de4178c3d
commit 8cfac8df6a
3 changed files with 48 additions and 2 deletions

View File

@ -2,6 +2,7 @@ import hashlib
from datetime import datetime from datetime import datetime
from functools import cached_property from functools import cached_property
from typing import Any from typing import Any
from urllib.parse import urlparse
import pydantic import pydantic
from bs4 import BeautifulSoup # type: ignore from bs4 import BeautifulSoup # type: ignore
@ -11,6 +12,7 @@ from app import activitypub as ap
from app.actor import LOCAL_ACTOR from app.actor import LOCAL_ACTOR
from app.actor import Actor from app.actor import Actor
from app.actor import RemoteActor from app.actor import RemoteActor
from app.config import PRIVACY_REPLACE
from app.media import proxied_media_url from app.media import proxied_media_url
from app.utils.datetime import now from app.utils.datetime import now
from app.utils.datetime import parse_isoformat from app.utils.datetime import parse_isoformat
@ -175,10 +177,23 @@ class Object:
# PeerTube returns the content as markdown # PeerTube returns the content as markdown
if self.ap_object.get("mediaType") == "text/markdown": if self.ap_object.get("mediaType") == "text/markdown":
return markdown(content, extensions=["mdx_linkify"]) content = markdown(content, extensions=["mdx_linkify"])
if not PRIVACY_REPLACE:
return content return content
soup = BeautifulSoup(content, "html5lib")
links = soup.find_all("a", href=True)
for link in links:
parsed_href = urlparse(link.attrs["href"])
if new_netloc := PRIVACY_REPLACE.get(
parsed_href.netloc.removeprefix("www.")
):
link.attrs["href"] = parsed_href._replace(netloc=new_netloc).geturl()
return soup.find("body").decode_contents()
@property @property
def summary(self) -> str | None: def summary(self) -> str | None:
return self.ap_object.get("summary") return self.ap_object.get("summary")

View File

@ -31,6 +31,11 @@ USER_AGENT = f"microblogpub/{VERSION}"
AP_CONTENT_TYPE = "application/activity+json" AP_CONTENT_TYPE = "application/activity+json"
class _PrivacyReplace(pydantic.BaseModel):
domain: str
replace_by: str
class Config(pydantic.BaseModel): class Config(pydantic.BaseModel):
domain: str domain: str
username: str username: str
@ -43,6 +48,7 @@ class Config(pydantic.BaseModel):
debug: bool = False debug: bool = False
trusted_hosts: list[str] = ["127.0.0.1"] trusted_hosts: list[str] = ["127.0.0.1"]
manually_approves_followers: bool = False manually_approves_followers: bool = False
privacy_replace: list[_PrivacyReplace] | None = None
# Config items to make tests easier # Config items to make tests easier
sqlalchemy_database: str | None = None sqlalchemy_database: str | None = None
@ -84,6 +90,9 @@ _SCHEME = "https" if CONFIG.https else "http"
ID = f"{_SCHEME}://{DOMAIN}" ID = f"{_SCHEME}://{DOMAIN}"
USERNAME = CONFIG.username USERNAME = CONFIG.username
MANUALLY_APPROVES_FOLLOWERS = CONFIG.manually_approves_followers MANUALLY_APPROVES_FOLLOWERS = CONFIG.manually_approves_followers
PRIVACY_REPLACE = None
if CONFIG.privacy_replace:
PRIVACY_REPLACE = {pr.domain: pr.replace_by for pr in CONFIG.privacy_replace}
BASE_URL = ID BASE_URL = ID
DEBUG = CONFIG.debug DEBUG = CONFIG.debug
DB_PATH = CONFIG.sqlalchemy_database or ROOT_DIR / "data" / "microblogpub.db" DB_PATH = CONFIG.sqlalchemy_database or ROOT_DIR / "data" / "microblogpub.db"

View File

@ -31,6 +31,28 @@ You can tweak your profile by tweaking these items:
Whenever one of these config items is updated, an `Update` activity will be sent to all know server to update your remote profile. Whenever one of these config items is updated, an `Update` activity will be sent to all know server to update your remote profile.
### Privacy replace
You can define domain to be rewrited to more "privacy friendly" alternatives, like [Invidious](https://invidious.io/)
or [Nitter](https://nitter.net/about).
To do so, just add as these extra config items, this is a sample config that rewrite URLs for Twitter, Youtube, Reddit and Medium:
```toml
[[privacy_replace]]
domain = "youtube.com"
replace_by ="yewtu.be"
[[privacy_replace]]
domain = "twitter.com"
replace_by = "nitter.net"
[[privacy_replace]]
domain = "medium.com"
replace_by = "scribe.rip"
[[privacy_replace]]
domain = "reddit.com"
replace_by = "teddit.net"
```
### Customization ### Customization
#### Custom emoji #### Custom emoji