kopia lustrzana https://github.com/snarfed/bridgy-fed
rodzic
817ef1d5d6
commit
133d640f1d
|
@ -54,6 +54,8 @@ _INSTANCE_ACTOR = None
|
||||||
# populated in User.status
|
# populated in User.status
|
||||||
WEB_OPT_OUT_DOMAINS = None
|
WEB_OPT_OUT_DOMAINS = None
|
||||||
|
|
||||||
|
FEDI_URL_RE = re.compile(r'https://[^/]+/(@|users/)([^/@]+)(@[^/@]+)?(/(?:statuses/)?[0-9]+)?')
|
||||||
|
|
||||||
|
|
||||||
def instance_actor():
|
def instance_actor():
|
||||||
global _INSTANCE_ACTOR
|
global _INSTANCE_ACTOR
|
||||||
|
|
30
atproto.py
30
atproto.py
|
@ -47,6 +47,14 @@ appview = Client(f'https://{os.environ["APPVIEW_HOST"]}',
|
||||||
headers={'User-Agent': USER_AGENT})
|
headers={'User-Agent': USER_AGENT})
|
||||||
LEXICONS = appview.defs
|
LEXICONS = appview.defs
|
||||||
|
|
||||||
|
# https://atproto.com/guides/applications#record-types
|
||||||
|
COLLECTION_TO_TYPE = {
|
||||||
|
'app.bsky.actor.profile': 'profile',
|
||||||
|
'app.bsky.feed.like': 'like',
|
||||||
|
'app.bsky.feed.post': 'post',
|
||||||
|
'app.bsky.feed.repost': 'repost',
|
||||||
|
'app.bsky.graph.follow': 'follow',
|
||||||
|
}
|
||||||
|
|
||||||
DNS_GCP_PROJECT = 'brid-gy'
|
DNS_GCP_PROJECT = 'brid-gy'
|
||||||
DNS_ZONE = 'brid-gy'
|
DNS_ZONE = 'brid-gy'
|
||||||
|
@ -55,6 +63,22 @@ logger.info(f'Using GCP DNS project {DNS_GCP_PROJECT} zone {DNS_ZONE}')
|
||||||
dns_client = dns.Client(project=DNS_GCP_PROJECT)
|
dns_client = dns.Client(project=DNS_GCP_PROJECT)
|
||||||
|
|
||||||
|
|
||||||
|
def did_to_handle(did):
|
||||||
|
"""Resolves a DID to a handle _if_ we have the DID doc stored locally.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
did (str)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: handle, or None
|
||||||
|
"""
|
||||||
|
if did_obj := ATProto.load(did, did_doc=True):
|
||||||
|
if aka := util.get_first(did_obj.raw, 'alsoKnownAs', ''):
|
||||||
|
handle, _, _ = parse_at_uri(aka)
|
||||||
|
if handle:
|
||||||
|
return handle
|
||||||
|
|
||||||
|
|
||||||
class ATProto(User, Protocol):
|
class ATProto(User, Protocol):
|
||||||
"""AT Protocol class.
|
"""AT Protocol class.
|
||||||
|
|
||||||
|
@ -86,11 +110,7 @@ class ATProto(User, Protocol):
|
||||||
@ndb.ComputedProperty
|
@ndb.ComputedProperty
|
||||||
def handle(self):
|
def handle(self):
|
||||||
"""Returns handle if the DID document includes one, otherwise None."""
|
"""Returns handle if the DID document includes one, otherwise None."""
|
||||||
if did_obj := ATProto.load(self.key.id(), did_doc=True):
|
return did_to_handle(self.key.id())
|
||||||
if aka := util.get_first(did_obj.raw, 'alsoKnownAs', ''):
|
|
||||||
handle, _, _ = parse_at_uri(aka)
|
|
||||||
if handle:
|
|
||||||
return handle
|
|
||||||
|
|
||||||
def web_url(self):
|
def web_url(self):
|
||||||
return bluesky.Bluesky.user_url(self.handle_or_id())
|
return bluesky.Bluesky.user_url(self.handle_or_id())
|
||||||
|
|
37
models.py
37
models.py
|
@ -15,7 +15,7 @@ from Crypto.PublicKey import RSA
|
||||||
from flask import g, request
|
from flask import g, request
|
||||||
from google.cloud import ndb
|
from google.cloud import ndb
|
||||||
from granary import as1, as2, atom, bluesky, microformats2
|
from granary import as1, as2, atom, bluesky, microformats2
|
||||||
from granary.bluesky import BSKY_APP_URL_RE
|
from granary.bluesky import AT_URI_PATTERN, BSKY_APP_URL_RE
|
||||||
from granary.source import html_to_text
|
from granary.source import html_to_text
|
||||||
from oauth_dropins.webutil import util
|
from oauth_dropins.webutil import util
|
||||||
from oauth_dropins.webutil.appengine_info import DEBUG
|
from oauth_dropins.webutil.appengine_info import DEBUG
|
||||||
|
@ -1272,23 +1272,32 @@ def fetch_objects(query, by=None, user=None):
|
||||||
'url': id,
|
'url': id,
|
||||||
})
|
})
|
||||||
elif url:
|
elif url:
|
||||||
# heuristics for sniffing Mastodon and similar fediverse URLs and
|
# heuristics for sniffing URLs and converting them to more friendly
|
||||||
# converting them to more friendly @-names
|
# phrases and user handles.
|
||||||
# TODO: standardize this into granary.as2 somewhere?
|
# TODO: standardize this into granary.as2 somewhere?
|
||||||
if not content:
|
if not content:
|
||||||
fedi_url = re.match(
|
from activitypub import FEDI_URL_RE
|
||||||
r'https://[^/]+/(@|users/)([^/@]+)(@[^/@]+)?(/(?:statuses/)?[0-9]+)?', url)
|
from atproto import COLLECTION_TO_TYPE, did_to_handle
|
||||||
if fedi_url:
|
|
||||||
content = '@' + fedi_url.group(2)
|
|
||||||
if fedi_url.group(4):
|
|
||||||
content += "'s post"
|
|
||||||
|
|
||||||
if not content:
|
if match := FEDI_URL_RE.match(url):
|
||||||
if bsky_url := BSKY_APP_URL_RE.match(url):
|
content = '@' + match.group(2)
|
||||||
if handle := bsky_url.group('id'): # or DID
|
if match.group(4):
|
||||||
content = '@' + handle
|
|
||||||
if bsky_url.group('tid'):
|
|
||||||
content += "'s post"
|
content += "'s post"
|
||||||
|
elif match := BSKY_APP_URL_RE.match(url):
|
||||||
|
id = match.group('id')
|
||||||
|
if id.startswith('did:'):
|
||||||
|
id = ATdid_to_handle(id) or id
|
||||||
|
content = '@' + id
|
||||||
|
if match.group('tid'):
|
||||||
|
content += "'s post"
|
||||||
|
elif match := AT_URI_PATTERN.match(url):
|
||||||
|
id = match.group('repo')
|
||||||
|
if id.startswith('did:'):
|
||||||
|
id = did_to_handle(id) or id
|
||||||
|
content = '@' + id
|
||||||
|
if coll := match.group('collection'):
|
||||||
|
content += f"'s {COLLECTION_TO_TYPE.get(coll) or 'post'}"
|
||||||
|
url = bluesky.at_uri_to_web_url(url)
|
||||||
|
|
||||||
content = common.pretty_link(url, text=content, user=user)
|
content = common.pretty_link(url, text=content, user=user)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue