mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon
commit
bca847e5e5
31
blog.py
31
blog.py
|
|
@ -863,3 +863,34 @@ def htmlEditBlog(mediaInstance: bool, translate: {},
|
||||||
|
|
||||||
editBlogForm += htmlFooter()
|
editBlogForm += htmlFooter()
|
||||||
return editBlogForm
|
return editBlogForm
|
||||||
|
|
||||||
|
|
||||||
|
def pathContainsBlogLink(baseDir: str,
|
||||||
|
httpPrefix: str, domain: str,
|
||||||
|
domainFull: str, path: str) -> (str, str):
|
||||||
|
"""If the path contains a blog entry then return its filename
|
||||||
|
"""
|
||||||
|
if '/users/' not in path:
|
||||||
|
return None, None
|
||||||
|
userEnding = path.split('/users/', 1)[1]
|
||||||
|
if '/' not in userEnding:
|
||||||
|
return None, None
|
||||||
|
userEnding2 = userEnding.split('/')
|
||||||
|
nickname = userEnding2[0]
|
||||||
|
if len(userEnding2) != 2:
|
||||||
|
return None, None
|
||||||
|
if len(userEnding2[1]) < 14:
|
||||||
|
return None, None
|
||||||
|
userEnding2[1] = userEnding2[1].strip()
|
||||||
|
if not userEnding2[1].isdigit():
|
||||||
|
return None, None
|
||||||
|
# check for blog posts
|
||||||
|
blogIndexFilename = baseDir + '/accounts/' + \
|
||||||
|
nickname + '@' + domain + '/tlblogs.index'
|
||||||
|
if not os.path.isfile(blogIndexFilename):
|
||||||
|
return None, None
|
||||||
|
if '#' + userEnding2[1] + '.' not in open(blogIndexFilename).read():
|
||||||
|
return None, None
|
||||||
|
messageId = httpPrefix + '://' + domainFull + \
|
||||||
|
'/users/' + nickname + '/statuses/' + userEnding2[1]
|
||||||
|
return locatePost(baseDir, nickname, domain, messageId), nickname
|
||||||
|
|
|
||||||
12
city.py
12
city.py
|
|
@ -217,3 +217,15 @@ def spoofGeolocation(baseDir: str,
|
||||||
return (default_latitude, default_longitude,
|
return (default_latitude, default_longitude,
|
||||||
default_latdirection, default_longdirection,
|
default_latdirection, default_longdirection,
|
||||||
"", "", 0)
|
"", "", 0)
|
||||||
|
|
||||||
|
|
||||||
|
def getSpoofedCity(city: str, baseDir: str, nickname: str, domain: str) -> str:
|
||||||
|
"""Returns the name of the city to use as a GPS spoofing location for
|
||||||
|
image metadata
|
||||||
|
"""
|
||||||
|
cityFilename = baseDir + '/accounts/' + \
|
||||||
|
nickname + '@' + domain + '/city.txt'
|
||||||
|
if os.path.isfile(cityFilename):
|
||||||
|
with open(cityFilename, 'r') as fp:
|
||||||
|
city = fp.read().replace('\n', '')
|
||||||
|
return city
|
||||||
|
|
|
||||||
366
daemon.py
366
daemon.py
|
|
@ -24,10 +24,7 @@ from webfinger import webfingerMeta
|
||||||
from webfinger import webfingerNodeInfo
|
from webfinger import webfingerNodeInfo
|
||||||
from webfinger import webfingerLookup
|
from webfinger import webfingerLookup
|
||||||
from webfinger import webfingerUpdate
|
from webfinger import webfingerUpdate
|
||||||
from mastoapiv1 import getMastoApiV1Account
|
from mastoapiv1 import mastoApiV1Response
|
||||||
from mastoapiv1 import getMastApiV1Id
|
|
||||||
from mastoapiv1 import getNicknameFromMastoApiV1Id
|
|
||||||
from metadata import metaDataInstance
|
|
||||||
from metadata import metaDataNodeInfo
|
from metadata import metaDataNodeInfo
|
||||||
from metadata import metadataCustomEmoji
|
from metadata import metadataCustomEmoji
|
||||||
from pgp import getEmailAddress
|
from pgp import getEmailAddress
|
||||||
|
|
@ -113,6 +110,9 @@ from threads import threadWithTrace
|
||||||
from threads import removeDormantThreads
|
from threads import removeDormantThreads
|
||||||
from media import replaceYouTube
|
from media import replaceYouTube
|
||||||
from media import attachMedia
|
from media import attachMedia
|
||||||
|
from media import pathIsImage
|
||||||
|
from media import pathIsVideo
|
||||||
|
from media import pathIsAudio
|
||||||
from blocking import mutePost
|
from blocking import mutePost
|
||||||
from blocking import unmutePost
|
from blocking import unmutePost
|
||||||
from blocking import setBrochMode
|
from blocking import setBrochMode
|
||||||
|
|
@ -130,12 +130,15 @@ from roles import clearModeratorStatus
|
||||||
from roles import clearEditorStatus
|
from roles import clearEditorStatus
|
||||||
from roles import clearCounselorStatus
|
from roles import clearCounselorStatus
|
||||||
from roles import clearArtistStatus
|
from roles import clearArtistStatus
|
||||||
|
from blog import pathContainsBlogLink
|
||||||
from blog import htmlBlogPageRSS2
|
from blog import htmlBlogPageRSS2
|
||||||
from blog import htmlBlogPageRSS3
|
from blog import htmlBlogPageRSS3
|
||||||
from blog import htmlBlogView
|
from blog import htmlBlogView
|
||||||
from blog import htmlBlogPage
|
from blog import htmlBlogPage
|
||||||
from blog import htmlBlogPost
|
from blog import htmlBlogPost
|
||||||
from blog import htmlEditBlog
|
from blog import htmlEditBlog
|
||||||
|
from webapp_utils import setMinimal
|
||||||
|
from webapp_utils import isMinimal
|
||||||
from webapp_utils import getAvatarImageUrl
|
from webapp_utils import getAvatarImageUrl
|
||||||
from webapp_utils import htmlHashtagBlocked
|
from webapp_utils import htmlHashtagBlocked
|
||||||
from webapp_utils import htmlFollowingList
|
from webapp_utils import htmlFollowingList
|
||||||
|
|
@ -203,6 +206,7 @@ from shares import addShare
|
||||||
from shares import removeShare
|
from shares import removeShare
|
||||||
from shares import expireShares
|
from shares import expireShares
|
||||||
from categories import setHashtagCategory
|
from categories import setHashtagCategory
|
||||||
|
from utils import permittedDir
|
||||||
from utils import isAccountDir
|
from utils import isAccountDir
|
||||||
from utils import getOccupationSkills
|
from utils import getOccupationSkills
|
||||||
from utils import getOccupationName
|
from utils import getOccupationName
|
||||||
|
|
@ -290,6 +294,7 @@ from filters import addGlobalFilter
|
||||||
from filters import removeGlobalFilter
|
from filters import removeGlobalFilter
|
||||||
from context import hasValidContext
|
from context import hasValidContext
|
||||||
from speaker import getSSMLbox
|
from speaker import getSSMLbox
|
||||||
|
from city import getSpoofedCity
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -327,18 +332,6 @@ def saveDomainQrcode(baseDir: str, httpPrefix: str,
|
||||||
class PubServer(BaseHTTPRequestHandler):
|
class PubServer(BaseHTTPRequestHandler):
|
||||||
protocol_version = 'HTTP/1.1'
|
protocol_version = 'HTTP/1.1'
|
||||||
|
|
||||||
def _getSpoofedCity(self, baseDir: str, nickname: str, domain: str) -> str:
|
|
||||||
"""Returns the name of the city to use as a GPS spoofing location for
|
|
||||||
image metadata
|
|
||||||
"""
|
|
||||||
city = self.server.city
|
|
||||||
cityFilename = baseDir + '/accounts/' + \
|
|
||||||
nickname + '@' + domain + '/city.txt'
|
|
||||||
if os.path.isfile(cityFilename):
|
|
||||||
with open(cityFilename, 'r') as fp:
|
|
||||||
city = fp.read().replace('\n', '')
|
|
||||||
return city
|
|
||||||
|
|
||||||
def _getInstalceUrl(self, callingDomain: str) -> str:
|
def _getInstalceUrl(self, callingDomain: str) -> str:
|
||||||
"""Returns the URL for this instance
|
"""Returns the URL for this instance
|
||||||
"""
|
"""
|
||||||
|
|
@ -366,61 +359,11 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return self.headers['signature']
|
return self.headers['signature']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _pathIsImage(self, path: str) -> bool:
|
|
||||||
if path.endswith('.png') or \
|
|
||||||
path.endswith('.jpg') or \
|
|
||||||
path.endswith('.gif') or \
|
|
||||||
path.endswith('.svg') or \
|
|
||||||
path.endswith('.avif') or \
|
|
||||||
path.endswith('.webp'):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _pathIsVideo(self, path: str) -> bool:
|
|
||||||
if path.endswith('.ogv') or \
|
|
||||||
path.endswith('.mp4'):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _pathIsAudio(self, path: str) -> bool:
|
|
||||||
if path.endswith('.ogg') or \
|
|
||||||
path.endswith('.mp3'):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def handle_error(self, request, client_address):
|
def handle_error(self, request, client_address):
|
||||||
print('ERROR: http server error: ' + str(request) + ', ' +
|
print('ERROR: http server error: ' + str(request) + ', ' +
|
||||||
str(client_address))
|
str(client_address))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _isMinimal(self, nickname: str) -> bool:
|
|
||||||
"""Returns true if minimal buttons should be shown
|
|
||||||
for the given account
|
|
||||||
"""
|
|
||||||
accountDir = self.server.baseDir + '/accounts/' + \
|
|
||||||
nickname + '@' + self.server.domain
|
|
||||||
if not os.path.isdir(accountDir):
|
|
||||||
return True
|
|
||||||
minimalFilename = accountDir + '/.notminimal'
|
|
||||||
if os.path.isfile(minimalFilename):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _setMinimal(self, nickname: str, minimal: bool) -> None:
|
|
||||||
"""Sets whether an account should display minimal buttons
|
|
||||||
"""
|
|
||||||
accountDir = self.server.baseDir + '/accounts/' + \
|
|
||||||
nickname + '@' + self.server.domain
|
|
||||||
if not os.path.isdir(accountDir):
|
|
||||||
return
|
|
||||||
minimalFilename = accountDir + '/.notminimal'
|
|
||||||
minimalFileExists = os.path.isfile(minimalFilename)
|
|
||||||
if minimal and minimalFileExists:
|
|
||||||
os.remove(minimalFilename)
|
|
||||||
elif not minimal and not minimalFileExists:
|
|
||||||
with open(minimalFilename, 'w+') as fp:
|
|
||||||
fp.write('\n')
|
|
||||||
|
|
||||||
def _sendReplyToQuestion(self, nickname: str, messageId: str,
|
def _sendReplyToQuestion(self, nickname: str, messageId: str,
|
||||||
answer: str) -> None:
|
answer: str) -> None:
|
||||||
"""Sends a reply to a question
|
"""Sends a reply to a question
|
||||||
|
|
@ -447,7 +390,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
eventDate = None
|
eventDate = None
|
||||||
eventTime = None
|
eventTime = None
|
||||||
location = None
|
location = None
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname, self.server.domain)
|
nickname, self.server.domain)
|
||||||
|
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -860,6 +804,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _hasAccept(self, callingDomain: str) -> bool:
|
def _hasAccept(self, callingDomain: str) -> bool:
|
||||||
|
"""Do the http headers have an Accept field?
|
||||||
|
"""
|
||||||
if self.headers.get('Accept') or callingDomain.endswith('.b32.i2p'):
|
if self.headers.get('Accept') or callingDomain.endswith('.b32.i2p'):
|
||||||
if not self.headers.get('Accept'):
|
if not self.headers.get('Accept'):
|
||||||
self.headers['Accept'] = \
|
self.headers['Accept'] = \
|
||||||
|
|
@ -890,123 +836,23 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
print('mastodon api v1: authorized ' + str(authorized))
|
print('mastodon api v1: authorized ' + str(authorized))
|
||||||
print('mastodon api v1: nickname ' + str(nickname))
|
print('mastodon api v1: nickname ' + str(nickname))
|
||||||
|
|
||||||
sendJson = None
|
brochMode = brochModeIsActive(baseDir)
|
||||||
sendJsonStr = ''
|
sendJson, sendJsonStr = mastoApiV1Response(path,
|
||||||
|
callingDomain,
|
||||||
# parts of the api needing authorization
|
authorized,
|
||||||
if authorized and nickname:
|
|
||||||
if path == '/api/v1/accounts/verify_credentials':
|
|
||||||
sendJson = getMastoApiV1Account(baseDir, nickname, domain)
|
|
||||||
sendJsonStr = 'masto API account sent for ' + nickname
|
|
||||||
|
|
||||||
# Parts of the api which don't need authorization
|
|
||||||
mastoId = getMastApiV1Id(path)
|
|
||||||
if mastoId is not None:
|
|
||||||
pathNickname = getNicknameFromMastoApiV1Id(mastoId)
|
|
||||||
if pathNickname:
|
|
||||||
originalPath = path
|
|
||||||
if '/followers?' in path or \
|
|
||||||
'/following?' in path or \
|
|
||||||
'/search?' in path or \
|
|
||||||
'/relationships?' in path or \
|
|
||||||
'/statuses?' in path:
|
|
||||||
path = path.split('?')[0]
|
|
||||||
if path.endswith('/followers'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API followers sent for ' + nickname
|
|
||||||
elif path.endswith('/following'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API following sent for ' + nickname
|
|
||||||
elif path.endswith('/statuses'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API statuses sent for ' + nickname
|
|
||||||
elif path.endswith('/search'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API search sent ' + originalPath
|
|
||||||
elif path.endswith('/relationships'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = \
|
|
||||||
'masto API relationships sent ' + originalPath
|
|
||||||
else:
|
|
||||||
sendJson = \
|
|
||||||
getMastoApiV1Account(baseDir, pathNickname, domain)
|
|
||||||
sendJsonStr = 'masto API account sent for ' + nickname
|
|
||||||
|
|
||||||
if path.startswith('/api/v1/blocks'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API instance blocks sent'
|
|
||||||
elif path.startswith('/api/v1/favorites'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API favorites sent'
|
|
||||||
elif path.startswith('/api/v1/follow_requests'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API follow requests sent'
|
|
||||||
elif path.startswith('/api/v1/mutes'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API mutes sent'
|
|
||||||
elif path.startswith('/api/v1/notifications'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API notifications sent'
|
|
||||||
elif path.startswith('/api/v1/reports'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API reports sent'
|
|
||||||
elif path.startswith('/api/v1/statuses'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API statuses sent'
|
|
||||||
elif path.startswith('/api/v1/timelines'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API timelines sent'
|
|
||||||
elif path.startswith('/api/v1/custom_emojis'):
|
|
||||||
sendJson = customEmoji
|
|
||||||
sendJsonStr = 'masto API custom emojis sent'
|
|
||||||
|
|
||||||
adminNickname = getConfigParam(baseDir, 'admin')
|
|
||||||
if adminNickname and path == '/api/v1/instance':
|
|
||||||
instanceDescriptionShort = \
|
|
||||||
getConfigParam(baseDir,
|
|
||||||
'instanceDescriptionShort')
|
|
||||||
if not instanceDescriptionShort:
|
|
||||||
instanceDescriptionShort = \
|
|
||||||
translate['Yet another Epicyon Instance']
|
|
||||||
instanceDescription = getConfigParam(baseDir,
|
|
||||||
'instanceDescription')
|
|
||||||
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
|
|
||||||
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
domainFull = onionDomain
|
|
||||||
httpPrefix = 'http'
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
domainFull = i2pDomain
|
|
||||||
httpPrefix = 'http'
|
|
||||||
|
|
||||||
if brochModeIsActive(baseDir):
|
|
||||||
showNodeInfoAccounts = False
|
|
||||||
|
|
||||||
sendJson = \
|
|
||||||
metaDataInstance(showNodeInfoAccounts,
|
|
||||||
instanceTitle,
|
|
||||||
instanceDescriptionShort,
|
|
||||||
instanceDescription,
|
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
baseDir,
|
baseDir,
|
||||||
adminNickname,
|
nickname, domain,
|
||||||
domain,
|
|
||||||
domainFull,
|
domainFull,
|
||||||
|
onionDomain,
|
||||||
|
i2pDomain,
|
||||||
|
translate,
|
||||||
registration,
|
registration,
|
||||||
systemLanguage,
|
systemLanguage,
|
||||||
projectVersion)
|
projectVersion,
|
||||||
sendJsonStr = 'masto API instance metadata sent'
|
customEmoji,
|
||||||
elif path.startswith('/api/v1/instance/peers'):
|
showNodeInfoAccounts,
|
||||||
# This is just a dummy result.
|
brochMode)
|
||||||
# Showing the full list of peers would have privacy implications.
|
|
||||||
# On a large instance you are somewhat lost in the crowd, but on
|
|
||||||
# small instances a full list of peers would convey a lot of
|
|
||||||
# information about the interests of a small number of accounts
|
|
||||||
sendJson = ['mastodon.social', domainFull]
|
|
||||||
sendJsonStr = 'masto API peers metadata sent'
|
|
||||||
elif path.startswith('/api/v1/instance/activity'):
|
|
||||||
sendJson = []
|
|
||||||
sendJsonStr = 'masto API activity metadata sent'
|
|
||||||
|
|
||||||
if sendJson is not None:
|
if sendJson is not None:
|
||||||
msg = json.dumps(sendJson).encode('utf-8')
|
msg = json.dumps(sendJson).encode('utf-8')
|
||||||
|
|
@ -1176,16 +1022,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self._404()
|
self._404()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _permittedDir(self, path: str) -> bool:
|
|
||||||
"""These are special paths which should not be accessible
|
|
||||||
directly via GET or POST
|
|
||||||
"""
|
|
||||||
if path.startswith('/wfendpoints') or \
|
|
||||||
path.startswith('/keys') or \
|
|
||||||
path.startswith('/accounts'):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _postToOutbox(self, messageJson: {}, version: str,
|
def _postToOutbox(self, messageJson: {}, version: str,
|
||||||
postToNickname=None) -> bool:
|
postToNickname=None) -> bool:
|
||||||
"""post is received by the outbox
|
"""post is received by the outbox
|
||||||
|
|
@ -1197,7 +1033,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if postToNickname:
|
if postToNickname:
|
||||||
print('Posting to nickname ' + postToNickname)
|
print('Posting to nickname ' + postToNickname)
|
||||||
self.postToNickname = postToNickname
|
self.postToNickname = postToNickname
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
postToNickname, self.server.domain)
|
postToNickname, self.server.domain)
|
||||||
|
|
||||||
return postMessageToOutbox(self.server.session,
|
return postMessageToOutbox(self.server.session,
|
||||||
|
|
@ -1427,12 +1264,12 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
def _isAuthorized(self) -> bool:
|
def _isAuthorized(self) -> bool:
|
||||||
self.authorizedNickname = None
|
self.authorizedNickname = None
|
||||||
|
|
||||||
if self.path.startswith('/icons/') or \
|
notAuthPaths = (
|
||||||
self.path.startswith('/avatars/') or \
|
'/icons/', '/avatars/', '/favicon.ico', '/newswire.xml',
|
||||||
self.path.startswith('/favicon.ico') or \
|
'/newswire_favicon.ico', '/categories.xml'
|
||||||
self.path.startswith('/newswire_favicon.ico') or \
|
)
|
||||||
self.path.startswith('/categories.xml') or \
|
for notAuthStr in notAuthPaths:
|
||||||
self.path.startswith('/newswire.xml'):
|
if self.path.startswith(notAuthStr):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# token based authenticated used by the web interface
|
# token based authenticated used by the web interface
|
||||||
|
|
@ -1526,36 +1363,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
print('POST TIMING|' + str(ctr) + '|' + timeDiff)
|
print('POST TIMING|' + str(ctr) + '|' + timeDiff)
|
||||||
ctr += 1
|
ctr += 1
|
||||||
|
|
||||||
def _pathContainsBlogLink(self, baseDir: str,
|
|
||||||
httpPrefix: str, domain: str,
|
|
||||||
domainFull: str, path: str) -> (str, str):
|
|
||||||
"""If the path contains a blog entry then return its filename
|
|
||||||
"""
|
|
||||||
if '/users/' not in path:
|
|
||||||
return None, None
|
|
||||||
userEnding = path.split('/users/', 1)[1]
|
|
||||||
if '/' not in userEnding:
|
|
||||||
return None, None
|
|
||||||
userEnding2 = userEnding.split('/')
|
|
||||||
nickname = userEnding2[0]
|
|
||||||
if len(userEnding2) != 2:
|
|
||||||
return None, None
|
|
||||||
if len(userEnding2[1]) < 14:
|
|
||||||
return None, None
|
|
||||||
userEnding2[1] = userEnding2[1].strip()
|
|
||||||
if not userEnding2[1].isdigit():
|
|
||||||
return None, None
|
|
||||||
# check for blog posts
|
|
||||||
blogIndexFilename = baseDir + '/accounts/' + \
|
|
||||||
nickname + '@' + domain + '/tlblogs.index'
|
|
||||||
if not os.path.isfile(blogIndexFilename):
|
|
||||||
return None, None
|
|
||||||
if '#' + userEnding2[1] + '.' not in open(blogIndexFilename).read():
|
|
||||||
return None, None
|
|
||||||
messageId = httpPrefix + '://' + domainFull + \
|
|
||||||
'/users/' + nickname + '/statuses/' + userEnding2[1]
|
|
||||||
return locatePost(baseDir, nickname, domain, messageId), nickname
|
|
||||||
|
|
||||||
def _loginScreen(self, path: str, callingDomain: str, cookie: str,
|
def _loginScreen(self, path: str, callingDomain: str, cookie: str,
|
||||||
baseDir: str, httpPrefix: str,
|
baseDir: str, httpPrefix: str,
|
||||||
domain: str, domainFull: str, port: int,
|
domain: str, domainFull: str, port: int,
|
||||||
|
|
@ -4184,7 +3991,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
except BaseException:
|
except BaseException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
|
|
||||||
processMetaData(baseDir, nickname, domain,
|
processMetaData(baseDir, nickname, domain,
|
||||||
filename, postImageFilename, city)
|
filename, postImageFilename, city)
|
||||||
|
|
@ -6041,9 +5849,9 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
GETstartTime, GETtimings: {}) -> None:
|
GETstartTime, GETtimings: {}) -> None:
|
||||||
"""Returns a media file
|
"""Returns a media file
|
||||||
"""
|
"""
|
||||||
if self._pathIsImage(path) or \
|
if pathIsImage(path) or \
|
||||||
self._pathIsVideo(path) or \
|
pathIsVideo(path) or \
|
||||||
self._pathIsAudio(path):
|
pathIsAudio(path):
|
||||||
mediaStr = path.split('/media/')[1]
|
mediaStr = path.split('/media/')[1]
|
||||||
mediaFilename = baseDir + '/media/' + mediaStr
|
mediaFilename = baseDir + '/media/' + mediaStr
|
||||||
if os.path.isfile(mediaFilename):
|
if os.path.isfile(mediaFilename):
|
||||||
|
|
@ -6071,7 +5879,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
GETstartTime, GETtimings: {}) -> None:
|
GETstartTime, GETtimings: {}) -> None:
|
||||||
"""Returns an emoji image
|
"""Returns an emoji image
|
||||||
"""
|
"""
|
||||||
if self._pathIsImage(path):
|
if pathIsImage(path):
|
||||||
emojiStr = path.split('/emoji/')[1]
|
emojiStr = path.split('/emoji/')[1]
|
||||||
emojiFilename = baseDir + '/emoji/' + emojiStr
|
emojiFilename = baseDir + '/emoji/' + emojiStr
|
||||||
if os.path.isfile(emojiFilename):
|
if os.path.isfile(emojiFilename):
|
||||||
|
|
@ -7585,7 +7393,9 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
accessKeys = self.server.keyShortcuts[nickname]
|
accessKeys = self.server.keyShortcuts[nickname]
|
||||||
|
|
||||||
rolesList = getActorRolesList(actorJson)
|
rolesList = getActorRolesList(actorJson)
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = \
|
||||||
|
getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
self.server.cssCache,
|
self.server.cssCache,
|
||||||
|
|
@ -7683,7 +7493,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
actorSkillsList = \
|
actorSkillsList = \
|
||||||
getOccupationSkills(actorJson)
|
getOccupationSkills(actorJson)
|
||||||
skills = getSkillsFromList(actorSkillsList)
|
skills = getSkillsFromList(actorSkillsList)
|
||||||
city = self._getSpoofedCity(baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir,
|
||||||
nickname, domain)
|
nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
|
|
@ -8073,7 +7884,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
'show inbox page')
|
'show inbox page')
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8209,7 +8020,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8338,7 +8149,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8467,7 +8278,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8597,7 +8408,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8735,7 +8546,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
editor = isEditor(baseDir, currNickname)
|
editor = isEditor(baseDir, currNickname)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -8871,7 +8682,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
currNickname = currNickname.split('/')[0]
|
currNickname = currNickname.split('/')[0]
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -9080,7 +8891,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -9213,7 +9024,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -9338,7 +9149,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.votingTimeMins)
|
self.server.votingTimeMins)
|
||||||
fullWidthTimelineButtonHeader = \
|
fullWidthTimelineButtonHeader = \
|
||||||
self.server.fullWidthTimelineButtonHeader
|
self.server.fullWidthTimelineButtonHeader
|
||||||
minimalNick = self._isMinimal(nickname)
|
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||||
|
|
||||||
accessKeys = self.server.accessKeys
|
accessKeys = self.server.accessKeys
|
||||||
if self.server.keyShortcuts.get(nickname):
|
if self.server.keyShortcuts.get(nickname):
|
||||||
|
|
@ -9582,7 +9393,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
accessKeys = \
|
accessKeys = \
|
||||||
self.server.keyShortcuts[nickname]
|
self.server.keyShortcuts[nickname]
|
||||||
|
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
self.server.cssCache,
|
self.server.cssCache,
|
||||||
|
|
@ -9694,7 +9506,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
accessKeys = \
|
accessKeys = \
|
||||||
self.server.keyShortcuts[nickname]
|
self.server.keyShortcuts[nickname]
|
||||||
|
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
self.server.cssCache,
|
self.server.cssCache,
|
||||||
|
|
@ -9805,7 +9618,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
accessKeys = \
|
accessKeys = \
|
||||||
self.server.keyShortcuts[nickname]
|
self.server.keyShortcuts[nickname]
|
||||||
|
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
self.server.cssCache,
|
self.server.cssCache,
|
||||||
|
|
@ -9940,7 +9754,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
accessKeys = \
|
accessKeys = \
|
||||||
self.server.keyShortcuts[nickname]
|
self.server.keyShortcuts[nickname]
|
||||||
|
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
msg = \
|
msg = \
|
||||||
htmlProfile(self.server.rssIconAtTop,
|
htmlProfile(self.server.rssIconAtTop,
|
||||||
self.server.cssCache,
|
self.server.cssCache,
|
||||||
|
|
@ -10309,7 +10124,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
GETstartTime, GETtimings: {}) -> bool:
|
GETstartTime, GETtimings: {}) -> bool:
|
||||||
"""Show a shared item image
|
"""Show a shared item image
|
||||||
"""
|
"""
|
||||||
if not self._pathIsImage(path):
|
if not pathIsImage(path):
|
||||||
self._404()
|
self._404()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -10357,7 +10172,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
if '/users/' not in path:
|
if '/users/' not in path:
|
||||||
return False
|
return False
|
||||||
if not self._pathIsImage(path):
|
if not pathIsImage(path):
|
||||||
return False
|
return False
|
||||||
avatarStr = path.split('/users/')[1]
|
avatarStr = path.split('/users/')[1]
|
||||||
if not ('/' in avatarStr and '.temp.' not in path):
|
if not ('/' in avatarStr and '.temp.' not in path):
|
||||||
|
|
@ -10542,7 +10357,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
peertubeInstances = self.server.peertubeInstances
|
peertubeInstances = self.server.peertubeInstances
|
||||||
nickname = getNicknameFromActor(path)
|
nickname = getNicknameFromActor(path)
|
||||||
if nickname:
|
if nickname:
|
||||||
city = self._getSpoofedCity(baseDir, nickname, domain)
|
city = getSpoofedCity(self.server.city,
|
||||||
|
baseDir, nickname, domain)
|
||||||
else:
|
else:
|
||||||
city = self.server.city
|
city = self.server.city
|
||||||
|
|
||||||
|
|
@ -11290,7 +11106,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
'person options done')
|
'person options done')
|
||||||
# show blog post
|
# show blog post
|
||||||
blogFilename, nickname = \
|
blogFilename, nickname = \
|
||||||
self._pathContainsBlogLink(self.server.baseDir,
|
pathContainsBlogLink(self.server.baseDir,
|
||||||
self.server.httpPrefix,
|
self.server.httpPrefix,
|
||||||
self.server.domain,
|
self.server.domain,
|
||||||
self.server.domainFull,
|
self.server.domainFull,
|
||||||
|
|
@ -11569,7 +11385,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# if not authorized then show the login screen
|
# if not authorized then show the login screen
|
||||||
if htmlGET and self.path != '/login' and \
|
if htmlGET and self.path != '/login' and \
|
||||||
not self._pathIsImage(self.path) and \
|
not pathIsImage(self.path) and \
|
||||||
self.path != '/' and \
|
self.path != '/' and \
|
||||||
self.path != '/users/news/linksmobile' and \
|
self.path != '/users/news/linksmobile' and \
|
||||||
self.path != '/users/news/newswiremobile':
|
self.path != '/users/news/newswiremobile':
|
||||||
|
|
@ -11873,7 +11689,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
'avatar background shown done',
|
'avatar background shown done',
|
||||||
'GET busy time')
|
'GET busy time')
|
||||||
|
|
||||||
if not self._permittedDir(self.path):
|
if not permittedDir(self.path):
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG: GET Not permitted')
|
print('DEBUG: GET Not permitted')
|
||||||
self._404()
|
self._404()
|
||||||
|
|
@ -12062,7 +11878,10 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
nickname = self.path.split('/users/')[1]
|
nickname = self.path.split('/users/')[1]
|
||||||
if '/' in nickname:
|
if '/' in nickname:
|
||||||
nickname = nickname.split('/')[0]
|
nickname = nickname.split('/')[0]
|
||||||
self._setMinimal(nickname, not self._isMinimal(nickname))
|
notMin = not isMinimal(self.server.baseDir,
|
||||||
|
self.server.domain, nickname)
|
||||||
|
setMinimal(self.server.baseDir,
|
||||||
|
self.server.domain, nickname, notMin)
|
||||||
if not (self.server.mediaInstance or
|
if not (self.server.mediaInstance or
|
||||||
self.server.blogsInstance):
|
self.server.blogsInstance):
|
||||||
self.path = '/users/' + nickname + '/inbox'
|
self.path = '/users/' + nickname + '/inbox'
|
||||||
|
|
@ -13227,9 +13046,9 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
fileLength = -1
|
fileLength = -1
|
||||||
|
|
||||||
if '/media/' in self.path:
|
if '/media/' in self.path:
|
||||||
if self._pathIsImage(self.path) or \
|
if pathIsImage(self.path) or \
|
||||||
self._pathIsVideo(self.path) or \
|
pathIsVideo(self.path) or \
|
||||||
self._pathIsAudio(self.path):
|
pathIsAudio(self.path):
|
||||||
mediaStr = self.path.split('/media/')[1]
|
mediaStr = self.path.split('/media/')[1]
|
||||||
mediaFilename = \
|
mediaFilename = \
|
||||||
self.server.baseDir + '/media/' + mediaStr
|
self.server.baseDir + '/media/' + mediaStr
|
||||||
|
|
@ -13335,7 +13154,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
filename.endswith('.gif'):
|
filename.endswith('.gif'):
|
||||||
postImageFilename = filename.replace('.temp', '')
|
postImageFilename = filename.replace('.temp', '')
|
||||||
print('Removing metadata from ' + postImageFilename)
|
print('Removing metadata from ' + postImageFilename)
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname, self.server.domain)
|
nickname, self.server.domain)
|
||||||
processMetaData(self.server.baseDir,
|
processMetaData(self.server.baseDir,
|
||||||
nickname, self.server.domain,
|
nickname, self.server.domain,
|
||||||
|
|
@ -13448,7 +13268,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
nickname, self.server.domain)
|
nickname, self.server.domain)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname, self.server.domain)
|
nickname, self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
createPublicPost(self.server.baseDir,
|
createPublicPost(self.server.baseDir,
|
||||||
|
|
@ -13597,7 +13418,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
imgDescription = fields['imageDescription']
|
imgDescription = fields['imageDescription']
|
||||||
|
|
||||||
if filename:
|
if filename:
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
postJsonObject['object'] = \
|
postJsonObject['object'] = \
|
||||||
|
|
@ -13632,7 +13454,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
str(fields['postUrl']))
|
str(fields['postUrl']))
|
||||||
return -1
|
return -1
|
||||||
elif postType == 'newunlisted':
|
elif postType == 'newunlisted':
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13666,7 +13489,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
elif postType == 'newfollowers':
|
elif postType == 'newfollowers':
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13722,7 +13546,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
maximumAttendeeCapacity = \
|
maximumAttendeeCapacity = \
|
||||||
int(fields['maximumAttendeeCapacity'])
|
int(fields['maximumAttendeeCapacity'])
|
||||||
|
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13762,7 +13587,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
messageJson = None
|
messageJson = None
|
||||||
print('A DM was posted')
|
print('A DM was posted')
|
||||||
if '@' in mentionsStr:
|
if '@' in mentionsStr:
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13806,7 +13632,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
print('A reminder was posted for ' + handle)
|
print('A reminder was posted for ' + handle)
|
||||||
if '@' + handle not in mentionsStr:
|
if '@' + handle not in mentionsStr:
|
||||||
mentionsStr = '@' + handle + ' ' + mentionsStr
|
mentionsStr = '@' + handle + ' ' + mentionsStr
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13843,7 +13670,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# and not accounts being reported we disable any
|
# and not accounts being reported we disable any
|
||||||
# included fediverse addresses by replacing '@' with '-at-'
|
# included fediverse addresses by replacing '@' with '-at-'
|
||||||
fields['message'] = fields['message'].replace('@', '-at-')
|
fields['message'] = fields['message'].replace('@', '-at-')
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13875,7 +13703,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
str(questionCtr)])
|
str(questionCtr)])
|
||||||
if not qOptions:
|
if not qOptions:
|
||||||
return -1
|
return -1
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
|
|
@ -13914,7 +13743,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if durationStr:
|
if durationStr:
|
||||||
if ' ' not in durationStr:
|
if ' ' not in durationStr:
|
||||||
durationStr = durationStr + ' days'
|
durationStr = durationStr + ' days'
|
||||||
city = self._getSpoofedCity(self.server.baseDir,
|
city = getSpoofedCity(self.server.city,
|
||||||
|
self.server.baseDir,
|
||||||
nickname,
|
nickname,
|
||||||
self.server.domain)
|
self.server.domain)
|
||||||
addShare(self.server.baseDir,
|
addShare(self.server.baseDir,
|
||||||
|
|
|
||||||
143
mastoapiv1.py
143
mastoapiv1.py
|
|
@ -8,9 +8,11 @@ __status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from utils import loadJson
|
from utils import loadJson
|
||||||
|
from utils import getConfigParam
|
||||||
|
from metadata import metaDataInstance
|
||||||
|
|
||||||
|
|
||||||
def getMastApiV1Id(path: str) -> int:
|
def _getMastApiV1Id(path: str) -> int:
|
||||||
"""Extracts the mastodon Id number from the given path
|
"""Extracts the mastodon Id number from the given path
|
||||||
"""
|
"""
|
||||||
mastoId = None
|
mastoId = None
|
||||||
|
|
@ -46,7 +48,7 @@ def getNicknameFromMastoApiV1Id(mastoId: int) -> str:
|
||||||
return nickname[::-1]
|
return nickname[::-1]
|
||||||
|
|
||||||
|
|
||||||
def getMastoApiV1Account(baseDir: str, nickname: str, domain: str) -> {}:
|
def _getMastoApiV1Account(baseDir: str, nickname: str, domain: str) -> {}:
|
||||||
"""See https://github.com/McKael/mastodon-documentation/
|
"""See https://github.com/McKael/mastodon-documentation/
|
||||||
blob/master/Using-the-API/API.md#account
|
blob/master/Using-the-API/API.md#account
|
||||||
Authorization has already been performed
|
Authorization has already been performed
|
||||||
|
|
@ -76,3 +78,140 @@ def getMastoApiV1Account(baseDir: str, nickname: str, domain: str) -> {}:
|
||||||
"header_static": accountJson['image']['url']
|
"header_static": accountJson['image']['url']
|
||||||
}
|
}
|
||||||
return mastoAccountJson
|
return mastoAccountJson
|
||||||
|
|
||||||
|
|
||||||
|
def mastoApiV1Response(path: str, callingDomain: str,
|
||||||
|
authorized: bool,
|
||||||
|
httpPrefix: str,
|
||||||
|
baseDir: str, nickname: str, domain: str,
|
||||||
|
domainFull: str,
|
||||||
|
onionDomain: str, i2pDomain: str,
|
||||||
|
translate: {},
|
||||||
|
registration: bool,
|
||||||
|
systemLanguage: str,
|
||||||
|
projectVersion: str,
|
||||||
|
customEmoji: [],
|
||||||
|
showNodeInfoAccounts: bool,
|
||||||
|
brochMode: bool) -> ({}, str):
|
||||||
|
"""This is a vestigil mastodon API for the purpose
|
||||||
|
of returning an empty result to sites like
|
||||||
|
https://mastopeek.app-dist.eu
|
||||||
|
"""
|
||||||
|
sendJson = None
|
||||||
|
sendJsonStr = ''
|
||||||
|
|
||||||
|
# parts of the api needing authorization
|
||||||
|
if authorized and nickname:
|
||||||
|
if path == '/api/v1/accounts/verify_credentials':
|
||||||
|
sendJson = _getMastoApiV1Account(baseDir, nickname, domain)
|
||||||
|
sendJsonStr = 'masto API account sent for ' + nickname
|
||||||
|
|
||||||
|
# Parts of the api which don't need authorization
|
||||||
|
mastoId = _getMastApiV1Id(path)
|
||||||
|
if mastoId is not None:
|
||||||
|
pathNickname = getNicknameFromMastoApiV1Id(mastoId)
|
||||||
|
if pathNickname:
|
||||||
|
originalPath = path
|
||||||
|
if '/followers?' in path or \
|
||||||
|
'/following?' in path or \
|
||||||
|
'/search?' in path or \
|
||||||
|
'/relationships?' in path or \
|
||||||
|
'/statuses?' in path:
|
||||||
|
path = path.split('?')[0]
|
||||||
|
if path.endswith('/followers'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API followers sent for ' + nickname
|
||||||
|
elif path.endswith('/following'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API following sent for ' + nickname
|
||||||
|
elif path.endswith('/statuses'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API statuses sent for ' + nickname
|
||||||
|
elif path.endswith('/search'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API search sent ' + originalPath
|
||||||
|
elif path.endswith('/relationships'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = \
|
||||||
|
'masto API relationships sent ' + originalPath
|
||||||
|
else:
|
||||||
|
sendJson = \
|
||||||
|
_getMastoApiV1Account(baseDir, pathNickname, domain)
|
||||||
|
sendJsonStr = 'masto API account sent for ' + nickname
|
||||||
|
|
||||||
|
if path.startswith('/api/v1/blocks'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API instance blocks sent'
|
||||||
|
elif path.startswith('/api/v1/favorites'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API favorites sent'
|
||||||
|
elif path.startswith('/api/v1/follow_requests'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API follow requests sent'
|
||||||
|
elif path.startswith('/api/v1/mutes'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API mutes sent'
|
||||||
|
elif path.startswith('/api/v1/notifications'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API notifications sent'
|
||||||
|
elif path.startswith('/api/v1/reports'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API reports sent'
|
||||||
|
elif path.startswith('/api/v1/statuses'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API statuses sent'
|
||||||
|
elif path.startswith('/api/v1/timelines'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API timelines sent'
|
||||||
|
elif path.startswith('/api/v1/custom_emojis'):
|
||||||
|
sendJson = customEmoji
|
||||||
|
sendJsonStr = 'masto API custom emojis sent'
|
||||||
|
|
||||||
|
adminNickname = getConfigParam(baseDir, 'admin')
|
||||||
|
if adminNickname and path == '/api/v1/instance':
|
||||||
|
instanceDescriptionShort = \
|
||||||
|
getConfigParam(baseDir,
|
||||||
|
'instanceDescriptionShort')
|
||||||
|
if not instanceDescriptionShort:
|
||||||
|
instanceDescriptionShort = \
|
||||||
|
translate['Yet another Epicyon Instance']
|
||||||
|
instanceDescription = getConfigParam(baseDir,
|
||||||
|
'instanceDescription')
|
||||||
|
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
|
||||||
|
|
||||||
|
if callingDomain.endswith('.onion') and onionDomain:
|
||||||
|
domainFull = onionDomain
|
||||||
|
httpPrefix = 'http'
|
||||||
|
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
||||||
|
domainFull = i2pDomain
|
||||||
|
httpPrefix = 'http'
|
||||||
|
|
||||||
|
if brochMode:
|
||||||
|
showNodeInfoAccounts = False
|
||||||
|
|
||||||
|
sendJson = \
|
||||||
|
metaDataInstance(showNodeInfoAccounts,
|
||||||
|
instanceTitle,
|
||||||
|
instanceDescriptionShort,
|
||||||
|
instanceDescription,
|
||||||
|
httpPrefix,
|
||||||
|
baseDir,
|
||||||
|
adminNickname,
|
||||||
|
domain,
|
||||||
|
domainFull,
|
||||||
|
registration,
|
||||||
|
systemLanguage,
|
||||||
|
projectVersion)
|
||||||
|
sendJsonStr = 'masto API instance metadata sent'
|
||||||
|
elif path.startswith('/api/v1/instance/peers'):
|
||||||
|
# This is just a dummy result.
|
||||||
|
# Showing the full list of peers would have privacy implications.
|
||||||
|
# On a large instance you are somewhat lost in the crowd, but on
|
||||||
|
# small instances a full list of peers would convey a lot of
|
||||||
|
# information about the interests of a small number of accounts
|
||||||
|
sendJson = ['mastodon.social', domainFull]
|
||||||
|
sendJsonStr = 'masto API peers metadata sent'
|
||||||
|
elif path.startswith('/api/v1/instance/activity'):
|
||||||
|
sendJson = []
|
||||||
|
sendJsonStr = 'masto API activity metadata sent'
|
||||||
|
return sendJson, sendJsonStr
|
||||||
|
|
|
||||||
25
media.py
25
media.py
|
|
@ -283,3 +283,28 @@ def archiveMedia(baseDir: str, archiveDirectory: str, maxWeeks=4) -> None:
|
||||||
# archive to /dev/null
|
# archive to /dev/null
|
||||||
rmtree(os.path.join(baseDir + '/media', weekDir))
|
rmtree(os.path.join(baseDir + '/media', weekDir))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def pathIsImage(path: str) -> bool:
|
||||||
|
if path.endswith('.png') or \
|
||||||
|
path.endswith('.jpg') or \
|
||||||
|
path.endswith('.gif') or \
|
||||||
|
path.endswith('.svg') or \
|
||||||
|
path.endswith('.avif') or \
|
||||||
|
path.endswith('.webp'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def pathIsVideo(path: str) -> bool:
|
||||||
|
if path.endswith('.ogv') or \
|
||||||
|
path.endswith('.mp4'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def pathIsAudio(path: str) -> bool:
|
||||||
|
if path.endswith('.ogg') or \
|
||||||
|
path.endswith('.mp3'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
||||||
11
utils.py
11
utils.py
|
|
@ -2410,3 +2410,14 @@ def isAccountDir(dirName: str) -> bool:
|
||||||
if 'inbox@' in dirName or 'news@' in dirName:
|
if 'inbox@' in dirName or 'news@' in dirName:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def permittedDir(path: str) -> bool:
|
||||||
|
"""These are special paths which should not be accessible
|
||||||
|
directly via GET or POST
|
||||||
|
"""
|
||||||
|
if path.startswith('/wfendpoints') or \
|
||||||
|
path.startswith('/keys') or \
|
||||||
|
path.startswith('/accounts'):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
|
||||||
|
|
@ -1358,3 +1358,33 @@ def htmlKeyboardNavigation(banner: str, links: {}, accessKeys: {},
|
||||||
str(title) + '</a></label></li>\n'
|
str(title) + '</a></label></li>\n'
|
||||||
htmlStr += '</ul></div>\n'
|
htmlStr += '</ul></div>\n'
|
||||||
return htmlStr
|
return htmlStr
|
||||||
|
|
||||||
|
|
||||||
|
def isMinimal(baseDir: str, domain: str, nickname: str) -> bool:
|
||||||
|
"""Returns true if minimal buttons should be shown
|
||||||
|
for the given account
|
||||||
|
"""
|
||||||
|
accountDir = baseDir + '/accounts/' + \
|
||||||
|
nickname + '@' + domain
|
||||||
|
if not os.path.isdir(accountDir):
|
||||||
|
return True
|
||||||
|
minimalFilename = accountDir + '/.notminimal'
|
||||||
|
if os.path.isfile(minimalFilename):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def setMinimal(baseDir: str, domain: str, nickname: str,
|
||||||
|
minimal: bool) -> None:
|
||||||
|
"""Sets whether an account should display minimal buttons
|
||||||
|
"""
|
||||||
|
accountDir = baseDir + '/accounts/' + nickname + '@' + domain
|
||||||
|
if not os.path.isdir(accountDir):
|
||||||
|
return
|
||||||
|
minimalFilename = accountDir + '/.notminimal'
|
||||||
|
minimalFileExists = os.path.isfile(minimalFilename)
|
||||||
|
if minimal and minimalFileExists:
|
||||||
|
os.remove(minimalFilename)
|
||||||
|
elif not minimal and not minimalFileExists:
|
||||||
|
with open(minimalFilename, 'w+') as fp:
|
||||||
|
fp.write('\n')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue