diff --git a/acceptreject.py b/acceptreject.py index 995b3e32c..d4d0e22ec 100644 --- a/acceptreject.py +++ b/acceptreject.py @@ -18,6 +18,7 @@ from utils import followPerson from utils import hasObjectDict from utils import acctDir from utils import hasGroupType +from utils import localActorUrl def _createAcceptReject(baseDir: str, federationList: [], @@ -41,7 +42,7 @@ def _createAcceptReject(baseDir: str, federationList: [], newAccept = { "@context": "https://www.w3.org/ns/activitystreams", 'type': acceptType, - 'actor': httpPrefix + '://' + domain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, domain), 'to': [toUrl], 'cc': [], 'object': objectJson diff --git a/announce.py b/announce.py index c108fcd7b..8fc49bf8d 100644 --- a/announce.py +++ b/announce.py @@ -22,6 +22,7 @@ from utils import locatePost from utils import saveJson from utils import undoAnnounceCollectionEntry from utils import updateAnnounceCollection +from utils import localActorUrl from posts import sendSignedJson from posts import getPersonBox from session import postJson @@ -136,11 +137,11 @@ def createAnnounce(session, baseDir: str, federationList: [], statusNumber, published = getStatusNumber() newAnnounceId = httpPrefix + '://' + fullDomain + \ '/users/' + nickname + '/statuses/' + statusNumber - atomUriStr = httpPrefix + '://' + fullDomain + '/users/' + nickname + \ + atomUriStr = localActorUrl(httpPrefix, nickname, fullDomain) + \ '/statuses/' + statusNumber newAnnounce = { "@context": "https://www.w3.org/ns/activitystreams", - 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, fullDomain), 'atomUri': atomUriStr, 'cc': [], 'id': newAnnounceId + '/activity', @@ -193,8 +194,7 @@ def announcePublic(session, baseDir: str, federationList: [], fromDomain = getFullDomain(domain, port) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomain + '/users/' + nickname + \ - '/followers' + ccUrl = localActorUrl(httpPrefix, nickname, fromDomain) + '/followers' return createAnnounce(session, baseDir, federationList, nickname, domain, port, toUrl, ccUrl, httpPrefix, @@ -219,13 +219,11 @@ def sendAnnounceViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + \ - '/followers' + actorStr = localActorUrl(httpPrefix, fromNickname, fromDomainFull) + ccUrl = actorStr + '/followers' statusNumber, published = getStatusNumber() - newAnnounceId = httpPrefix + '://' + fromDomainFull + '/users/' + \ - fromNickname + '/statuses/' + statusNumber - actorStr = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + newAnnounceId = actorStr + '/statuses/' + statusNumber newAnnounceJson = { "@context": "https://www.w3.org/ns/activitystreams", 'actor': actorStr, @@ -308,7 +306,7 @@ def sendUndoAnnounceViaServer(baseDir: str, session, domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) handle = actor.replace('/users/', '/@') statusNumber, published = getStatusNumber() diff --git a/availability.py b/availability.py index a0ab3622a..35ba9164e 100644 --- a/availability.py +++ b/availability.py @@ -18,6 +18,7 @@ from utils import getDomainFromActor from utils import loadJson from utils import saveJson from utils import acctDir +from utils import localActorUrl def setAvailability(baseDir: str, nickname: str, domain: str, @@ -90,13 +91,12 @@ def sendAvailabilityViaServer(baseDir: str, session, domainFull = getFullDomain(domain, port) - toUrl = httpPrefix + '://' + domainFull + '/users/' + nickname - ccUrl = httpPrefix + '://' + domainFull + '/users/' + nickname + \ - '/followers' + toUrl = localActorUrl(httpPrefix, nickname, domainFull) + ccUrl = toUrl + '/followers' newAvailabilityJson = { 'type': 'Availability', - 'actor': httpPrefix + '://' + domainFull + '/users/' + nickname, + 'actor': toUrl, 'object': '"' + status + '"', 'to': [toUrl], 'cc': [ccUrl] diff --git a/blocking.py b/blocking.py index 4f6a5388a..406b79717 100644 --- a/blocking.py +++ b/blocking.py @@ -28,6 +28,7 @@ from utils import evilIncarnate from utils import getDomainFromActor from utils import getNicknameFromActor from utils import acctDir +from utils import localActorUrl from conversation import muteConversation from conversation import unmuteConversation @@ -469,7 +470,7 @@ def mutePost(baseDir: str, nickname: str, domain: str, port: int, if hasObjectDict(postJsonObject): domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) if postJsonObject['object'].get('conversation'): muteConversation(baseDir, nickname, domain, @@ -559,7 +560,7 @@ def unmutePost(baseDir: str, nickname: str, domain: str, port: int, if postJsonObject['object'].get('ignores'): domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) totalItems = 0 if postJsonObject['object']['ignores'].get('totalItems'): totalItems = \ diff --git a/blog.py b/blog.py index 12d753906..58ac947ca 100644 --- a/blog.py +++ b/blog.py @@ -17,6 +17,7 @@ from webapp_utils import htmlFooter from webapp_utils import getPostAttachmentsAsHtml from webapp_utils import editTextArea from webapp_media import addEmbeddedElements +from utils import localActorUrl from utils import getActorLanguagesList from utils import getBaseContentFromPost from utils import getContentFromPost @@ -242,8 +243,7 @@ def _htmlBlogPostContent(authorized: bool, if attachmentStr: blogStr += '
' + attachmentStr + '
' - personUrl = \ - httpPrefix + '://' + domainFull + '/users/' + nickname + personUrl = localActorUrl(httpPrefix, nickname, domainFull) actorJson = \ getPersonFromCache(baseDir, personUrl, personCache, False) languagesUnderstood = [] @@ -288,8 +288,8 @@ def _htmlBlogPostContent(authorized: bool, if not linkedAuthor: blogStr += '

' + translate['About the author'] + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ + '">' + translate['About the author'] + \ '

\n' replies = _noOfBlogReplies(baseDir, httpPrefix, translate, @@ -902,8 +902,8 @@ def pathContainsBlogLink(baseDir: str, return None, None if '#' + userEnding2[1] + '.' not in open(blogIndexFilename).read(): return None, None - messageId = httpPrefix + '://' + domainFull + \ - '/users/' + nickname + '/statuses/' + userEnding2[1] + messageId = localActorUrl(httpPrefix, nickname, domainFull) + \ + '/statuses/' + userEnding2[1] return locatePost(baseDir, nickname, domain, messageId), nickname diff --git a/bookmarks.py b/bookmarks.py index d8691d4b4..921c057e4 100644 --- a/bookmarks.py +++ b/bookmarks.py @@ -25,6 +25,7 @@ from utils import loadJson from utils import saveJson from utils import hasObjectDict from utils import acctDir +from utils import localActorUrl from posts import getPersonBox from session import postJson @@ -242,7 +243,7 @@ def bookmark(recentPostsCache: {}, newBookmarkJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Bookmark', - 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, fullDomain), 'object': objectUrl } if ccList: @@ -301,10 +302,10 @@ def undoBookmark(recentPostsCache: {}, newUndoBookmarkJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Undo', - 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, fullDomain), 'object': { 'type': 'Bookmark', - 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, fullDomain), 'object': objectUrl } } @@ -356,7 +357,7 @@ def sendBookmarkViaServer(baseDir: str, session, domainFull = getFullDomain(domain, fromPort) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) newBookmarkJson = { "@context": "https://www.w3.org/ns/activitystreams", @@ -441,7 +442,7 @@ def sendUndoBookmarkViaServer(baseDir: str, session, domainFull = getFullDomain(domain, fromPort) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) newBookmarkJson = { "@context": "https://www.w3.org/ns/activitystreams", diff --git a/daemon.py b/daemon.py index c377a4a84..654f9ffa3 100644 --- a/daemon.py +++ b/daemon.py @@ -225,6 +225,7 @@ from shares import sharesCatalogCSVEndpoint from categories import setHashtagCategory from languages import getActorLanguages from languages import setActorLanguages +from utils import localActorUrl from utils import isfloat from utils import validPassword from utils import removeLineEndings @@ -2586,8 +2587,7 @@ class PubServer(BaseHTTPRequestHandler): print(followerNickname + ' stops following ' + followingActor) followActor = \ - httpPrefix + '://' + domainFull + \ - '/users/' + followerNickname + localActorUrl(httpPrefix, followerNickname, domainFull) statusNumber, published = getStatusNumber() followId = followActor + '/statuses/' + str(statusNumber) unfollowJson = { @@ -3091,10 +3091,11 @@ class PubServer(BaseHTTPRequestHandler): searchNickname = getNicknameFromActor(searchStr) searchDomain, searchPort = \ getDomainFromActor(searchStr) + searchDomainFull = \ + getFullDomain(searchDomain, searchPort) actor = \ - httpPrefix + '://' + \ - getFullDomain(searchDomain, searchPort) + \ - '/users/' + searchNickname + localActorUrl(httpPrefix, searchNickname, + searchDomainFull) else: actor = searchStr avatarUrl = \ @@ -6660,8 +6661,8 @@ class PubServer(BaseHTTPRequestHandler): return self.server.actorRepeat = path.split('?actor=')[1] announceToStr = \ - httpPrefix + '://' + domainFull + '/users/' + \ - self.postToNickname + '/followers' + localActorUrl(httpPrefix, self.postToNickname, domainFull) + \ + '/followers' if not repeatPrivate: announceToStr = 'https://www.w3.org/ns/activitystreams#Public' announceJson = \ @@ -7066,8 +7067,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.GETbusy = False return likeActor = \ - httpPrefix + '://' + \ - domainFull + '/users/' + self.postToNickname + localActorUrl(httpPrefix, self.postToNickname, domainFull) actorLiked = path.split('?actor=')[1] if '?' in actorLiked: actorLiked = actorLiked.split('?')[0] @@ -7165,7 +7165,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.GETbusy = False return undoActor = \ - httpPrefix + '://' + domainFull + '/users/' + self.postToNickname + localActorUrl(httpPrefix, self.postToNickname, domainFull) actorLiked = path.split('?actor=')[1] if '?' in actorLiked: actorLiked = actorLiked.split('?')[0] @@ -7263,7 +7263,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.GETbusy = False return bookmarkActor = \ - httpPrefix + '://' + domainFull + '/users/' + self.postToNickname + localActorUrl(httpPrefix, self.postToNickname, domainFull) ccList = [] bookmark(self.server.recentPostsCache, self.server.session, @@ -7349,7 +7349,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.GETbusy = False return undoActor = \ - httpPrefix + '://' + domainFull + '/users/' + self.postToNickname + localActorUrl(httpPrefix, self.postToNickname, domainFull) ccList = [] undoBookmark(self.server.recentPostsCache, self.server.session, @@ -7616,15 +7616,15 @@ class PubServer(BaseHTTPRequestHandler): 'https://www.w3.org/ns/activitystreams' firstStr = \ - httpPrefix + '://' + domainFull + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ '/statuses/' + statusNumber + '/replies?page=true' idStr = \ - httpPrefix + '://' + domainFull + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ '/statuses/' + statusNumber + '/replies' lastStr = \ - httpPrefix + '://' + domainFull + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ '/statuses/' + statusNumber + '/replies?page=true' repliesJson = { @@ -7701,13 +7701,12 @@ class PubServer(BaseHTTPRequestHandler): contextStr = 'https://www.w3.org/ns/activitystreams' idStr = \ - httpPrefix + '://' + domainFull + \ - '/users/' + nickname + '/statuses/' + \ - statusNumber + '?page=true' + localActorUrl(httpPrefix, nickname, domainFull) + \ + '/statuses/' + statusNumber + '?page=true' partOfStr = \ - httpPrefix + '://' + domainFull + \ - '/users/' + nickname + '/statuses/' + statusNumber + localActorUrl(httpPrefix, nickname, domainFull) + \ + '/statuses/' + statusNumber repliesJson = { '@context': contextStr, @@ -10879,8 +10878,8 @@ class PubServer(BaseHTTPRequestHandler): postId = path.split('/editnewspost=')[1] if '?' in postId: postId = postId.split('?')[0] - postUrl = httpPrefix + '://' + domainFull + \ - '/users/' + postActor + '/statuses/' + postId + postUrl = localActorUrl(httpPrefix, postActor, domainFull) + \ + '/statuses/' + postId path = path.split('/editnewspost=')[0] msg = htmlEditNewsPost(self.server.cssCache, translate, baseDir, @@ -10930,8 +10929,7 @@ class PubServer(BaseHTTPRequestHandler): # don't block self return False blockActor = \ - httpPrefix + '://' + blockerDomainFull + '/users/' + \ - blockerNickname + localActorUrl(httpPrefix, blockerNickname, blockerDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' ccUrl = blockActor + '/followers' @@ -13090,8 +13088,8 @@ class PubServer(BaseHTTPRequestHandler): nickname = getNicknameFromActor(self.path.split('?')[0]) if nickname == actor: postUrl = \ - self.server.httpPrefix + '://' + \ - self.server.domainFull + '/users/' + nickname + \ + localActorUrl(self.server.httpPrefix, nickname, + self.server.domainFull) + \ '/statuses/' + messageId msg = htmlEditBlog(self.server.mediaInstance, self.server.translate, @@ -15243,23 +15241,25 @@ class PubServer(BaseHTTPRequestHandler): if callingDomain.endswith('.onion') and \ self.server.onionDomain: actorPathStr = \ - 'http://' + self.server.onionDomain + \ - '/users/' + nickname + '/' + postRedirect + \ + localActorUrl('http', nickname, + self.server.onionDomain) + \ + '/' + postRedirect + \ '?page=' + str(pageNumber) self._redirect_headers(actorPathStr, cookie, callingDomain) elif (callingDomain.endswith('.i2p') and self.server.i2pDomain): actorPathStr = \ - 'http://' + self.server.i2pDomain + \ - '/users/' + nickname + '/' + postRedirect + \ + localActorUrl('http', nickname, + self.server.i2pDomain) + \ + '/' + postRedirect + \ '?page=' + str(pageNumber) self._redirect_headers(actorPathStr, cookie, callingDomain) else: actorPathStr = \ - self.server.httpPrefix + '://' + \ - self.server.domainFull + '/users/' + nickname + \ + localActorUrl(self.server.httpPrefix, nickname, + self.server.domainFull) + \ '/' + postRedirect + '?page=' + str(pageNumber) self._redirect_headers(actorPathStr, cookie, callingDomain) diff --git a/delete.py b/delete.py index d06031e56..ef042d8a3 100644 --- a/delete.py +++ b/delete.py @@ -18,6 +18,7 @@ from utils import getDomainFromActor from utils import locatePost from utils import deletePost from utils import removeModerationPostFromIndex +from utils import localActorUrl from session import postJson from webfinger import webfingerHandle from auth import createBasicAuthHeader @@ -38,8 +39,7 @@ def sendDeleteViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) - actor = httpPrefix + '://' + fromDomainFull + \ - '/users/' + fromNickname + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' ccUrl = actor + '/followers' diff --git a/desktop_client.py b/desktop_client.py index c85407273..353a682c1 100644 --- a/desktop_client.py +++ b/desktop_client.py @@ -25,6 +25,7 @@ from utils import removeHtml from utils import getNicknameFromActor from utils import getDomainFromActor from utils import isPGPEncrypted +from utils import localActorUrl from session import createSession from speaker import speakableText from speaker import getSpeakerPitch @@ -1374,7 +1375,7 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, systemLanguage, espeak) domainFull = getFullDomain(domain, port) - yourActor = httpPrefix + '://' + domainFull + '/users/' + nickname + yourActor = localActorUrl(httpPrefix, nickname, domainFull) actorJson = None notifyJson = { @@ -1949,8 +1950,8 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, blockDomain = blockHandle.split('@')[1] blockNickname = blockHandle.split('@')[0] blockActor = \ - httpPrefix + '://' + blockDomain + \ - '/users/' + blockNickname + localActorUrl(httpPrefix, + blockNickname, blockDomain) if currIndex > 0 and boxJson and not blockActor: postJsonObject = \ _desktopGetBoxPostObject(boxJson, currIndex) diff --git a/devices.py b/devices.py index b2fb09707..8b56e5d37 100644 --- a/devices.py +++ b/devices.py @@ -34,6 +34,7 @@ import os from utils import loadJson from utils import saveJson from utils import acctDir +from utils import localActorUrl def E2EEremoveDevice(baseDir: str, nickname: str, domain: str, @@ -142,7 +143,7 @@ def E2EEdevicesCollection(baseDir: str, nickname: str, domain: str, personDir = acctDir(baseDir, nickname, domain) if not os.path.isdir(personDir): return {} - personId = httpPrefix + '://' + domainFull + '/users/' + nickname + personId = localActorUrl(httpPrefix, nickname, domainFull) if not os.path.isdir(personDir + '/devices'): os.mkdir(personDir + '/devices') deviceList = [] diff --git a/epicyon.py b/epicyon.py index 93d88456b..6748ee1b4 100644 --- a/epicyon.py +++ b/epicyon.py @@ -1166,7 +1166,6 @@ if args.message: toDomain = 'public' toPort = port - # ccUrl = httpPrefix + '://' + domain + '/users/' + nickname + '/followers' ccUrl = None sendMessage = args.message followersOnly = args.followersonly diff --git a/follow.py b/follow.py index f7be6c2b3..2295553bb 100644 --- a/follow.py +++ b/follow.py @@ -30,6 +30,7 @@ from utils import getUserPaths from utils import acctDir from utils import hasGroupType from utils import isGroupAccount +from utils import localActorUrl from acceptreject import createAccept from acceptreject import createReject from webfinger import webfingerHandle @@ -67,8 +68,7 @@ def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None: domain = handle.split('@')[1] if nickname.startswith('!'): nickname = nickname[1:] - actor = \ - httpPrefix + '://' + domain + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domain) lastSeenFilename = \ lastSeenDir + '/' + actor.replace('/', '#') + '.txt' if not os.path.isfile(lastSeenFilename): @@ -399,11 +399,10 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, if headerOnly: firstStr = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + followFile + '?page=1' + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + followFile + '?page=1' idStr = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + followFile + localActorUrl(httpPrefix, nickname, domain) + '/' + followFile totalStr = \ _getNoOfFollows(baseDir, nickname, domain, authorized) following = { @@ -420,10 +419,10 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, nextPageNumber = int(pageNumber + 1) idStr = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + followFile + '?page=' + str(pageNumber) + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + followFile + '?page=' + str(pageNumber) partOfStr = \ - httpPrefix + '://' + domain + '/users/' + nickname + '/' + followFile + localActorUrl(httpPrefix, nickname, domain) + '/' + followFile following = { '@context': 'https://www.w3.org/ns/activitystreams', 'id': idStr, @@ -457,7 +456,7 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, dom = line2.split('@')[1] if not nick.startswith('!'): # person actor - url = httpPrefix + '://' + dom + '/users/' + nick + url = localActorUrl(httpPrefix, nick, dom) else: # group actor url = httpPrefix + '://' + dom + '/c/' + nick @@ -481,8 +480,8 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, lastPage = 1 if nextPageNumber > lastPage: following['next'] = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + followFile + '?page=' + str(lastPage) + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + followFile + '?page=' + str(lastPage) return following @@ -969,7 +968,7 @@ def sendFollowRequest(session, baseDir: str, return None fullDomain = getFullDomain(domain, port) - followActor = httpPrefix + '://' + fullDomain + '/users/' + nickname + followActor = localActorUrl(httpPrefix, nickname, fullDomain) requestDomain = getFullDomain(followDomain, followPort) @@ -1040,10 +1039,8 @@ def sendFollowRequestViaServer(baseDir: str, session, followDomainFull = getFullDomain(followDomain, followPort) - followActor = httpPrefix + '://' + \ - fromDomainFull + '/users/' + fromNickname - followedId = httpPrefix + '://' + \ - followDomainFull + '/users/' + followNickname + followActor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) + followedId = localActorUrl(httpPrefix, followNickname, followDomainFull) statusNumber, published = getStatusNumber() newFollowJson = { @@ -1126,10 +1123,8 @@ def sendUnfollowRequestViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) followDomainFull = getFullDomain(followDomain, followPort) - followActor = httpPrefix + '://' + \ - fromDomainFull + '/users/' + fromNickname - followedId = httpPrefix + '://' + \ - followDomainFull + '/users/' + followNickname + followActor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) + followedId = localActorUrl(httpPrefix, followNickname, followDomainFull) statusNumber, published = getStatusNumber() unfollowJson = { @@ -1216,7 +1211,7 @@ def getFollowingViaServer(baseDir: str, session, return 6 domainFull = getFullDomain(domain, port) - followActor = httpPrefix + '://' + domainFull + '/users/' + nickname + followActor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) @@ -1257,7 +1252,7 @@ def getFollowersViaServer(baseDir: str, session, return 6 domainFull = getFullDomain(domain, port) - followActor = httpPrefix + '://' + domainFull + '/users/' + nickname + followActor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) @@ -1298,7 +1293,7 @@ def getFollowRequestsViaServer(baseDir: str, session, domainFull = getFullDomain(domain, port) - followActor = httpPrefix + '://' + domainFull + '/users/' + nickname + followActor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) headers = { @@ -1339,7 +1334,7 @@ def approveFollowRequestViaServer(baseDir: str, session, return 6 domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) @@ -1379,7 +1374,7 @@ def denyFollowRequestViaServer(baseDir: str, session, return 6 domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) diff --git a/httpsig.py b/httpsig.py index 45372fc90..50d897e3c 100644 --- a/httpsig.py +++ b/httpsig.py @@ -24,6 +24,7 @@ from time import gmtime, strftime import datetime from utils import getFullDomain from utils import getSHA256 +from utils import localActorUrl def messageContentDigest(messageBodyJsonStr: str) -> str: @@ -48,7 +49,7 @@ def signPostHeaders(dateStr: str, privateKeyPem: str, if not dateStr: dateStr = strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime()) - keyID = httpPrefix + '://' + domain + '/users/' + nickname + '#main-key' + keyID = localActorUrl(httpPrefix, nickname, domain) + '#main-key' if not messageBodyJsonStr: headers = { '(request-target)': f'post {path}', @@ -125,7 +126,7 @@ def signPostHeadersNew(dateStr: str, privateKeyPem: str, currTime = datetime.datetime.strptime(dateStr, timeFormat) secondsSinceEpoch = \ int((currTime - datetime.datetime(1970, 1, 1)).total_seconds()) - keyID = httpPrefix + '://' + domain + '/users/' + nickname + '#main-key' + keyID = localActorUrl(httpPrefix, nickname, domain) + '#main-key' if not messageBodyJsonStr: headers = { '*request-target': f'post {path}', diff --git a/inbox.py b/inbox.py index 1c7878f64..4b1ffeb77 100644 --- a/inbox.py +++ b/inbox.py @@ -46,6 +46,7 @@ from utils import saveJson from utils import updateLikesCollection from utils import undoLikesCollectionEntry from utils import hasGroupType +from utils import localActorUrl from categories import getHashtagCategories from categories import setHashtagCategory from httpsig import verifyPostHeaders @@ -401,8 +402,8 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str, if actor: postId = actor + '/statuses/' + statusNumber else: - postId = httpPrefix + '://' + originalDomain + \ - '/users/' + nickname + '/statuses/' + statusNumber + postId = localActorUrl(httpPrefix, nickname, originalDomain) + \ + '/statuses/' + statusNumber # NOTE: don't change postJsonObject['id'] before signature check @@ -1912,7 +1913,7 @@ def _sendToGroupMembers(session, baseDir: str, handle: str, port: int, nickname = handle.split('@')[0].replace('!', '') domain = handle.split('@')[1] domainFull = getFullDomain(domain, port) - groupActor = httpPrefix + '://' + domainFull + '/users/' + nickname + groupActor = localActorUrl(httpPrefix, nickname, domainFull) if groupActor not in postJsonObject['to']: return cc = '' @@ -2148,8 +2149,8 @@ def _isValidDM(baseDir: str, nickname: str, domain: str, port: int, if not os.path.isfile(followDMsFilename): # dm index will be updated updateIndexList.append('dm') - _dmNotify(baseDir, handle, - httpPrefix + '://' + domain + '/users/' + nickname + '/dm') + actUrl = localActorUrl(httpPrefix, nickname, domain) + _dmNotify(baseDir, handle, actUrl + '/dm') return True # get the file containing following handles @@ -2216,8 +2217,8 @@ def _isValidDM(baseDir: str, nickname: str, domain: str, port: int, # dm index will be updated updateIndexList.append('dm') - _dmNotify(baseDir, handle, - httpPrefix + '://' + domain + '/users/' + nickname + '/dm') + actUrl = localActorUrl(httpPrefix, nickname, domain) + _dmNotify(baseDir, handle, actUrl + '/dm') return True @@ -2465,7 +2466,7 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int, return False # get the actor being replied to - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) # create a reply notification file if needed if not postIsDM and isReply(postJsonObject, actor): @@ -2484,10 +2485,11 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int, if isinstance(inReplyTo, str): if not isMuted(baseDir, nickname, domain, inReplyTo, conversationId): + actUrl = \ + localActorUrl(httpPrefix, + nickname, domain) _replyNotify(baseDir, handle, - httpPrefix + '://' + domain + - '/users/' + nickname + - '/tlreplies') + actUrl + '/tlreplies') else: isReplyToMutedPost = True @@ -2523,10 +2525,10 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int, if notifyWhenPersonPosts(baseDir, nickname, domain, fromNickname, fromDomainFull): postId = removeIdEnding(jsonObj['id']) + domFull = getFullDomain(domain, port) postLink = \ - httpPrefix + '://' + \ - getFullDomain(domain, port) + \ - '/users/' + nickname + \ + localActorUrl(httpPrefix, + nickname, domFull) + \ '?notifypost=' + postId.replace('/', '-') _notifyPostArrival(baseDir, handle, postLink) diff --git a/languages.py b/languages.py index eab773b18..9d0d4022b 100644 --- a/languages.py +++ b/languages.py @@ -14,6 +14,7 @@ from utils import getActorLanguagesList from utils import removeHtml from utils import hasObjectDict from utils import getConfigParam +from utils import localActorUrl from cache import getPersonFromCache @@ -104,7 +105,7 @@ def understoodPostLanguage(baseDir: str, nickname: str, domain: str, return True if msgObject['contentMap'].get(systemLanguage): return True - personUrl = httpPrefix + '://' + domainFull + '/users/' + nickname + personUrl = localActorUrl(httpPrefix, nickname, domainFull) actorJson = getPersonFromCache(baseDir, personUrl, personCache, False) if not actorJson: print('WARN: unable to load actor to check languages ' + personUrl) diff --git a/like.py b/like.py index ee3a81be0..1eddf571d 100644 --- a/like.py +++ b/like.py @@ -19,6 +19,7 @@ from utils import locatePost from utils import updateLikesCollection from utils import undoLikesCollectionEntry from utils import hasGroupType +from utils import localActorUrl from posts import sendSignedJson from session import postJson from webfinger import webfingerHandle @@ -75,7 +76,7 @@ def _like(recentPostsCache: {}, newLikeJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Like', - 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, fullDomain), 'object': objectUrl } if ccList: @@ -139,7 +140,7 @@ def likePost(recentPostsCache: {}, """ likeDomain = getFullDomain(likeDomain, likePort) - actorLiked = httpPrefix + '://' + likeDomain + '/users/' + likeNickname + actorLiked = localActorUrl(httpPrefix, likeNickname, likeDomain) objectUrl = actorLiked + '/statuses/' + str(likeStatusNumber) return _like(recentPostsCache, @@ -163,7 +164,7 @@ def sendLikeViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) newLikeJson = { "@context": "https://www.w3.org/ns/activitystreams", @@ -241,7 +242,7 @@ def sendUndoLikeViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) newUndoLikeJson = { "@context": "https://www.w3.org/ns/activitystreams", diff --git a/newsdaemon.py b/newsdaemon.py index f26e6bee7..6e529471b 100644 --- a/newsdaemon.py +++ b/newsdaemon.py @@ -33,6 +33,7 @@ from utils import saveJson from utils import getStatusNumber from utils import clearFromPostCaches from utils import dangerousMarkup +from utils import localActorUrl from inbox import storeHashTags from session import createSession @@ -547,8 +548,8 @@ def _convertRSStoActivityPub(baseDir: str, httpPrefix: str, statusNumber, published = getStatusNumber(dateStr) newPostId = \ - httpPrefix + '://' + domain + \ - '/users/news/statuses/' + statusNumber + localActorUrl(httpPrefix, 'news', domain) + \ + '/statuses/' + statusNumber # file where the post is stored filename = basePath + '/' + newPostId.replace('/', '#') + '.json' @@ -613,7 +614,7 @@ def _convertRSStoActivityPub(baseDir: str, httpPrefix: str, continue idStr = \ - httpPrefix + '://' + domain + '/users/news' + \ + localActorUrl(httpPrefix, 'news', domain) + \ '/statuses/' + statusNumber + '/replies' blog['news'] = True diff --git a/newswire.py b/newswire.py index 1b75873ac..9bcaf0ed5 100644 --- a/newswire.py +++ b/newswire.py @@ -30,6 +30,7 @@ from utils import containsInvalidChars from utils import removeHtml from utils import isAccountDir from utils import acctDir +from utils import localActorUrl from blocking import isBlockedDomain from blocking import isBlockedHashtag from filters import isFiltered @@ -68,8 +69,9 @@ def rss2Header(httpPrefix: str, else: rssStr += \ ' ' + translate[title] + '' + \ - ' ' + httpPrefix + '://' + domainFull + \ - '/users/' + nickname + '/rss.xml' + '' + ' ' + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ + '/rss.xml' + '' return rssStr diff --git a/outbox.py b/outbox.py index a602f83ed..b8b6fb98d 100644 --- a/outbox.py +++ b/outbox.py @@ -27,6 +27,7 @@ from utils import isFeaturedWriter from utils import loadJson from utils import saveJson from utils import acctDir +from utils import localActorUrl from blocking import isBlockedDomain from blocking import outboxBlock from blocking import outboxUndoBlock @@ -100,8 +101,8 @@ def _outboxPersonReceiveUpdate(recentPostsCache: {}, if debug: print('DEBUG: c2s actor update id is not a string') return - actor = \ - httpPrefix + '://' + getFullDomain(domain, port) + '/users/' + nickname + domainFull = getFullDomain(domain, port) + actor = localActorUrl(httpPrefix, nickname, domainFull) if len(messageJson['to']) != 1: if debug: print('DEBUG: c2s actor update - to does not contain one actor ' + @@ -393,7 +394,7 @@ def postMessageToOutbox(session, translate: {}, if messageJson['type'] in indexedActivities: indexes = [outboxName, "inbox"] selfActor = \ - httpPrefix + '://' + domainFull + '/users/' + postToNickname + localActorUrl(httpPrefix, postToNickname, domainFull) for boxNameIndex in indexes: if not boxNameIndex: continue diff --git a/person.py b/person.py index f80ed7501..985286d8e 100644 --- a/person.py +++ b/person.py @@ -54,6 +54,7 @@ from utils import isImageFile from utils import acctDir from utils import getUserPaths from utils import getGroupPaths +from utils import localActorUrl from session import createSession from session import getJson from webfinger import webfingerHandle @@ -138,8 +139,8 @@ def setProfileImage(baseDir: str, httpPrefix: str, nickname: str, domain: str, if personJson: personJson[iconFilenameBase]['mediaType'] = mediaType personJson[iconFilenameBase]['url'] = \ - httpPrefix + '://' + fullDomain + '/users/' + \ - nickname + '/' + iconFilename + localActorUrl(httpPrefix, nickname, fullDomain) + \ + '/' + iconFilename saveJson(personJson, personFilename) cmd = \ @@ -251,7 +252,7 @@ def _createPersonBase(baseDir: str, nickname: str, domain: str, port: int, # Enable follower approval by default approveFollowers = manualFollowerApproval personName = nickname - personId = httpPrefix + '://' + domain + '/users/' + nickname + personId = localActorUrl(httpPrefix, nickname, domain) inboxStr = personId + '/inbox' personUrl = httpPrefix + '://' + domain + '/@' + personName if nickname == 'inbox': diff --git a/pgp.py b/pgp.py index b5c00d92a..5abf6856d 100644 --- a/pgp.py +++ b/pgp.py @@ -15,6 +15,7 @@ from utils import containsPGPPublicKey from utils import isPGPEncrypted from utils import getFullDomain from utils import getStatusNumber +from utils import localActorUrl from webfinger import webfingerHandle from posts import getPersonBox from auth import createBasicAuthHeader @@ -489,7 +490,7 @@ def pgpPublicKeyUpload(baseDir: str, session, if debug: print('Actor for ' + handle + ' obtained') - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) handle = actor.replace('/users/', '/@') # check that this looks like the correct actor diff --git a/posts.py b/posts.py index b9f1ff86f..3593f7ed3 100644 --- a/posts.py +++ b/posts.py @@ -63,6 +63,7 @@ from utils import votesOnNewswireItem from utils import removeHtml from utils import dangerousMarkup from utils import acctDir +from utils import localActorUrl from media import attachMedia from media import replaceYouTube from content import limitRepeatedWords @@ -292,7 +293,7 @@ def getPersonBox(baseDir: str, session, wfRequest: {}, } else: # the final fallback is a mastodon style url - personUrl = httpPrefix + '://' + domain + '/users/' + nickname + personUrl = localActorUrl(httpPrefix, nickname, domain) if not personUrl: return None, None, None, None, None, None, None @@ -766,7 +767,7 @@ def savePostToBox(baseDir: str, httpPrefix: str, postId: str, if not postId: statusNumber, published = getStatusNumber() postId = \ - httpPrefix + '://' + originalDomain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, originalDomain) + \ '/statuses/' + statusNumber postJsonObject['id'] = postId + '/activity' if hasObjectDict(postJsonObject): @@ -919,14 +920,14 @@ def _createPostS2S(baseDir: str, nickname: str, domain: str, port: int, conversationId: str, lowBandwidth: bool) -> {}: """Creates a new server-to-server post """ - actorUrl = httpPrefix + '://' + domain + '/users/' + nickname + actorUrl = localActorUrl(httpPrefix, nickname, domain) idStr = \ - httpPrefix + '://' + domain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domain) + \ '/statuses/' + statusNumber + '/replies' newPostUrl = \ httpPrefix + '://' + domain + '/@' + nickname + '/' + statusNumber newPostAttributedTo = \ - httpPrefix + '://' + domain + '/users/' + nickname + localActorUrl(httpPrefix, nickname, domain) if not conversationId: conversationId = newPostId newPost = { @@ -991,8 +992,9 @@ def _createPostC2S(baseDir: str, nickname: str, domain: str, port: int, conversationId: str, lowBandwidth: str) -> {}: """Creates a new client-to-server post """ + domainFull = getFullDomain(domain, port) idStr = \ - httpPrefix + '://' + domain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domainFull) + \ '/statuses/' + statusNumber + '/replies' newPostUrl = \ httpPrefix + '://' + domain + '/@' + nickname + '/' + statusNumber @@ -1007,7 +1009,7 @@ def _createPostC2S(baseDir: str, nickname: str, domain: str, port: int, 'inReplyTo': inReplyTo, 'published': published, 'url': newPostUrl, - 'attributedTo': httpPrefix + '://' + domain + '/users/' + nickname, + 'attributedTo': localActorUrl(httpPrefix, nickname, domainFull), 'to': toRecipients, 'cc': toCC, 'sensitive': sensitive, @@ -1205,8 +1207,8 @@ def _createPostBase(baseDir: str, nickname: str, domain: str, port: int, statusNumber, published = getStatusNumber() newPostId = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/statuses/' + statusNumber + localActorUrl(httpPrefix, nickname, domain) + \ + '/statuses/' + statusNumber sensitive = False summary = None @@ -1347,7 +1349,7 @@ def outboxMessageCreateWrap(httpPrefix: str, if messageJson.get('published'): published = messageJson['published'] newPostId = \ - httpPrefix + '://' + domain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domain) + \ '/statuses/' + statusNumber cc = [] if messageJson.get('cc'): @@ -1356,7 +1358,7 @@ def outboxMessageCreateWrap(httpPrefix: str, "@context": "https://www.w3.org/ns/activitystreams", 'id': newPostId + '/activity', 'type': 'Create', - 'actor': httpPrefix + '://' + domain + '/users/' + nickname, + 'actor': localActorUrl(httpPrefix, nickname, domain), 'published': published, 'to': messageJson['to'], 'cc': cc, @@ -1366,7 +1368,7 @@ def outboxMessageCreateWrap(httpPrefix: str, newPost['object']['url'] = \ httpPrefix + '://' + domain + '/@' + nickname + '/' + statusNumber newPost['object']['atomUri'] = \ - httpPrefix + '://' + domain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domain) + \ '/statuses/' + statusNumber return newPost @@ -1395,8 +1397,8 @@ def _postIsAddressedToFollowers(baseDir: str, if postJsonObject.get('cc'): ccList = postJsonObject['cc'] - followersUrl = httpPrefix + '://' + domainFull + '/users/' + \ - nickname + '/followers' + followersUrl = \ + localActorUrl(httpPrefix, nickname, domainFull) + '/followers' # does the followers url exist in 'to' or 'cc' lists? addressedToFollowers = False @@ -1434,7 +1436,7 @@ def getPinnedPostAsJson(baseDir: str, httpPrefix: str, accountDir = acctDir(baseDir, nickname, domain) pinnedFilename = accountDir + '/pinToProfile.txt' pinnedPostJson = {} - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) if os.path.isfile(pinnedFilename): pinnedContent = None with open(pinnedFilename, 'r') as pinFile: @@ -1479,7 +1481,7 @@ def jsonPinPost(baseDir: str, httpPrefix: str, if pinnedPostJson: itemsList = [pinnedPostJson] - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) return { '@context': [ 'https://www.w3.org/ns/activitystreams', @@ -1559,10 +1561,10 @@ def createPublicPost(baseDir: str, anonymousParticipationEnabled = None eventStatus = None ticketUrl = None + localActor = localActorUrl(httpPrefix, nickname, domainFull) return _createPostBase(baseDir, nickname, domain, port, 'https://www.w3.org/ns/activitystreams#Public', - httpPrefix + '://' + domainFull + '/users/' + - nickname + '/followers', + localActor + '/followers', httpPrefix, content, followersOnly, saveToFile, clientToServer, commentsEnabled, attachImageFilename, mediaType, @@ -1680,11 +1682,11 @@ def createQuestionPost(baseDir: str, """Question post with multiple choice options """ domainFull = getFullDomain(domain, port) + localActor = localActorUrl(httpPrefix, nickname, domainFull) messageJson = \ _createPostBase(baseDir, nickname, domain, port, 'https://www.w3.org/ns/activitystreams#Public', - httpPrefix + '://' + domainFull + '/users/' + - nickname + '/followers', + localActor + '/followers', httpPrefix, content, followersOnly, saveToFile, clientToServer, commentsEnabled, attachImageFilename, mediaType, @@ -1729,9 +1731,9 @@ def createUnlistedPost(baseDir: str, """Unlisted post. This has the #Public and followers links inverted. """ domainFull = getFullDomain(domain, port) + localActor = localActorUrl(httpPrefix, domainFull, nickname) return _createPostBase(baseDir, nickname, domain, port, - httpPrefix + '://' + domainFull + '/users/' + - nickname + '/followers', + localActor + '/followers', 'https://www.w3.org/ns/activitystreams#Public', httpPrefix, content, followersOnly, saveToFile, clientToServer, commentsEnabled, @@ -1762,9 +1764,9 @@ def createFollowersOnlyPost(baseDir: str, """Followers only post """ domainFull = getFullDomain(domain, port) + localActor = localActorUrl(httpPrefix, domainFull, nickname) return _createPostBase(baseDir, nickname, domain, port, - httpPrefix + '://' + domainFull + '/users/' + - nickname + '/followers', + localActor + '/followers', None, httpPrefix, content, followersOnly, saveToFile, clientToServer, commentsEnabled, @@ -1808,8 +1810,7 @@ def getMentionedPeople(baseDir: str, httpPrefix: str, if not validNickname(mentionedDomain, mentionedNickname): continue actor = \ - httpPrefix + '://' + handle.split('@')[1] + \ - '/users/' + mentionedNickname + localActorUrl(httpPrefix, mentionedNickname, handle.split('@')[1]) mentions.append(actor) return mentions @@ -1898,8 +1899,9 @@ def createReportPost(baseDir: str, if line.startswith('@'): line = line[1:] if '@' in line: - moderatorActor = httpPrefix + '://' + domainFull + \ - '/users/' + line.split('@')[0] + nick = line.split('@')[0] + moderatorActor = \ + localActorUrl(httpPrefix, nick, domainFull) if moderatorActor not in moderatorsList: moderatorsList.append(moderatorActor) continue @@ -1910,16 +1912,16 @@ def createReportPost(baseDir: str, moderatorsList.append(line) else: if '/' not in line: - moderatorActor = httpPrefix + '://' + domainFull + \ - '/users/' + line + moderatorActor = \ + localActorUrl(httpPrefix, line, domainFull) if moderatorActor not in moderatorsList: moderatorsList.append(moderatorActor) if len(moderatorsList) == 0: # if there are no moderators then the admin becomes the moderator adminNickname = getConfigParam(baseDir, 'admin') if adminNickname: - moderatorsList.append(httpPrefix + '://' + domainFull + - '/users/' + adminNickname) + localActor = localActorUrl(httpPrefix, adminNickname, domainFull) + moderatorsList.append(localActor) if not moderatorsList: return None if debug: @@ -2236,18 +2238,17 @@ def sendPostViaServer(projectVersion: str, clientToServer = True if toDomain.lower().endswith('public'): toPersonId = 'https://www.w3.org/ns/activitystreams#Public' - cc = httpPrefix + '://' + fromDomainFull + '/users/' + \ - fromNickname + '/followers' + cc = localActorUrl(httpPrefix, fromNickname, fromDomainFull) + \ + '/followers' else: if toDomain.lower().endswith('followers') or \ toDomain.lower().endswith('followersonly'): toPersonId = \ - httpPrefix + '://' + \ - fromDomainFull + '/users/' + fromNickname + '/followers' + localActorUrl(httpPrefix, fromNickname, fromDomainFull) + \ + '/followers' else: toDomainFull = getFullDomain(toDomain, toPort) - toPersonId = httpPrefix + '://' + toDomainFull + \ - '/users/' + toNickname + toPersonId = localActorUrl(httpPrefix, toNickname, toDomainFull) postJsonObject = \ _createPostBase(baseDir, @@ -3086,7 +3087,7 @@ def createModeration(baseDir: str, nickname: str, domain: str, port: int, pageNumber = 1 pageStr = '?page=' + str(pageNumber) - boxUrl = httpPrefix + '://' + domain + '/users/' + nickname + '/' + boxname + boxUrl = localActorUrl(httpPrefix, nickname, domain) + '/' + boxname boxHeader = { '@context': 'https://www.w3.org/ns/activitystreams', 'first': boxUrl + '?page=true', @@ -3362,7 +3363,7 @@ def _createBoxIndexed(recentPostsCache: {}, originalDomain = domain domain = getFullDomain(domain, port) - boxActor = httpPrefix + '://' + domain + '/users/' + nickname + boxActor = localActorUrl(httpPrefix, nickname, domain) pageStr = '?page=true' if pageNumber: @@ -3372,7 +3373,7 @@ def _createBoxIndexed(recentPostsCache: {}, pageStr = '?page=' + str(pageNumber) except BaseException: pass - boxUrl = httpPrefix + '://' + domain + '/users/' + nickname + '/' + boxname + boxUrl = localActorUrl(httpPrefix, nickname, domain) + '/' + boxname boxHeader = { '@context': 'https://www.w3.org/ns/activitystreams', 'first': boxUrl + '?page=true', @@ -3493,8 +3494,8 @@ def _createBoxIndexed(recentPostsCache: {}, if lastPage < 1: lastPage = 1 boxHeader['last'] = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + boxname + '?page=' + str(lastPage) + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + boxname + '?page=' + str(lastPage) if headerOnly: boxHeader['totalItems'] = len(postsInBox) @@ -3502,13 +3503,13 @@ def _createBoxIndexed(recentPostsCache: {}, if pageNumber > 1: prevPageStr = str(pageNumber - 1) boxHeader['prev'] = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + boxname + '?page=' + prevPageStr + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + boxname + '?page=' + prevPageStr nextPageStr = str(pageNumber + 1) boxHeader['next'] = \ - httpPrefix + '://' + domain + '/users/' + \ - nickname + '/' + boxname + '?page=' + nextPageStr + localActorUrl(httpPrefix, nickname, domain) + \ + '/' + boxname + '?page=' + nextPageStr return boxHeader for postStr in postsInBox: @@ -4358,11 +4359,10 @@ def sendBlockViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + blockActor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + '/users/' + \ - fromNickname + '/followers' + ccUrl = blockActor + '/followers' - blockActor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname newBlockJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Block', @@ -4439,7 +4439,7 @@ def sendMuteViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) handle = actor.replace('/users/', '/@') newMuteJson = { @@ -4515,7 +4515,7 @@ def sendUndoMuteViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) handle = actor.replace('/users/', '/@') undoMuteJson = { @@ -4597,11 +4597,10 @@ def sendUndoBlockViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + blockActor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + '/users/' + \ - fromNickname + '/followers' + ccUrl = blockActor + '/followers' - blockActor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname newBlockJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Undo', @@ -4705,7 +4704,7 @@ def c2sBoxJson(baseDir: str, session, return None domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) authHeader = createBasicAuthHeader(nickname, password) diff --git a/shares.py b/shares.py index 4d16f0fbb..e4b7e4045 100644 --- a/shares.py +++ b/shares.py @@ -37,6 +37,7 @@ from utils import acctDir from utils import isfloat from utils import getCategoryTypes from utils import getSharesFilesList +from utils import localActorUrl from media import processMetaData from media import convertImageToLowBandwidth from filters import isFilteredGlobally @@ -274,14 +275,13 @@ def _indicateNewShareAvailable(baseDir: str, httpPrefix: str, if isBlocked(baseDir, accountNickname, domain, nickname, domain, None): continue + localActor = localActorUrl(httpPrefix, accountNickname, domainFull) try: with open(newShareFile, 'w+') as fp: if sharesFileType == 'shares': - fp.write(httpPrefix + '://' + domainFull + - '/users/' + accountNickname + '/tlshares') + fp.write(localActor + '/tlshares') else: - fp.write(httpPrefix + '://' + domainFull + - '/users/' + accountNickname + '/tlwanted') + fp.write(localActor + '/tlwanted') except BaseException: pass break @@ -313,7 +313,7 @@ def addShare(baseDir: str, durationSec = _addShareDurationSec(duration, published) domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) itemID = _getValidSharedItemID(actor, displayName) dfcId = _getshareDfcId(baseDir, systemLanguage, itemType, itemCategory, translate) @@ -474,7 +474,7 @@ def getSharesFeedForPerson(baseDir: str, sharesJson = loadJson(sharesFilename) if sharesJson: noOfShares = len(sharesJson.items()) - idStr = httpPrefix + '://' + domain + '/users/' + nickname + idStr = localActorUrl(httpPrefix, nickname, domain) shares = { '@context': 'https://www.w3.org/ns/activitystreams', 'first': idStr + '/' + sharesFileType + '?page=1', @@ -488,7 +488,7 @@ def getSharesFeedForPerson(baseDir: str, pageNumber = 1 nextPageNumber = int(pageNumber + 1) - idStr = httpPrefix + '://' + domain + '/users/' + nickname + idStr = localActorUrl(httpPrefix, nickname, domain) shares = { '@context': 'https://www.w3.org/ns/activitystreams', 'id': idStr + '/' + sharesFileType + '?page=' + str(pageNumber), @@ -521,7 +521,7 @@ def getSharesFeedForPerson(baseDir: str, lastPage = 1 if nextPageNumber > lastPage: shares['next'] = \ - httpPrefix + '://' + domain + '/users/' + nickname + \ + localActorUrl(httpPrefix, nickname, domain) + \ '/' + sharesFileType + '?page=' + str(lastPage) return shares @@ -552,11 +552,10 @@ def sendShareViaServer(baseDir, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + \ - '/users/' + fromNickname + '/followers' + ccUrl = actor + '/followers' - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname newShareJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Add', @@ -662,11 +661,10 @@ def sendUndoShareViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + \ - '/users/' + fromNickname + '/followers' + ccUrl = actor + '/followers' - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname undoShareJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Remove', @@ -766,11 +764,10 @@ def sendWantedViaServer(baseDir, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + \ - '/users/' + fromNickname + '/followers' + ccUrl = actor + '/followers' - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname newShareJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Add', @@ -876,11 +873,10 @@ def sendUndoWantedViaServer(baseDir: str, session, fromDomainFull = getFullDomain(fromDomain, fromPort) + actor = localActorUrl(httpPrefix, fromNickname, fromDomainFull) toUrl = 'https://www.w3.org/ns/activitystreams#Public' - ccUrl = httpPrefix + '://' + fromDomainFull + \ - '/users/' + fromNickname + '/followers' + ccUrl = actor + '/followers' - actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname undoShareJson = { "@context": "https://www.w3.org/ns/activitystreams", 'type': 'Remove', @@ -973,7 +969,7 @@ def getSharedItemsCatalogViaServer(baseDir, session, 'Accept': 'application/json' } domainFull = getFullDomain(domain, port) - url = httpPrefix + '://' + domainFull + '/users/' + nickname + '/catalog' + url = localActorUrl(httpPrefix, nickname, domainFull) + '/catalog' if debug: print('Shared items catalog request to: ' + url) catalogJson = getJson(session, url, headers, None, debug, @@ -1139,7 +1135,7 @@ def sharesCatalogAccountEndpoint(baseDir: str, httpPrefix: str, "http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl#" dfcPtUrl = \ "http://static.datafoodconsortium.org/data/productTypes.rdf#" - owner = httpPrefix + '://' + domainFull + '/users/' + nickname + owner = localActorUrl(httpPrefix, nickname, domainFull) if sharesFileType == 'shares': dfcInstanceId = owner + '/catalog' else: @@ -1248,7 +1244,7 @@ def sharesCatalogEndpoint(baseDir: str, httpPrefix: str, continue nickname = acct.split('@')[0] domain = acct.split('@')[1] - owner = httpPrefix + '://' + domainFull + '/users/' + nickname + owner = localActorUrl(httpPrefix, nickname, domainFull) sharesFilename = \ acctDir(baseDir, nickname, domain) + '/' + \ diff --git a/skills.py b/skills.py index 3568db7d6..af8e125a4 100644 --- a/skills.py +++ b/skills.py @@ -19,6 +19,7 @@ from utils import loadJson from utils import getOccupationSkills from utils import setOccupationSkillsList from utils import acctDir +from utils import localActorUrl def setSkillsFromDict(actorJson: {}, skillsDict: {}) -> []: @@ -185,7 +186,7 @@ def sendSkillViaServer(baseDir: str, session, nickname: str, password: str, domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) toUrl = actor ccUrl = actor + '/followers' diff --git a/speaker.py b/speaker.py index 2c413abd6..7d81a48e9 100644 --- a/speaker.py +++ b/speaker.py @@ -24,6 +24,7 @@ from utils import saveJson from utils import isPGPEncrypted from utils import hasObjectDict from utils import acctDir +from utils import localActorUrl from content import htmlReplaceQuoteMarks speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!') @@ -452,7 +453,7 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, img['name'] + '. ' isDirect = isDM(postJsonObject) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) replyToYou = isReply(postJsonObject, actor) published = '' diff --git a/utils.py b/utils.py index 119fccf04..04ab3e8ba 100644 --- a/utils.py +++ b/utils.py @@ -28,6 +28,12 @@ invalidCharacters = ( ) +def localActorUrl(httpPrefix: str, nickname: str, domainFull: str) -> str: + """Returns the url for an actor on this instance + """ + return httpPrefix + '://' + domainFull + '/users/' + nickname + + def getActorLanguagesList(actorJson: {}) -> []: """Returns a list containing languages used by the given actor """ diff --git a/webapp_calendar.py b/webapp_calendar.py index 10e480fc1..81e4e65d8 100644 --- a/webapp_calendar.py +++ b/webapp_calendar.py @@ -21,6 +21,7 @@ from utils import weekDayOfMonthStart from utils import getAltPath from utils import removeDomainPort from utils import acctDir +from utils import localActorUrl from happening import getTodaysEvents from happening import getCalendarEvents from webapp_utils import htmlHeaderWithExternalStyle @@ -37,7 +38,7 @@ def htmlCalendarDeleteConfirm(cssCache: {}, translate: {}, baseDir: str, """Shows a screen asking to confirm the deletion of a calendar event """ nickname = getNicknameFromActor(path) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) domain, port = getDomainFromActor(actor) messageId = actor + '/statuses/' + postId diff --git a/webapp_column_left.py b/webapp_column_left.py index 5d67fff7a..33cd04a51 100644 --- a/webapp_column_left.py +++ b/webapp_column_left.py @@ -12,6 +12,7 @@ from utils import getConfigParam from utils import getNicknameFromActor from utils import isEditor from utils import removeDomainPort +from utils import localActorUrl from webapp_utils import sharesTimelineJson from webapp_utils import htmlPostSeparator from webapp_utils import getLeftImageFile @@ -37,7 +38,7 @@ def _getLeftColumnShares(baseDir: str, """get any shares and turn them into the left column links format """ pageNumber = 1 - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) # NOTE: this could potentially be slow if the number of federated # shared items is large sharesJson, lastPage = \ @@ -75,7 +76,7 @@ def _getLeftColumnWanted(baseDir: str, """get any wanted items and turn them into the left column links format """ pageNumber = 1 - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) # NOTE: this could potentially be slow if the number of federated # wanted items is large sharesJson, lastPage = \ diff --git a/webapp_moderation.py b/webapp_moderation.py index fd7215dd1..31823d8d7 100644 --- a/webapp_moderation.py +++ b/webapp_moderation.py @@ -15,6 +15,7 @@ from utils import loadJson from utils import getNicknameFromActor from utils import getDomainFromActor from utils import getConfigParam +from utils import localActorUrl from posts import downloadFollowCollection from posts import getPublicPostInfo from posts import isModerator @@ -94,7 +95,7 @@ def htmlAccountInfo(cssCache: {}, translate: {}, searchHandle = searchNickname + '@' + searchDomain searchActor = \ - httpPrefix + '://' + searchDomain + '/users/' + searchNickname + localActorUrl(httpPrefix, searchNickname, searchDomain) infoForm += \ '

' + \ translate['Account Information'] + ': ' followApprovalsSection += \ diff --git a/webapp_search.py b/webapp_search.py index 54c9297c8..2ed8d497f 100644 --- a/webapp_search.py +++ b/webapp_search.py @@ -25,6 +25,7 @@ from utils import firstParagraphFromString from utils import searchBoxPosts from utils import getAltPath from utils import acctDir +from utils import localActorUrl from skills import noOfActorSkills from skills import getSkillsFromList from categories import getHashtagCategory @@ -597,7 +598,7 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str, # add the page title domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) historySearchTitle = '🔍 ' + translate['Your Posts'] if boxName == 'bookmarks': historySearchTitle = '🔍 ' + translate['Bookmarks'] diff --git a/webapp_timeline.py b/webapp_timeline.py index 2ba825c91..cfd470dce 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -17,6 +17,7 @@ from utils import isEditor from utils import removeIdEnding from utils import acctDir from utils import isfloat +from utils import localActorUrl from follow import followerApprovalActive from person import isPersonSnoozed from markdown import markdownToHtml @@ -996,12 +997,12 @@ def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int, baseDir, domain, nickname, maxSharesPerAccount, sharedItemsFederatedDomains, sharesFileType) domainFull = getFullDomain(domain, port) - actor = httpPrefix + '://' + domainFull + '/users/' + nickname + actor = localActorUrl(httpPrefix, nickname, domainFull) adminNickname = getConfigParam(baseDir, 'admin') adminActor = '' if adminNickname: adminActor = \ - httpPrefix + '://' + domainFull + '/users/' + adminNickname + localActorUrl(httpPrefix, adminNickname, domainFull) timelineStr = '' if pageNumber > 1: diff --git a/webapp_tos.py b/webapp_tos.py index 119c853bf..6f9a6ba14 100644 --- a/webapp_tos.py +++ b/webapp_tos.py @@ -10,6 +10,7 @@ __module_group__ = "Web Interface" import os from shutil import copyfile from utils import getConfigParam +from utils import localActorUrl from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlFooter from markdown import markdownToHtml @@ -44,8 +45,7 @@ def htmlTermsOfService(cssCache: {}, baseDir: str, TOSForm = htmlHeaderWithExternalStyle(cssFilename, instanceTitle) TOSForm += '
' + TOSText + '
\n' if adminNickname: - adminActor = httpPrefix + '://' + domainFull + \ - '/users/' + adminNickname + adminActor = localActorUrl(httpPrefix, adminNickname, domainFull) TOSForm += \ '