mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon
commit
294d08c31d
|
|
@ -627,6 +627,13 @@ def outboxUndoMute(baseDir: str, httpPrefix: str,
|
||||||
print('DEBUG: post undo mute via c2s - ' + postFilename)
|
print('DEBUG: post undo mute via c2s - ' + postFilename)
|
||||||
|
|
||||||
|
|
||||||
|
def brochModeIsActive(baseDir: str) -> bool:
|
||||||
|
"""Returns true if broch mode is active
|
||||||
|
"""
|
||||||
|
allowFilename = baseDir + '/accounts/allowedinstances.txt'
|
||||||
|
return os.path.isfile(allowFilename)
|
||||||
|
|
||||||
|
|
||||||
def setBrochMode(baseDir: str, domainFull: str, enabled: bool) -> None:
|
def setBrochMode(baseDir: str, domainFull: str, enabled: bool) -> None:
|
||||||
"""Broch mode can be used to lock down the instance during
|
"""Broch mode can be used to lock down the instance during
|
||||||
a period of time when it is temporarily under attack.
|
a period of time when it is temporarily under attack.
|
||||||
|
|
|
||||||
427
daemon.py
427
daemon.py
|
|
@ -110,6 +110,7 @@ from media import attachMedia
|
||||||
from blocking import mutePost
|
from blocking import mutePost
|
||||||
from blocking import unmutePost
|
from blocking import unmutePost
|
||||||
from blocking import setBrochMode
|
from blocking import setBrochMode
|
||||||
|
from blocking import brochModeIsActive
|
||||||
from blocking import addBlock
|
from blocking import addBlock
|
||||||
from blocking import removeBlock
|
from blocking import removeBlock
|
||||||
from blocking import addGlobalBlock
|
from blocking import addGlobalBlock
|
||||||
|
|
@ -311,6 +312,20 @@ def saveDomainQrcode(baseDir: str, httpPrefix: str,
|
||||||
class PubServer(BaseHTTPRequestHandler):
|
class PubServer(BaseHTTPRequestHandler):
|
||||||
protocol_version = 'HTTP/1.1'
|
protocol_version = 'HTTP/1.1'
|
||||||
|
|
||||||
|
def _getInstalceUrl(self, callingDomain: str) -> str:
|
||||||
|
"""Returns the URL for this instance
|
||||||
|
"""
|
||||||
|
if callingDomain.endswith('.onion') and \
|
||||||
|
self.server.onionDomain:
|
||||||
|
instanceUrl = 'http://' + self.server.onionDomain
|
||||||
|
elif (callingDomain.endswith('.i2p') and
|
||||||
|
self.server.i2pDomain):
|
||||||
|
instanceUrl = 'http://' + self.server.i2pDomain
|
||||||
|
else:
|
||||||
|
instanceUrl = \
|
||||||
|
self.server.httpPrefix + '://' + self.server.domainFull
|
||||||
|
return instanceUrl
|
||||||
|
|
||||||
def _getheaderSignatureInput(self):
|
def _getheaderSignatureInput(self):
|
||||||
"""There are different versions of http signatures with
|
"""There are different versions of http signatures with
|
||||||
different header styles
|
different header styles
|
||||||
|
|
@ -821,7 +836,12 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
authorized: bool,
|
authorized: bool,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
baseDir: str, nickname: str, domain: str,
|
baseDir: str, nickname: str, domain: str,
|
||||||
domainFull: str) -> bool:
|
domainFull: str,
|
||||||
|
onionDomain: str, i2pDomain: str,
|
||||||
|
translate: {},
|
||||||
|
registration: bool,
|
||||||
|
systemLanguage: str,
|
||||||
|
projectVersion: str) -> bool:
|
||||||
"""This is a vestigil mastodon API for the purpose
|
"""This is a vestigil mastodon API for the purpose
|
||||||
of returning an empty result to sites like
|
of returning an empty result to sites like
|
||||||
https://mastopeek.app-dist.eu
|
https://mastopeek.app-dist.eu
|
||||||
|
|
@ -899,30 +919,37 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
sendJson = []
|
sendJson = []
|
||||||
sendJsonStr = 'masto API timelines sent'
|
sendJsonStr = 'masto API timelines sent'
|
||||||
|
|
||||||
adminNickname = getConfigParam(self.server.baseDir, 'admin')
|
adminNickname = getConfigParam(baseDir, 'admin')
|
||||||
if adminNickname and path == '/api/v1/instance':
|
if adminNickname and path == '/api/v1/instance':
|
||||||
instanceDescriptionShort = \
|
instanceDescriptionShort = \
|
||||||
getConfigParam(self.server.baseDir,
|
getConfigParam(baseDir,
|
||||||
'instanceDescriptionShort')
|
'instanceDescriptionShort')
|
||||||
if not instanceDescriptionShort:
|
if not instanceDescriptionShort:
|
||||||
instanceDescriptionShort = \
|
instanceDescriptionShort = \
|
||||||
self.server.translate['Yet another Epicyon Instance']
|
translate['Yet another Epicyon Instance']
|
||||||
instanceDescription = getConfigParam(self.server.baseDir,
|
instanceDescription = getConfigParam(baseDir,
|
||||||
'instanceDescription')
|
'instanceDescription')
|
||||||
instanceTitle = getConfigParam(self.server.baseDir,
|
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
|
||||||
'instanceTitle')
|
|
||||||
|
if callingDomain.endswith('.onion') and onionDomain:
|
||||||
|
domainFull = onionDomain
|
||||||
|
httpPrefix = 'http'
|
||||||
|
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
||||||
|
domainFull = i2pDomain
|
||||||
|
httpPrefix = 'http'
|
||||||
|
|
||||||
sendJson = \
|
sendJson = \
|
||||||
metaDataInstance(instanceTitle,
|
metaDataInstance(instanceTitle,
|
||||||
instanceDescriptionShort,
|
instanceDescriptionShort,
|
||||||
instanceDescription,
|
instanceDescription,
|
||||||
self.server.httpPrefix,
|
httpPrefix,
|
||||||
self.server.baseDir,
|
baseDir,
|
||||||
adminNickname,
|
adminNickname,
|
||||||
self.server.domain,
|
domain,
|
||||||
self.server.domainFull,
|
domainFull,
|
||||||
self.server.registration,
|
registration,
|
||||||
self.server.systemLanguage,
|
systemLanguage,
|
||||||
self.server.projectVersion)
|
projectVersion)
|
||||||
sendJsonStr = 'masto API instance metadata sent'
|
sendJsonStr = 'masto API instance metadata sent'
|
||||||
elif path.startswith('/api/v1/instance/peers'):
|
elif path.startswith('/api/v1/instance/peers'):
|
||||||
# This is just a dummy result.
|
# This is just a dummy result.
|
||||||
|
|
@ -930,7 +957,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# On a large instance you are somewhat lost in the crowd, but on
|
# 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
|
# small instances a full list of peers would convey a lot of
|
||||||
# information about the interests of a small number of accounts
|
# information about the interests of a small number of accounts
|
||||||
sendJson = ['mastodon.social', self.server.domainFull]
|
sendJson = ['mastodon.social', domainFull]
|
||||||
sendJsonStr = 'masto API peers metadata sent'
|
sendJsonStr = 'masto API peers metadata sent'
|
||||||
elif path.startswith('/api/v1/instance/activity'):
|
elif path.startswith('/api/v1/instance/activity'):
|
||||||
sendJson = []
|
sendJson = []
|
||||||
|
|
@ -961,19 +988,47 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
def _mastoApi(self, path: str, callingDomain: str,
|
def _mastoApi(self, path: str, callingDomain: str,
|
||||||
authorized: bool, httpPrefix: str,
|
authorized: bool, httpPrefix: str,
|
||||||
baseDir: str, nickname: str, domain: str,
|
baseDir: str, nickname: str, domain: str,
|
||||||
domainFull: str) -> bool:
|
domainFull: str,
|
||||||
|
onionDomain: str, i2pDomain: str,
|
||||||
|
translate: {},
|
||||||
|
registration: bool,
|
||||||
|
systemLanguage: str,
|
||||||
|
projectVersion: str) -> bool:
|
||||||
return self._mastoApiV1(path, callingDomain, authorized,
|
return self._mastoApiV1(path, callingDomain, authorized,
|
||||||
httpPrefix, baseDir, nickname, domain,
|
httpPrefix, baseDir, nickname, domain,
|
||||||
domainFull)
|
domainFull, onionDomain, i2pDomain,
|
||||||
|
translate, registration, systemLanguage,
|
||||||
|
projectVersion)
|
||||||
|
|
||||||
def _nodeinfo(self, callingDomain: str) -> bool:
|
def _nodeinfo(self, callingDomain: str) -> bool:
|
||||||
if not self.path.startswith('/nodeinfo/2.0'):
|
if not self.path.startswith('/nodeinfo/2.0'):
|
||||||
return False
|
return False
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG: nodeinfo ' + self.path)
|
print('DEBUG: nodeinfo ' + self.path)
|
||||||
|
|
||||||
|
# If we are in broch mode then don't show potentially
|
||||||
|
# sensitive metadata.
|
||||||
|
# For example, if this or allied instances are being attacked
|
||||||
|
# then numbers of accounts may be changing as people
|
||||||
|
# migrate, and that information may be useful to an adversary
|
||||||
|
brochMode = brochModeIsActive(self.server.baseDir)
|
||||||
|
|
||||||
|
nodeInfoVersion = self.server.projectVersion
|
||||||
|
if not self.server.showNodeInfoVersion or brochMode:
|
||||||
|
nodeInfoVersion = '0.0.0'
|
||||||
|
|
||||||
|
showNodeInfoAccounts = self.server.showNodeInfoAccounts
|
||||||
|
if brochMode:
|
||||||
|
showNodeInfoAccounts = False
|
||||||
|
|
||||||
|
instanceUrl = self._getInstalceUrl(callingDomain)
|
||||||
|
aboutUrl = instanceUrl + '/about'
|
||||||
|
termsOfServiceUrl = instanceUrl + '/terms'
|
||||||
info = metaDataNodeInfo(self.server.baseDir,
|
info = metaDataNodeInfo(self.server.baseDir,
|
||||||
|
aboutUrl, termsOfServiceUrl,
|
||||||
self.server.registration,
|
self.server.registration,
|
||||||
self.server.projectVersion)
|
nodeInfoVersion,
|
||||||
|
showNodeInfoAccounts)
|
||||||
if info:
|
if info:
|
||||||
msg = json.dumps(info).encode('utf-8')
|
msg = json.dumps(info).encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -1571,17 +1626,13 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/moderationaction', '')
|
usersPath = path.replace('/moderationaction', '')
|
||||||
nickname = usersPath.replace('/users/', '')
|
nickname = usersPath.replace('/users/', '')
|
||||||
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
if not isModerator(self.server.baseDir, nickname):
|
if not isModerator(self.server.baseDir, nickname):
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/moderation',
|
self._redirect_headers(actorStr + '/moderation',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
return
|
return
|
||||||
|
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
|
||||||
length = int(self.headers['Content-length'])
|
length = int(self.headers['Content-length'])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
@ -1768,10 +1819,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
debug,
|
debug,
|
||||||
self.server.recentPostsCache)
|
self.server.recentPostsCache)
|
||||||
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/moderation',
|
self._redirect_headers(actorStr + '/moderation',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -2740,7 +2787,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
path = path.split('?page=')[0]
|
path = path.split('?page=')[0]
|
||||||
|
|
||||||
usersPath = path.replace('/searchhandle', '')
|
usersPath = path.replace('/searchhandle', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
length = int(self.headers['Content-length'])
|
length = int(self.headers['Content-length'])
|
||||||
try:
|
try:
|
||||||
searchParams = self.rfile.read(length).decode('utf-8')
|
searchParams = self.rfile.read(length).decode('utf-8')
|
||||||
|
|
@ -2762,10 +2809,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return
|
return
|
||||||
if 'submitBack=' in searchParams:
|
if 'submitBack=' in searchParams:
|
||||||
# go back on search screen
|
# go back on search screen
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/' +
|
self._redirect_headers(actorStr + '/' +
|
||||||
self.server.defaultTimeline,
|
self.server.defaultTimeline,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
|
|
@ -2834,7 +2877,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
elif searchStr.startswith('!'):
|
elif searchStr.startswith('!'):
|
||||||
# your post history search
|
# your post history search
|
||||||
nickname = getNicknameFromActor(actorStr)
|
nickname = getNicknameFromActor(actorStr)
|
||||||
searchStr = searchStr.replace('!', '').strip()
|
searchStr = searchStr.replace('!', '', 1).strip()
|
||||||
historyStr = \
|
historyStr = \
|
||||||
htmlHistorySearch(self.server.cssCache,
|
htmlHistorySearch(self.server.cssCache,
|
||||||
self.server.translate,
|
self.server.translate,
|
||||||
|
|
@ -2856,7 +2899,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess,
|
self.server.allowLocalNetworkAccess,
|
||||||
self.server.themeName)
|
self.server.themeName, 'outbox')
|
||||||
if historyStr:
|
if historyStr:
|
||||||
msg = historyStr.encode('utf-8')
|
msg = historyStr.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -2865,16 +2908,47 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self._write(msg)
|
self._write(msg)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
return
|
return
|
||||||
|
elif searchStr.startswith('-'):
|
||||||
|
# bookmark search
|
||||||
|
nickname = getNicknameFromActor(actorStr)
|
||||||
|
searchStr = searchStr.replace('-', '', 1).strip()
|
||||||
|
bookmarksStr = \
|
||||||
|
htmlHistorySearch(self.server.cssCache,
|
||||||
|
self.server.translate,
|
||||||
|
baseDir,
|
||||||
|
httpPrefix,
|
||||||
|
nickname,
|
||||||
|
domain,
|
||||||
|
searchStr,
|
||||||
|
maxPostsInFeed,
|
||||||
|
pageNumber,
|
||||||
|
self.server.projectVersion,
|
||||||
|
self.server.recentPostsCache,
|
||||||
|
self.server.maxRecentPosts,
|
||||||
|
self.server.session,
|
||||||
|
self.server.cachedWebfingers,
|
||||||
|
self.server.personCache,
|
||||||
|
port,
|
||||||
|
self.server.YTReplacementDomain,
|
||||||
|
self.server.showPublishedDateOnly,
|
||||||
|
self.server.peertubeInstances,
|
||||||
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName, 'bookmarks')
|
||||||
|
if bookmarksStr:
|
||||||
|
msg = bookmarksStr.encode('utf-8')
|
||||||
|
msglen = len(msg)
|
||||||
|
self._login_headers('text/html',
|
||||||
|
msglen, callingDomain)
|
||||||
|
self._write(msg)
|
||||||
|
self.server.POSTbusy = False
|
||||||
|
return
|
||||||
elif ('@' in searchStr or
|
elif ('@' in searchStr or
|
||||||
('://' in searchStr and
|
('://' in searchStr and
|
||||||
hasUsersPath(searchStr))):
|
hasUsersPath(searchStr))):
|
||||||
if searchStr.endswith(':') or \
|
if searchStr.endswith(':') or \
|
||||||
searchStr.endswith(';') or \
|
searchStr.endswith(';') or \
|
||||||
searchStr.endswith('.'):
|
searchStr.endswith('.'):
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/search',
|
self._redirect_headers(actorStr + '/search',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -2963,10 +3037,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/search',
|
self._redirect_headers(actorStr + '/search',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3011,10 +3082,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self._write(msg)
|
self._write(msg)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
return
|
return
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
actorStr = 'http://' + onionDomain + usersPath
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorStr = 'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/' +
|
self._redirect_headers(actorStr + '/' +
|
||||||
self.server.defaultTimeline,
|
self.server.defaultTimeline,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
|
|
@ -3348,7 +3416,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/linksdata', '')
|
usersPath = path.replace('/linksdata', '')
|
||||||
usersPath = usersPath.replace('/editlinks', '')
|
usersPath = usersPath.replace('/editlinks', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
if ' boundary=' in self.headers['Content-type']:
|
if ' boundary=' in self.headers['Content-type']:
|
||||||
boundary = self.headers['Content-type'].split('boundary=')[1]
|
boundary = self.headers['Content-type'].split('boundary=')[1]
|
||||||
if ';' in boundary:
|
if ';' in boundary:
|
||||||
|
|
@ -3360,14 +3428,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if nickname:
|
if nickname:
|
||||||
editor = isEditor(baseDir, nickname)
|
editor = isEditor(baseDir, nickname)
|
||||||
if not nickname or not editor:
|
if not nickname or not editor:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
if not nickname:
|
if not nickname:
|
||||||
print('WARN: nickname not found in ' + actorStr)
|
print('WARN: nickname not found in ' + actorStr)
|
||||||
else:
|
else:
|
||||||
|
|
@ -3380,14 +3440,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum links data length exceeded ' + str(length))
|
print('Maximum links data length exceeded ' + str(length))
|
||||||
self._redirect_headers(actorStr, cookie, callingDomain)
|
self._redirect_headers(actorStr, cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3461,14 +3513,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
os.remove(TOSFilename)
|
os.remove(TOSFilename)
|
||||||
|
|
||||||
# redirect back to the default timeline
|
# redirect back to the default timeline
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/' + defaultTimeline,
|
self._redirect_headers(actorStr + '/' + defaultTimeline,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3501,7 +3545,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self._404()
|
self._404()
|
||||||
return
|
return
|
||||||
usersPath = usersPath.split('/tags/')[0]
|
usersPath = usersPath.split('/tags/')[0]
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
tagScreenStr = actorStr + '/tags/' + hashtag
|
tagScreenStr = actorStr + '/tags/' + hashtag
|
||||||
if ' boundary=' in self.headers['Content-type']:
|
if ' boundary=' in self.headers['Content-type']:
|
||||||
boundary = self.headers['Content-type'].split('boundary=')[1]
|
boundary = self.headers['Content-type'].split('boundary=')[1]
|
||||||
|
|
@ -3514,14 +3558,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if nickname:
|
if nickname:
|
||||||
editor = isEditor(baseDir, nickname)
|
editor = isEditor(baseDir, nickname)
|
||||||
if not hashtag or not editor:
|
if not hashtag or not editor:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
if not nickname:
|
if not nickname:
|
||||||
print('WARN: nickname not found in ' + actorStr)
|
print('WARN: nickname not found in ' + actorStr)
|
||||||
else:
|
else:
|
||||||
|
|
@ -3534,14 +3570,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum links data length exceeded ' + str(length))
|
print('Maximum links data length exceeded ' + str(length))
|
||||||
self._redirect_headers(tagScreenStr, cookie, callingDomain)
|
self._redirect_headers(tagScreenStr, cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3584,14 +3612,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
os.remove(categoryFilename)
|
os.remove(categoryFilename)
|
||||||
|
|
||||||
# redirect back to the default timeline
|
# redirect back to the default timeline
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(tagScreenStr,
|
self._redirect_headers(tagScreenStr,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3606,7 +3626,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/newswiredata', '')
|
usersPath = path.replace('/newswiredata', '')
|
||||||
usersPath = usersPath.replace('/editnewswire', '')
|
usersPath = usersPath.replace('/editnewswire', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
if ' boundary=' in self.headers['Content-type']:
|
if ' boundary=' in self.headers['Content-type']:
|
||||||
boundary = self.headers['Content-type'].split('boundary=')[1]
|
boundary = self.headers['Content-type'].split('boundary=')[1]
|
||||||
if ';' in boundary:
|
if ';' in boundary:
|
||||||
|
|
@ -3618,14 +3638,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if nickname:
|
if nickname:
|
||||||
moderator = isModerator(baseDir, nickname)
|
moderator = isModerator(baseDir, nickname)
|
||||||
if not nickname or not moderator:
|
if not nickname or not moderator:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
if not nickname:
|
if not nickname:
|
||||||
print('WARN: nickname not found in ' + actorStr)
|
print('WARN: nickname not found in ' + actorStr)
|
||||||
else:
|
else:
|
||||||
|
|
@ -3638,14 +3650,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum newswire data length exceeded ' + str(length))
|
print('Maximum newswire data length exceeded ' + str(length))
|
||||||
self._redirect_headers(actorStr, cookie, callingDomain)
|
self._redirect_headers(actorStr, cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3723,14 +3727,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
os.remove(newswireTrustedFilename)
|
os.remove(newswireTrustedFilename)
|
||||||
|
|
||||||
# redirect back to the default timeline
|
# redirect back to the default timeline
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/' + defaultTimeline,
|
self._redirect_headers(actorStr + '/' + defaultTimeline,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3746,7 +3742,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
update button on the citations screen
|
update button on the citations screen
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/citationsdata', '')
|
usersPath = path.replace('/citationsdata', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
nickname = getNicknameFromActor(actorStr)
|
nickname = getNicknameFromActor(actorStr)
|
||||||
|
|
||||||
citationsFilename = \
|
citationsFilename = \
|
||||||
|
|
@ -3766,14 +3762,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum citations data length exceeded ' + str(length))
|
print('Maximum citations data length exceeded ' + str(length))
|
||||||
self._redirect_headers(actorStr, cookie, callingDomain)
|
self._redirect_headers(actorStr, cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3826,14 +3814,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
citationsFile.close()
|
citationsFile.close()
|
||||||
|
|
||||||
# redirect back to the default timeline
|
# redirect back to the default timeline
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + '/newblog',
|
self._redirect_headers(actorStr + '/newblog',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -3848,7 +3828,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/newseditdata', '')
|
usersPath = path.replace('/newseditdata', '')
|
||||||
usersPath = usersPath.replace('/editnewspost', '')
|
usersPath = usersPath.replace('/editnewspost', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
if ' boundary=' in self.headers['Content-type']:
|
if ' boundary=' in self.headers['Content-type']:
|
||||||
boundary = self.headers['Content-type'].split('boundary=')[1]
|
boundary = self.headers['Content-type'].split('boundary=')[1]
|
||||||
if ';' in boundary:
|
if ';' in boundary:
|
||||||
|
|
@ -3860,14 +3840,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if nickname:
|
if nickname:
|
||||||
editorRole = isEditor(baseDir, nickname)
|
editorRole = isEditor(baseDir, nickname)
|
||||||
if not nickname or not editorRole:
|
if not nickname or not editorRole:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
if not nickname:
|
if not nickname:
|
||||||
print('WARN: nickname not found in ' + actorStr)
|
print('WARN: nickname not found in ' + actorStr)
|
||||||
else:
|
else:
|
||||||
|
|
@ -3885,14 +3857,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum news data length exceeded ' + str(length))
|
print('Maximum news data length exceeded ' + str(length))
|
||||||
if self.server.newsInstance:
|
if self.server.newsInstance:
|
||||||
self._redirect_headers(actorStr + '/tlfeatures',
|
self._redirect_headers(actorStr + '/tlfeatures',
|
||||||
|
|
@ -3979,14 +3943,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
saveJson(postJsonObject, postFilename)
|
saveJson(postJsonObject, postFilename)
|
||||||
|
|
||||||
# redirect back to the default timeline
|
# redirect back to the default timeline
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
if self.server.newsInstance:
|
if self.server.newsInstance:
|
||||||
self._redirect_headers(actorStr + '/tlfeatures',
|
self._redirect_headers(actorStr + '/tlfeatures',
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
|
|
@ -4007,7 +3963,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
"""
|
"""
|
||||||
usersPath = path.replace('/profiledata', '')
|
usersPath = path.replace('/profiledata', '')
|
||||||
usersPath = usersPath.replace('/editprofile', '')
|
usersPath = usersPath.replace('/editprofile', '')
|
||||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
actorStr = self._getInstalceUrl(callingDomain) + usersPath
|
||||||
if ' boundary=' in self.headers['Content-type']:
|
if ' boundary=' in self.headers['Content-type']:
|
||||||
boundary = self.headers['Content-type'].split('boundary=')[1]
|
boundary = self.headers['Content-type'].split('boundary=')[1]
|
||||||
if ';' in boundary:
|
if ';' in boundary:
|
||||||
|
|
@ -4016,14 +3972,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# get the nickname
|
# get the nickname
|
||||||
nickname = getNicknameFromActor(actorStr)
|
nickname = getNicknameFromActor(actorStr)
|
||||||
if not nickname:
|
if not nickname:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('WARN: nickname not found in ' + actorStr)
|
print('WARN: nickname not found in ' + actorStr)
|
||||||
self._redirect_headers(actorStr, cookie, callingDomain)
|
self._redirect_headers(actorStr, cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -4033,14 +3981,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# check that the POST isn't too large
|
# check that the POST isn't too large
|
||||||
if length > self.server.maxPostLength:
|
if length > self.server.maxPostLength:
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
print('Maximum profile data length exceeded ' +
|
print('Maximum profile data length exceeded ' +
|
||||||
str(length))
|
str(length))
|
||||||
self._redirect_headers(actorStr, cookie, callingDomain)
|
self._redirect_headers(actorStr, cookie, callingDomain)
|
||||||
|
|
@ -4685,6 +4625,24 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# on all incoming posts
|
# on all incoming posts
|
||||||
if path.startswith('/users/' +
|
if path.startswith('/users/' +
|
||||||
adminNickname + '/'):
|
adminNickname + '/'):
|
||||||
|
showNodeInfoAccounts = False
|
||||||
|
if fields.get('showNodeInfoAccounts'):
|
||||||
|
if fields['showNodeInfoAccounts'] == 'on':
|
||||||
|
showNodeInfoAccounts = True
|
||||||
|
self.server.showNodeInfoAccounts = \
|
||||||
|
showNodeInfoAccounts
|
||||||
|
setConfigParam(baseDir, "showNodeInfoAccounts",
|
||||||
|
showNodeInfoAccounts)
|
||||||
|
|
||||||
|
showNodeInfoVersion = False
|
||||||
|
if fields.get('showNodeInfoVersion'):
|
||||||
|
if fields['showNodeInfoVersion'] == 'on':
|
||||||
|
showNodeInfoVersion = True
|
||||||
|
self.server.showNodeInfoVersion = \
|
||||||
|
showNodeInfoVersion
|
||||||
|
setConfigParam(baseDir, "showNodeInfoVersion",
|
||||||
|
showNodeInfoVersion)
|
||||||
|
|
||||||
verifyAllSignatures = False
|
verifyAllSignatures = False
|
||||||
if fields.get('verifyallsignatures'):
|
if fields.get('verifyallsignatures'):
|
||||||
if fields['verifyallsignatures'] == 'on':
|
if fields['verifyallsignatures'] == 'on':
|
||||||
|
|
@ -5239,14 +5197,6 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return
|
return
|
||||||
|
|
||||||
# redirect back to the profile screen
|
# redirect back to the profile screen
|
||||||
if callingDomain.endswith('.onion') and \
|
|
||||||
onionDomain:
|
|
||||||
actorStr = \
|
|
||||||
'http://' + onionDomain + usersPath
|
|
||||||
elif (callingDomain.endswith('.i2p') and
|
|
||||||
i2pDomain):
|
|
||||||
actorStr = \
|
|
||||||
'http://' + i2pDomain + usersPath
|
|
||||||
self._redirect_headers(actorStr + redirectPath,
|
self._redirect_headers(actorStr + redirectPath,
|
||||||
cookie, callingDomain)
|
cookie, callingDomain)
|
||||||
self.server.POSTbusy = False
|
self.server.POSTbusy = False
|
||||||
|
|
@ -6219,12 +6169,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber)
|
'?page=' + str(pageNumber)
|
||||||
|
|
@ -6267,11 +6212,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
del self.server.iconsCache['repeat.png']
|
del self.server.iconsCache['repeat.png']
|
||||||
self._postToOutboxThread(announceJson)
|
self._postToOutboxThread(announceJson)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + '?page=' + \
|
actorAbsolute + '/' + timelineStr + '?page=' + \
|
||||||
str(pageNumber) + timelineBookmark
|
str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6318,11 +6259,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + '?page=' + \
|
actorAbsolute + '/' + timelineStr + '?page=' + \
|
||||||
str(pageNumber)
|
str(pageNumber)
|
||||||
|
|
@ -6361,11 +6298,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
del self.server.iconsCache['repeat_inactive.png']
|
del self.server.iconsCache['repeat_inactive.png']
|
||||||
self._postToOutboxThread(newUndoAnnounce)
|
self._postToOutboxThread(newUndoAnnounce)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + '?page=' + \
|
actorAbsolute + '/' + timelineStr + '?page=' + \
|
||||||
str(pageNumber) + timelineBookmark
|
str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6623,12 +6556,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber) + timelineBookmark
|
'?page=' + str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6678,12 +6606,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# send out the like to followers
|
# send out the like to followers
|
||||||
self._postToOutbox(likeJson, self.server.projectVersion)
|
self._postToOutbox(likeJson, self.server.projectVersion)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and i2pDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber) + timelineBookmark
|
'?page=' + str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6730,12 +6653,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif (callingDomain.endswith('.i2p') and onionDomain):
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber)
|
'?page=' + str(pageNumber)
|
||||||
|
|
@ -6785,11 +6703,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# send out the undo like to followers
|
# send out the undo like to followers
|
||||||
self._postToOutbox(undoLikeJson, self.server.projectVersion)
|
self._postToOutbox(undoLikeJson, self.server.projectVersion)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber) + timelineBookmark
|
'?page=' + str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6837,12 +6751,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber)
|
'?page=' + str(pageNumber)
|
||||||
|
|
@ -6881,12 +6790,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
del self.server.iconsCache['bookmark.png']
|
del self.server.iconsCache['bookmark.png']
|
||||||
# self._postToOutbox(bookmarkJson, self.server.projectVersion)
|
# self._postToOutbox(bookmarkJson, self.server.projectVersion)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber) + timelineBookmark
|
'?page=' + str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -6933,12 +6837,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
if not self.postToNickname:
|
if not self.postToNickname:
|
||||||
print('WARN: unable to find nickname in ' + actor)
|
print('WARN: unable to find nickname in ' + actor)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber)
|
'?page=' + str(pageNumber)
|
||||||
|
|
@ -6977,12 +6876,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
del self.server.iconsCache['bookmark_inactive.png']
|
del self.server.iconsCache['bookmark_inactive.png']
|
||||||
# self._postToOutbox(undoBookmarkJson, self.server.projectVersion)
|
# self._postToOutbox(undoBookmarkJson, self.server.projectVersion)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
actorAbsolute = \
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
httpPrefix + '://' + domainFull + actor
|
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
actorPathStr = \
|
actorPathStr = \
|
||||||
actorAbsolute + '/' + timelineStr + \
|
actorAbsolute + '/' + timelineStr + \
|
||||||
'?page=' + str(pageNumber) + timelineBookmark
|
'?page=' + str(pageNumber) + timelineBookmark
|
||||||
|
|
@ -7587,11 +7481,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
return True
|
return True
|
||||||
actor = path.replace('/skills', '')
|
actor = path.replace('/skills', '')
|
||||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
actorAbsolute = self._getInstalceUrl(callingDomain) + actor
|
||||||
if callingDomain.endswith('.onion') and onionDomain:
|
|
||||||
actorAbsolute = 'http://' + onionDomain + actor
|
|
||||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
|
||||||
actorAbsolute = 'http://' + i2pDomain + actor
|
|
||||||
self._redirect_headers(actorAbsolute, cookie, callingDomain)
|
self._redirect_headers(actorAbsolute, cookie, callingDomain)
|
||||||
self.server.GETbusy = False
|
self.server.GETbusy = False
|
||||||
return True
|
return True
|
||||||
|
|
@ -10718,7 +10608,13 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.baseDir,
|
self.server.baseDir,
|
||||||
self.authorizedNickname,
|
self.authorizedNickname,
|
||||||
self.server.domain,
|
self.server.domain,
|
||||||
self.server.domainFull):
|
self.server.domainFull,
|
||||||
|
self.server.onionDomain,
|
||||||
|
self.server.i2pDomain,
|
||||||
|
self.server.translate,
|
||||||
|
self.server.registration,
|
||||||
|
self.server.systemLanguage,
|
||||||
|
self.server.projectVersion):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._benchmarkGETtimings(GETstartTime, GETtimings,
|
self._benchmarkGETtimings(GETstartTime, GETtimings,
|
||||||
|
|
@ -14743,7 +14639,9 @@ def loadTokens(baseDir: str, tokensDict: {}, tokensLookup: {}) -> None:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def runDaemon(brochMode: bool,
|
def runDaemon(showNodeInfoAccounts: bool,
|
||||||
|
showNodeInfoVersion: bool,
|
||||||
|
brochMode: bool,
|
||||||
verifyAllSignatures: bool,
|
verifyAllSignatures: bool,
|
||||||
sendThreadsTimeoutMins: int,
|
sendThreadsTimeoutMins: int,
|
||||||
dormantMonths: int,
|
dormantMonths: int,
|
||||||
|
|
@ -14812,6 +14710,9 @@ def runDaemon(brochMode: bool,
|
||||||
print('serverAddress: ' + str(serverAddress))
|
print('serverAddress: ' + str(serverAddress))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
httpd.showNodeInfoAccounts = showNodeInfoAccounts
|
||||||
|
httpd.showNodeInfoVersion = showNodeInfoVersion
|
||||||
|
|
||||||
# ASCII/ANSI text banner used in shell browsers, such as Lynx
|
# ASCII/ANSI text banner used in shell browsers, such as Lynx
|
||||||
httpd.textModeBanner = getTextModeBanner(baseDir)
|
httpd.textModeBanner = getTextModeBanner(baseDir)
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -7,3 +7,12 @@
|
||||||
يؤدي تحديد **الشعار في الجزء العلوي** من الشاشة إلى التبديل بين عرض المخطط الزمني وملف التعريف الخاص بك.
|
يؤدي تحديد **الشعار في الجزء العلوي** من الشاشة إلى التبديل بين عرض المخطط الزمني وملف التعريف الخاص بك.
|
||||||
|
|
||||||
لن يتم تحديث الشاشة تلقائيًا عند وصول المنشورات ، لذا استخدم **F5** أو زر البريد الوارد للتحديث.
|
لن يتم تحديث الشاشة تلقائيًا عند وصول المنشورات ، لذا استخدم **F5** أو زر البريد الوارد للتحديث.
|
||||||
|
|
||||||
|
#### طقوس المرور
|
||||||
|
تدربك ثقافة الشركة على الرغبة في الحصول على أكبر عدد من المتابعين والإعجابات - للبحث عن الشهرة الشخصية والتفاعلات السطحية التي تثير الغضب لجذب الانتباه.
|
||||||
|
|
||||||
|
لذلك إذا كنت قادمًا من تلك الثقافة ، فيرجى العلم أن هذا نوع مختلف من النظام مع مجموعة مختلفة جدًا من التوقعات.
|
||||||
|
|
||||||
|
ليس من الضروري وجود الكثير من المتابعين ، وغالبًا ما يكون غير مرغوب فيه. قد يحظرك الناس ، ولا بأس بذلك. لا أحد لديه الحق في جمهور. إذا قام شخص ما بحظرك فأنت لا تخضع للرقابة. يمارس الناس فقط حريتهم في الارتباط بمن يرغبون فيه.
|
||||||
|
|
||||||
|
من المتوقع أن تكون معايير السلوك الشخصي أفضل مما هي عليه في أنظمة الشركات. سلوكك له أيضًا عواقب على سمعة هذه الحالة. إذا كنت تتصرف بطريقة متهورة تتعارض مع شروط الخدمة ، فقد يتم تعليق حسابك أو إزالته.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Utilitzeu la icona de **lupa** 🔍 per cercar manetes fedivers i seguir les per
|
||||||
Si seleccioneu el **bàner a la part superior** de la pantalla es canvia entre la visualització de la línia de temps i el vostre perfil.
|
Si seleccioneu el **bàner a la part superior** de la pantalla es canvia entre la visualització de la línia de temps i el vostre perfil.
|
||||||
|
|
||||||
La pantalla no s'actualitzarà automàticament quan arribin les publicacions, així que utilitzeu **F5** o el botó **Safata d'entrada** per actualitzar.
|
La pantalla no s'actualitzarà automàticament quan arribin les publicacions, així que utilitzeu **F5** o el botó **Safata d'entrada** per actualitzar.
|
||||||
|
|
||||||
|
#### Ritu de pas
|
||||||
|
La cultura corporativa us capacita per desitjar el màxim nombre de seguidors i gustos: per buscar fama personal i interaccions poc profundes i indignants per cridar l'atenció.
|
||||||
|
|
||||||
|
Per tant, si proveniu d’aquesta cultura, tingueu en compte que es tracta d’un tipus de sistema diferent amb un conjunt d’expectatives molt diferents.
|
||||||
|
|
||||||
|
No és necessari tenir molts seguidors i sovint no és desitjable. És possible que la gent us bloquegi i això està bé. Ningú no té dret a un públic. Si algú et bloqueja, no et censuraran. La gent només exerceix la seva llibertat per associar-se amb qui vulgui.
|
||||||
|
|
||||||
|
S'espera que els estàndards de comportament personal siguin millors que en els sistemes corporatius. El vostre comportament també té conseqüències per a la reputació d'aquesta instància. Si us comporteu de manera desmesurada que va en contra de les condicions del servei, el vostre compte es pot suspendre o eliminar.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Defnyddiwch yr eicon **chwyddwydr** 🔍 i chwilio am ddolenni bwydo a dilyn pob
|
||||||
Mae dewis y faner **ar frig** y sgrin yn newid rhwng yr olygfa llinell amser a'ch proffil.
|
Mae dewis y faner **ar frig** y sgrin yn newid rhwng yr olygfa llinell amser a'ch proffil.
|
||||||
|
|
||||||
Ni fydd y sgrin yn adnewyddu'n awtomatig pan fydd pyst yn cyrraedd, felly defnyddiwch **F5** neu'r botwm **Mewnflwch** i adnewyddu.
|
Ni fydd y sgrin yn adnewyddu'n awtomatig pan fydd pyst yn cyrraedd, felly defnyddiwch **F5** neu'r botwm **Mewnflwch** i adnewyddu.
|
||||||
|
|
||||||
|
#### Defod y Tocyn
|
||||||
|
Mae diwylliant corfforaethol yn eich hyfforddi i fod eisiau'r nifer uchaf o ddilynwyr a hoff bethau - i geisio enwogrwydd personol a rhyngweithio bas, sy'n achosi dicter, i fachu sylw.
|
||||||
|
|
||||||
|
Felly os ydych chi'n dod o'r diwylliant hwnnw, byddwch yn ymwybodol bod hon yn fath wahanol o system gyda set wahanol iawn o ddisgwyliadau.
|
||||||
|
|
||||||
|
Nid oes angen cael llawer o ddilynwyr, ac yn aml mae'n annymunol. Efallai y bydd pobl yn eich rhwystro chi, ac mae hynny'n iawn. Nid oes gan neb hawl i gynulleidfa. Os bydd rhywun yn eich blocio yna nid ydych chi'n cael eich sensro. Mae pobl yn arfer eu rhyddid i gysylltu â phwy bynnag maen nhw'n dymuno.
|
||||||
|
|
||||||
|
Disgwylir i safonau ymddygiad personol fod yn well nag yn y systemau corfforaethol. Mae gan eich ymddygiad ganlyniadau i enw da'r achos hwn hefyd. Os ydych chi'n ymddwyn mewn modd anystyriol sy'n mynd yn groes i'r telerau gwasanaeth yna gellir atal neu ddileu eich cyfrif.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Use the **magnifier** icon 🔍 to search for fediverse handles and follow peopl
|
||||||
Selecting the **banner at the top** of the screen switches between timeline view and your profile.
|
Selecting the **banner at the top** of the screen switches between timeline view and your profile.
|
||||||
|
|
||||||
The screen will not automatically refresh when posts arrive, so use **F5** or the **Inbox** button to refresh.
|
The screen will not automatically refresh when posts arrive, so use **F5** or the **Inbox** button to refresh.
|
||||||
|
|
||||||
|
#### Rite of Passage
|
||||||
|
Corporate culture trains you to want the maximum number of followers and likes - to seek personal fame and shallow, outrage-inducing interactions to grab attention.
|
||||||
|
|
||||||
|
So if you are coming from that culture, please be aware that this is a different type of system with a very different set of expectations.
|
||||||
|
|
||||||
|
Having a lot of followers is not necessary, and often it's undesirable. People may block you, and that's ok. Nobody has a right to an audience. If someone blocks you then you're not being censored. People are just exercising their freedom to associate with whoever they wish.
|
||||||
|
|
||||||
|
Standards of personal behavior are expected to be better than in the corporate systems. Your behavior also has consequences for the reputation of this instance. If you behave in an inconsiderate manner which goes against the terms of service then your account may be suspended or removed.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Utilice el icono de **lupa** 🔍 para buscar identificadores de fediverse y seg
|
||||||
Al seleccionar el **banner en la parte superior** de la pantalla, se cambia entre la vista de línea de tiempo y su perfil.
|
Al seleccionar el **banner en la parte superior** de la pantalla, se cambia entre la vista de línea de tiempo y su perfil.
|
||||||
|
|
||||||
La pantalla no se actualizará automáticamente cuando lleguen las publicaciones, así que use **F5** o el botón **Bandeja de entrada** para actualizar.
|
La pantalla no se actualizará automáticamente cuando lleguen las publicaciones, así que use **F5** o el botón **Bandeja de entrada** para actualizar.
|
||||||
|
|
||||||
|
#### Rito de paso
|
||||||
|
La cultura corporativa te entrena para querer el máximo número de seguidores y me gusta, para buscar fama personal e interacciones superficiales e indignantes para llamar la atención.
|
||||||
|
|
||||||
|
Entonces, si viene de esa cultura, tenga en cuenta que este es un tipo diferente de sistema con un conjunto de expectativas muy diferente.
|
||||||
|
|
||||||
|
No es necesario tener muchos seguidores y, a menudo, no es deseable. Es posible que la gente te bloquee, y eso está bien. Nadie tiene derecho a una audiencia. Si alguien te bloquea, no estás siendo censurado. La gente simplemente está ejerciendo su libertad para asociarse con quien quiera.
|
||||||
|
|
||||||
|
Se espera que los estándares de comportamiento personal sean mejores que los de los sistemas corporativos. Su comportamiento también tiene consecuencias para la reputación de esta instancia. Si se comporta de manera desconsiderada que va en contra de los términos de servicio, su cuenta puede ser suspendida o eliminada.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Utilisez l'icône **loupe** 🔍 pour rechercher des poignées fediverse et suiv
|
||||||
La sélection de la **bannière en haut** de l'écran bascule entre la vue chronologique et votre profil.
|
La sélection de la **bannière en haut** de l'écran bascule entre la vue chronologique et votre profil.
|
||||||
|
|
||||||
L'écran ne s'actualisera pas automatiquement à l'arrivée des messages, utilisez donc **F5** ou le bouton **Boîte de réception** pour actualiser.
|
L'écran ne s'actualisera pas automatiquement à l'arrivée des messages, utilisez donc **F5** ou le bouton **Boîte de réception** pour actualiser.
|
||||||
|
|
||||||
|
#### Rite de passage
|
||||||
|
La culture d'entreprise vous entraîne à vouloir le maximum de followers et de likes - à rechercher une renommée personnelle et des interactions superficielles et indignées pour attirer l'attention.
|
||||||
|
|
||||||
|
Donc, si vous venez de cette culture, sachez qu'il s'agit d'un type de système différent avec un ensemble d'attentes très différent.
|
||||||
|
|
||||||
|
Avoir beaucoup d'adeptes n'est pas nécessaire et souvent indésirable. Les gens peuvent vous bloquer, et ce n'est pas grave. Personne n'a droit à une audience. Si quelqu'un vous bloque, vous n'êtes pas censuré. Les gens exercent simplement leur liberté de s'associer avec qui ils veulent.
|
||||||
|
|
||||||
|
On s'attend à ce que les normes de comportement personnel soient meilleures que dans les systèmes d'entreprise. Votre comportement a également des conséquences sur la réputation de cette instance. Si vous vous comportez d'une manière inconsidérée qui va à l'encontre des conditions d'utilisation, votre compte peut être suspendu ou supprimé.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Tá tú réidh anois chun Epicyon a úsáid. Is spás sóisialta measartha é se
|
||||||
Ag roghnú an bhratach **ag barr** na lasca scáileáin idir amharc amlíne agus do phróifíl.
|
Ag roghnú an bhratach **ag barr** na lasca scáileáin idir amharc amlíne agus do phróifíl.
|
||||||
|
|
||||||
Ní dhéanfaidh an scáileán athnuachan go huathoibríoch nuair a thiocfaidh na poist, mar sin bain úsáid as **F5** nó an cnaipe **Bosca Isteach** chun athnuachan a dhéanamh.
|
Ní dhéanfaidh an scáileán athnuachan go huathoibríoch nuair a thiocfaidh na poist, mar sin bain úsáid as **F5** nó an cnaipe **Bosca Isteach** chun athnuachan a dhéanamh.
|
||||||
|
|
||||||
|
#### Deasghnáth an Phasáiste
|
||||||
|
Cuireann an cultúr corparáideach oiliúint ort go dteastaíonn uait an líon is mó leantóirí agus a leithéidí - clú agus cáil phearsanta agus idirghníomhaíochtaí éadomhain, spreagtha a lorg chun aird a tharraingt.
|
||||||
|
|
||||||
|
Mar sin má tá tú ag teacht ón gcultúr sin, bí ar an eolas gur cineál difriúil córais é seo le tacar ionchais an-difriúil.
|
||||||
|
|
||||||
|
Ní gá go leor leantóirí a bheith agat, agus go minic bíonn sé neamh-inmhianaithe. Féadfaidh daoine bac a chur ort, agus tá sé sin ceart go leor. Níl sé de cheart ag aon duine lucht féachana a fháil. Má chuireann duine bac ort níl cinsireacht á dhéanamh ort. Níl ach a saoirse á fheidhmiú ag daoine chun caidreamh a dhéanamh le cibé duine is mian leo.
|
||||||
|
|
||||||
|
Meastar go mbeidh caighdeáin iompraíochta pearsanta níos fearr ná sna córais chorparáideacha. Tá iarmhairtí ag d’iompar freisin ar cháil an cháis seo. Má iompraíonn tú ar bhealach neamhfhreagrach a théann i gcoinne na dtéarmaí seirbhíse ansin féadfar do chuntas a chur ar fionraí nó a bhaint.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@
|
||||||
समय दृश्य और आपकी प्रोफ़ाइल के बीच स्क्रीन स्विच के शीर्ष **पर स्थित** बैनर का चयन करना।
|
समय दृश्य और आपकी प्रोफ़ाइल के बीच स्क्रीन स्विच के शीर्ष **पर स्थित** बैनर का चयन करना।
|
||||||
|
|
||||||
पोस्ट आने पर स्क्रीन अपने आप रिफ्रेश नहीं होगी, इसलिए रीफ्रेश करने के लिए **F5** या **इनबॉक्स** बटन का उपयोग करें।
|
पोस्ट आने पर स्क्रीन अपने आप रिफ्रेश नहीं होगी, इसलिए रीफ्रेश करने के लिए **F5** या **इनबॉक्स** बटन का उपयोग करें।
|
||||||
|
|
||||||
|
#### यादगार घटना
|
||||||
|
कॉरपोरेट कल्चर आपको अधिक से अधिक संख्या में अनुयायियों और पसंदों को प्राप्त करने के लिए प्रशिक्षित करता है - ध्यान आकर्षित करने के लिए व्यक्तिगत प्रसिद्धि और उथले, नाराजगी-उत्प्रेरण बातचीत।
|
||||||
|
|
||||||
|
इसलिए यदि आप उस संस्कृति से आ रहे हैं, तो कृपया ध्यान रखें कि यह एक अलग प्रकार की प्रणाली है जिसमें बहुत अलग अपेक्षाएं हैं।
|
||||||
|
|
||||||
|
बहुत सारे अनुयायी होना आवश्यक नहीं है, और अक्सर यह अवांछनीय है। लोग आपको ब्लॉक कर सकते हैं, और यह ठीक है। किसी को भी एक दर्शक का अधिकार नहीं है। अगर कोई आपको ब्लॉक करता है तो आपको सेंसर नहीं किया जा रहा है। लोग बस अपनी स्वतंत्रता का प्रयोग कर रहे हैं कि वे जो चाहें करें।
|
||||||
|
|
||||||
|
व्यक्तिगत व्यवहार के मानक कॉर्पोरेट सिस्टम की तुलना में बेहतर होने की उम्मीद है। इस उदाहरण की प्रतिष्ठा के लिए आपके व्यवहार के परिणाम भी हैं। यदि आप एक असंगत तरीके से व्यवहार करते हैं जो सेवा की शर्तों के खिलाफ जाता है तो आपका खाता निलंबित या हटाया जा सकता है।
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Usa l'icona **lente d'ingrandimento** 🔍 per cercare gli handle di fediverse e
|
||||||
Selezionando il **banner nella parte superiore** dello schermo si passa dalla visualizzazione della sequenza temporale al tuo profilo.
|
Selezionando il **banner nella parte superiore** dello schermo si passa dalla visualizzazione della sequenza temporale al tuo profilo.
|
||||||
|
|
||||||
La schermata non si aggiornerà automaticamente all'arrivo dei post, quindi utilizza **F5** o il pulsante **Posta in arrivo** per aggiornare.
|
La schermata non si aggiornerà automaticamente all'arrivo dei post, quindi utilizza **F5** o il pulsante **Posta in arrivo** per aggiornare.
|
||||||
|
|
||||||
|
#### Rito di passaggio
|
||||||
|
La cultura aziendale ti insegna a desiderare il numero massimo di follower e Mi piace, a cercare la fama personale e interazioni superficiali e indignate per attirare l'attenzione.
|
||||||
|
|
||||||
|
Quindi, se vieni da quella cultura, tieni presente che questo è un tipo diverso di sistema con un insieme di aspettative molto diverso.
|
||||||
|
|
||||||
|
Avere molti follower non è necessario e spesso è indesiderabile. Le persone potrebbero bloccarti, e va bene. Nessuno ha diritto a un pubblico. Se qualcuno ti blocca, non verrai censurato. Le persone stanno solo esercitando la loro libertà di associarsi con chi desiderano.
|
||||||
|
|
||||||
|
Gli standard di comportamento personale dovrebbero essere migliori rispetto ai sistemi aziendali. Il tuo comportamento ha anche conseguenze sulla reputazione di questa istanza. Se ti comporti in modo sconsiderato che va contro i termini di servizio, il tuo account potrebbe essere sospeso o rimosso.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@
|
||||||
画面の上部にある **バナー** を選択すると、タイムラインビューとプロファイルが切り替わります。
|
画面の上部にある **バナー** を選択すると、タイムラインビューとプロファイルが切り替わります。
|
||||||
|
|
||||||
投稿が到着しても画面は自動的に更新されないため、 **F5** または **受信トレイ** ボタンを使用して更新してください。
|
投稿が到着しても画面は自動的に更新されないため、 **F5** または **受信トレイ** ボタンを使用して更新してください。
|
||||||
|
|
||||||
|
#### 通過儀礼
|
||||||
|
企業文化は、最大数のフォロワーや好きな人を求め、個人的な名声と浅い、怒りを誘発する相互作用を求めて注目を集めるように訓練します。
|
||||||
|
|
||||||
|
したがって、その文化から来ている場合、これは非常に異なる一連の期待を持つ異なるタイプのシステムであることに注意してください。
|
||||||
|
|
||||||
|
多くのフォロワーを持つ必要はなく、多くの場合、それは望ましくありません。 人々があなたをブロックするかもしれません、そしてそれは大丈夫です。 誰も聴衆に対する権利を持っていません。 誰かがあなたをブロックした場合、あなたは検閲されていません。 人々は、彼らが望む誰とでも交際する自由を行使しているだけです。
|
||||||
|
|
||||||
|
個人の行動基準は、企業システムよりも優れていると期待されています。 あなたの行動は、このインスタンスの評判にも影響を及ぼします。 利用規約に違反する軽率な行動をとった場合、アカウントが停止または削除される可能性があります。
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Hûn niha amade ne ku dest bi karanîna Epicyon bikin. Ev cîhek civakî ya nerm
|
||||||
Hilbijartina **pankarta li jor** a switches-ekranê di navbera dîtina demjimêr û profîla we de.
|
Hilbijartina **pankarta li jor** a switches-ekranê di navbera dîtina demjimêr û profîla we de.
|
||||||
|
|
||||||
Dema ku şande tên dîmender dê bixweber nûve nebe, ji ber vê yekê **F5** an bişkoja **Inbox** ji bo nûvekirinê bikar bînin.
|
Dema ku şande tên dîmender dê bixweber nûve nebe, ji ber vê yekê **F5** an bişkoja **Inbox** ji bo nûvekirinê bikar bînin.
|
||||||
|
|
||||||
|
#### Rêûresma Derbasbûnê
|
||||||
|
Çanda pargîdaniyê we perwerde dike ku hûn jimara herî zêde şopîner û hezên xwe bixwazin - li navdariyek kesane û têkiliyên kûr, hêrs-lêgerîn digerin da ku balê bikişînin.
|
||||||
|
|
||||||
|
Ji ber vê yekê heke hûn ji wê çandê têne, ji kerema xwe hay ji xwe hebin ku ev pergalek celebek cuda ye ku bi bendewariyek pir cûda ye.
|
||||||
|
|
||||||
|
Hebûna gelek şagirtan ne hewce ye, û pir caran ew nexwaze. Mirov dikare we bloke bike, û ew baş e. Mafê kesî tune ku guhdar bike. Ger kesek we bloke bike wê hingê hûn nayên sansur kirin. Mirov tenê azadiya xwe ya ku bi kî bixwaze re têkildar dibe bikar tîne.
|
||||||
|
|
||||||
|
Tê payîn ku standardên tevgera kesane ji pergalên pargîdaniyê çêtir in. Reftara we ji bo navûdengê vê nimûneyê jî encam dide. Heke hûn bi rengek bêhesib tevdigerin ku li dijî şertên karûbarê ye wê hingê dibe ku hesabê we were sekinandin an rakirin.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Use the **magnifier** icon 🔍 to search for fediverse handles and follow peopl
|
||||||
Selecting the **banner at the top** of the screen switches between timeline view and your profile.
|
Selecting the **banner at the top** of the screen switches between timeline view and your profile.
|
||||||
|
|
||||||
The screen will not automatically refresh when posts arrive, so use **F5** or the **Inbox** button to refresh.
|
The screen will not automatically refresh when posts arrive, so use **F5** or the **Inbox** button to refresh.
|
||||||
|
|
||||||
|
#### Rite of Passage
|
||||||
|
Corporate culture trains you to want the maximum number of followers and likes - to seek personal fame and shallow, outrage-inducing interactions to grab attention.
|
||||||
|
|
||||||
|
So if you are coming from that culture, please be aware that this is a different type of system with a very different set of expectations.
|
||||||
|
|
||||||
|
Having a lot of followers is not necessary, and often it's undesirable. People may block you, and that's ok. Nobody has a right to an audience. If someone blocks you then you're not being censored. People are just exercising their freedom to associate with whoever they wish.
|
||||||
|
|
||||||
|
Standards of personal behavior are expected to be better than in the corporate systems. Your behavior also has consequences for the reputation of this instance. If you behave in an inconsiderate manner which goes against the terms of service then your account may be suspended or removed.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@ Use o ícone de **lupa** 🔍 para pesquisar as alças do fediverse e seguir pes
|
||||||
Selecionar o **banner na parte superior** da tela alterna entre a visualização da linha do tempo e seu perfil.
|
Selecionar o **banner na parte superior** da tela alterna entre a visualização da linha do tempo e seu perfil.
|
||||||
|
|
||||||
A tela não será atualizada automaticamente quando as postagens chegarem, então use **F5** ou o botão **Caixa de entrada** para atualizar.
|
A tela não será atualizada automaticamente quando as postagens chegarem, então use **F5** ou o botão **Caixa de entrada** para atualizar.
|
||||||
|
|
||||||
|
#### Rito de passagem
|
||||||
|
A cultura corporativa treina você a querer o número máximo de seguidores e curtidas - a buscar fama pessoal e interações superficiais que induzem à indignação para chamar a atenção.
|
||||||
|
|
||||||
|
Portanto, se você vem dessa cultura, saiba que esse é um tipo diferente de sistema, com um conjunto de expectativas muito diferente.
|
||||||
|
|
||||||
|
Não é necessário ter muitos seguidores e, muitas vezes, é indesejável. As pessoas podem bloquear você, e tudo bem. Ninguém tem direito a audiência. Se alguém bloqueia você, você não está sendo censurado. As pessoas estão apenas exercendo sua liberdade de se associar com quem quiserem.
|
||||||
|
|
||||||
|
Espera-se que os padrões de comportamento pessoal sejam melhores do que os sistemas corporativos. Seu comportamento também tem consequências para a reputação desta instância. Se você se comportar de maneira imprudente que vá contra os termos de serviço, sua conta poderá ser suspensa ou removida.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@
|
||||||
При выборе **баннера вверху** экрана выполняется переключение между представлением временной шкалы и вашим профилем.
|
При выборе **баннера вверху** экрана выполняется переключение между представлением временной шкалы и вашим профилем.
|
||||||
|
|
||||||
Экран не обновляется автоматически при поступлении сообщений, поэтому используйте **F5** или кнопку **Входящие** для обновления.
|
Экран не обновляется автоматически при поступлении сообщений, поэтому используйте **F5** или кнопку **Входящие** для обновления.
|
||||||
|
|
||||||
|
#### Обряд посвящения
|
||||||
|
Корпоративная культура учит вас стремиться к максимальному количеству подписчиков и лайков - стремиться к личной славе и поверхностным, вызывающим возмущение взаимодействиям, чтобы привлечь внимание.
|
||||||
|
|
||||||
|
Так что, если вы происходите из этой культуры, имейте в виду, что это другой тип системы с совершенно другим набором ожиданий.
|
||||||
|
|
||||||
|
Не обязательно иметь много подписчиков, а зачастую и нежелательно. Люди могут заблокировать вас, и это нормально. Никто не имеет права на аудиенцию. Если кто-то вас блокирует, значит, вы не подвергаетесь цензуре. Люди просто пользуются своей свободой общаться с кем хотят.
|
||||||
|
|
||||||
|
Ожидается, что стандарты личного поведения будут лучше, чем в корпоративных системах. Ваше поведение также влияет на репутацию этого экземпляра. Если вы ведете себя невнимательно, что противоречит условиям обслуживания, ваша учетная запись может быть приостановлена или удалена.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,12 @@
|
||||||
选择屏幕顶部的横幅广告可在时间轴视图和个人资料之间切换。
|
选择屏幕顶部的横幅广告可在时间轴视图和个人资料之间切换。
|
||||||
|
|
||||||
帖子到达时,屏幕不会自动刷新,因此请使用F5或“收件箱”按钮刷新。
|
帖子到达时,屏幕不会自动刷新,因此请使用F5或“收件箱”按钮刷新。
|
||||||
|
|
||||||
|
#### 通行礼
|
||||||
|
企业文化训练您想要最大数量的追随者和喜欢的人-寻求个人名望和肤浅,激怒的互动来吸引注意力。
|
||||||
|
|
||||||
|
因此,如果您来自这种文化,请注意,这是另一种类型的系统,具有不同的期望值。
|
||||||
|
|
||||||
|
拥有大量的追随者不是必需的,而且通常是不可取的。 人们可能会阻止您,没关系。 没有人有听众的权利。 如果有人阻止了您,那么您将不会受到审查。 人们只是在行使与任何希望的人交往的自由。
|
||||||
|
|
||||||
|
个人行为标准有望比公司系统更好。 您的行为也会对该实例的声誉产生影响。 如果您的行为举止粗鲁,违反了服务条款,那么您的帐户可能会被暂停或删除。
|
||||||
|
|
|
||||||
|
|
@ -341,7 +341,7 @@ a:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
.profileHeader .title {
|
.profileHeader .title {
|
||||||
border-radius: 50%;
|
border-radius: 10%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
left: 25px;
|
left: 25px;
|
||||||
|
|
|
||||||
24
epicyon.py
24
epicyon.py
|
|
@ -322,6 +322,16 @@ parser.add_argument("--brochMode",
|
||||||
type=str2bool, nargs='?',
|
type=str2bool, nargs='?',
|
||||||
const=True, default=False,
|
const=True, default=False,
|
||||||
help="Enable broch mode")
|
help="Enable broch mode")
|
||||||
|
parser.add_argument("--nodeinfoaccounts",
|
||||||
|
dest='showNodeInfoAccounts',
|
||||||
|
type=str2bool, nargs='?',
|
||||||
|
const=True, default=False,
|
||||||
|
help="Show numbers of accounts within nodeinfo metadata")
|
||||||
|
parser.add_argument("--nodeinfoversion",
|
||||||
|
dest='showNodeInfoVersion',
|
||||||
|
type=str2bool, nargs='?',
|
||||||
|
const=True, default=False,
|
||||||
|
help="Show version number within nodeinfo metadata")
|
||||||
parser.add_argument("--noKeyPress",
|
parser.add_argument("--noKeyPress",
|
||||||
dest='noKeyPress',
|
dest='noKeyPress',
|
||||||
type=str2bool, nargs='?',
|
type=str2bool, nargs='?',
|
||||||
|
|
@ -2600,6 +2610,16 @@ brochMode = \
|
||||||
if brochMode is not None:
|
if brochMode is not None:
|
||||||
args.brochMode = bool(brochMode)
|
args.brochMode = bool(brochMode)
|
||||||
|
|
||||||
|
showNodeInfoAccounts = \
|
||||||
|
getConfigParam(baseDir, 'showNodeInfoAccounts')
|
||||||
|
if showNodeInfoAccounts is not None:
|
||||||
|
args.showNodeInfoAccounts = bool(showNodeInfoAccounts)
|
||||||
|
|
||||||
|
showNodeInfoVersion = \
|
||||||
|
getConfigParam(baseDir, 'showNodeInfoVersion')
|
||||||
|
if showNodeInfoVersion is not None:
|
||||||
|
args.showNodeInfoVersion = bool(showNodeInfoVersion)
|
||||||
|
|
||||||
YTDomain = getConfigParam(baseDir, 'youtubedomain')
|
YTDomain = getConfigParam(baseDir, 'youtubedomain')
|
||||||
if YTDomain:
|
if YTDomain:
|
||||||
if '://' in YTDomain:
|
if '://' in YTDomain:
|
||||||
|
|
@ -2614,7 +2634,9 @@ if setTheme(baseDir, themeName, domain,
|
||||||
print('Theme set to ' + themeName)
|
print('Theme set to ' + themeName)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
runDaemon(args.brochMode,
|
runDaemon(args.showNodeInfoAccounts,
|
||||||
|
args.showNodeInfoVersion,
|
||||||
|
args.brochMode,
|
||||||
args.verifyAllSignatures,
|
args.verifyAllSignatures,
|
||||||
args.sendThreadsTimeoutMins,
|
args.sendThreadsTimeoutMins,
|
||||||
args.dormantMonths,
|
args.dormantMonths,
|
||||||
|
|
|
||||||
38
inbox.py
38
inbox.py
|
|
@ -2973,8 +2973,42 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
if hasValidContext(originalJson):
|
if hasValidContext(originalJson):
|
||||||
hasJsonSignature = True
|
hasJsonSignature = True
|
||||||
else:
|
else:
|
||||||
print('unrecognised @context: ' +
|
unknownContextsFile = \
|
||||||
str(originalJson['@context']))
|
baseDir + '/accounts/unknownContexts.txt'
|
||||||
|
unknownContext = str(originalJson['@context'])
|
||||||
|
|
||||||
|
print('unrecognized @context: ' +
|
||||||
|
unknownContext)
|
||||||
|
|
||||||
|
alreadyUnknown = False
|
||||||
|
if os.path.isfile(unknownContextsFile):
|
||||||
|
if unknownContext in \
|
||||||
|
open(unknownContextsFile).read():
|
||||||
|
alreadyUnknown = True
|
||||||
|
|
||||||
|
if not alreadyUnknown:
|
||||||
|
unknownFile = open(unknownContextsFile, "a+")
|
||||||
|
if unknownFile:
|
||||||
|
unknownFile.write(unknownContext + '\n')
|
||||||
|
unknownFile.close()
|
||||||
|
else:
|
||||||
|
print('Unrecognized jsonld signature type: ' +
|
||||||
|
jwebsigType)
|
||||||
|
|
||||||
|
unknownSignaturesFile = \
|
||||||
|
baseDir + '/accounts/unknownJsonSignatures.txt'
|
||||||
|
|
||||||
|
alreadyUnknown = False
|
||||||
|
if os.path.isfile(unknownSignaturesFile):
|
||||||
|
if jwebsigType in \
|
||||||
|
open(unknownSignaturesFile).read():
|
||||||
|
alreadyUnknown = True
|
||||||
|
|
||||||
|
if not alreadyUnknown:
|
||||||
|
unknownFile = open(unknownSignaturesFile, "a+")
|
||||||
|
if unknownFile:
|
||||||
|
unknownFile.write(jwebsigType + '\n')
|
||||||
|
unknownFile.close()
|
||||||
|
|
||||||
# strict enforcement of json signatures
|
# strict enforcement of json signatures
|
||||||
if not hasJsonSignature:
|
if not hasJsonSignature:
|
||||||
|
|
|
||||||
30
metadata.py
30
metadata.py
|
|
@ -12,12 +12,30 @@ from utils import noOfAccounts
|
||||||
from utils import noOfActiveAccountsMonthly
|
from utils import noOfActiveAccountsMonthly
|
||||||
|
|
||||||
|
|
||||||
def metaDataNodeInfo(baseDir: str, registration: bool, version: str) -> {}:
|
def metaDataNodeInfo(baseDir: str,
|
||||||
|
aboutUrl: str,
|
||||||
|
termsOfServiceUrl: str,
|
||||||
|
registration: bool, version: str,
|
||||||
|
showAccounts: bool) -> {}:
|
||||||
""" /nodeinfo/2.0 endpoint
|
""" /nodeinfo/2.0 endpoint
|
||||||
|
Also see https://socialhub.activitypub.rocks/t/
|
||||||
|
fep-f1d5-nodeinfo-in-fediverse-software/1190/4
|
||||||
|
|
||||||
|
Note that there are security considerations with this. If an adversary
|
||||||
|
sees a lot of accounts and "local" posts then the instance may be
|
||||||
|
considered a higher priority target.
|
||||||
|
Also exposure of the version number and number of accounts could be
|
||||||
|
sensitive
|
||||||
"""
|
"""
|
||||||
|
if showAccounts:
|
||||||
activeAccounts = noOfAccounts(baseDir)
|
activeAccounts = noOfAccounts(baseDir)
|
||||||
activeAccountsMonthly = noOfActiveAccountsMonthly(baseDir, 1)
|
activeAccountsMonthly = noOfActiveAccountsMonthly(baseDir, 1)
|
||||||
activeAccountsHalfYear = noOfActiveAccountsMonthly(baseDir, 6)
|
activeAccountsHalfYear = noOfActiveAccountsMonthly(baseDir, 6)
|
||||||
|
else:
|
||||||
|
activeAccounts = 1
|
||||||
|
activeAccountsMonthly = 1
|
||||||
|
activeAccountsHalfYear = 1
|
||||||
|
|
||||||
nodeinfo = {
|
nodeinfo = {
|
||||||
'openRegistrations': registration,
|
'openRegistrations': registration,
|
||||||
'protocols': ['activitypub'],
|
'protocols': ['activitypub'],
|
||||||
|
|
@ -25,6 +43,10 @@ def metaDataNodeInfo(baseDir: str, registration: bool, version: str) -> {}:
|
||||||
'name': 'epicyon',
|
'name': 'epicyon',
|
||||||
'version': version
|
'version': version
|
||||||
},
|
},
|
||||||
|
'documents': {
|
||||||
|
'about': aboutUrl,
|
||||||
|
'terms': termsOfServiceUrl
|
||||||
|
},
|
||||||
'usage': {
|
'usage': {
|
||||||
'localPosts': 1,
|
'localPosts': 1,
|
||||||
'users': {
|
'users': {
|
||||||
|
|
@ -83,13 +105,13 @@ def metaDataInstance(instanceTitle: str,
|
||||||
'id': '1',
|
'id': '1',
|
||||||
'last_status_at': '2019-07-01T10:30:00Z',
|
'last_status_at': '2019-07-01T10:30:00Z',
|
||||||
'locked': adminActor['manuallyApprovesFollowers'],
|
'locked': adminActor['manuallyApprovesFollowers'],
|
||||||
'note': '<p>Admin of '+domain+'</p>',
|
'note': '<p>Admin of ' + domain + '</p>',
|
||||||
'statuses_count': 1,
|
'statuses_count': 1,
|
||||||
'url': url,
|
'url': url,
|
||||||
'username': adminActor['preferredUsername']
|
'username': adminActor['preferredUsername']
|
||||||
},
|
},
|
||||||
'description': instanceDescription,
|
'description': instanceDescription,
|
||||||
'email': 'admin@'+domain,
|
'email': 'admin@' + domain,
|
||||||
'languages': [systemLanguage],
|
'languages': [systemLanguage],
|
||||||
'registrations': registration,
|
'registrations': registration,
|
||||||
'short_description': instanceDescriptionShort,
|
'short_description': instanceDescriptionShort,
|
||||||
|
|
@ -98,7 +120,7 @@ def metaDataInstance(instanceTitle: str,
|
||||||
'status_count': 1,
|
'status_count': 1,
|
||||||
'user_count': noOfAccounts(baseDir)
|
'user_count': noOfAccounts(baseDir)
|
||||||
},
|
},
|
||||||
'thumbnail': httpPrefix+'://'+domainFull+'/login.png',
|
'thumbnail': httpPrefix + '://' + domainFull + '/login.png',
|
||||||
'title': instanceTitle,
|
'title': instanceTitle,
|
||||||
'uri': domainFull,
|
'uri': domainFull,
|
||||||
'urls': {},
|
'urls': {},
|
||||||
|
|
|
||||||
18
tests.py
18
tests.py
|
|
@ -504,8 +504,12 @@ def createServerAlice(path: str, domain: str, port: int,
|
||||||
maxFollowers = 10
|
maxFollowers = 10
|
||||||
verifyAllSignatures = True
|
verifyAllSignatures = True
|
||||||
brochMode = False
|
brochMode = False
|
||||||
|
showNodeInfoAccounts = True
|
||||||
|
showNodeInfoVersion = True
|
||||||
print('Server running: Alice')
|
print('Server running: Alice')
|
||||||
runDaemon(brochMode,
|
runDaemon(showNodeInfoAccounts,
|
||||||
|
showNodeInfoVersion,
|
||||||
|
brochMode,
|
||||||
verifyAllSignatures,
|
verifyAllSignatures,
|
||||||
sendThreadsTimeoutMins,
|
sendThreadsTimeoutMins,
|
||||||
dormantMonths, maxNewswirePosts,
|
dormantMonths, maxNewswirePosts,
|
||||||
|
|
@ -601,8 +605,12 @@ def createServerBob(path: str, domain: str, port: int,
|
||||||
maxFollowers = 10
|
maxFollowers = 10
|
||||||
verifyAllSignatures = True
|
verifyAllSignatures = True
|
||||||
brochMode = False
|
brochMode = False
|
||||||
|
showNodeInfoAccounts = True
|
||||||
|
showNodeInfoVersion = True
|
||||||
print('Server running: Bob')
|
print('Server running: Bob')
|
||||||
runDaemon(brochMode,
|
runDaemon(showNodeInfoAccounts,
|
||||||
|
showNodeInfoVersion,
|
||||||
|
brochMode,
|
||||||
verifyAllSignatures,
|
verifyAllSignatures,
|
||||||
sendThreadsTimeoutMins,
|
sendThreadsTimeoutMins,
|
||||||
dormantMonths, maxNewswirePosts,
|
dormantMonths, maxNewswirePosts,
|
||||||
|
|
@ -652,8 +660,12 @@ def createServerEve(path: str, domain: str, port: int, federationList: [],
|
||||||
maxFollowers = 10
|
maxFollowers = 10
|
||||||
verifyAllSignatures = True
|
verifyAllSignatures = True
|
||||||
brochMode = False
|
brochMode = False
|
||||||
|
showNodeInfoAccounts = True
|
||||||
|
showNodeInfoVersion = True
|
||||||
print('Server running: Eve')
|
print('Server running: Eve')
|
||||||
runDaemon(brochMode,
|
runDaemon(showNodeInfoAccounts,
|
||||||
|
showNodeInfoVersion,
|
||||||
|
brochMode,
|
||||||
verifyAllSignatures,
|
verifyAllSignatures,
|
||||||
sendThreadsTimeoutMins,
|
sendThreadsTimeoutMins,
|
||||||
dormantMonths, maxNewswirePosts,
|
dormantMonths, maxNewswirePosts,
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "عرض زر",
|
"viewButton": "عرض زر",
|
||||||
"enterPetname": "أدخل PETNAME",
|
"enterPetname": "أدخل PETNAME",
|
||||||
"enterNotes": "أدخل الملاحظات",
|
"enterNotes": "أدخل الملاحظات",
|
||||||
"These access keys may be used": "قد يتم استخدام مفاتيح الوصول هذه، عادة مع مفتاح ALT + SHIFT + مفتاح ALT +"
|
"These access keys may be used": "قد يتم استخدام مفاتيح الوصول هذه، عادة مع مفتاح ALT + SHIFT + مفتاح ALT +",
|
||||||
|
"Show numbers of accounts within instance metadata": "إظهار عدد الحسابات داخل البيانات الوصفية للمثيلات",
|
||||||
|
"Show version number within instance metadata": "إظهار رقم الإصدار داخل البيانات الوصفية للمثيل"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Botó Veure",
|
"viewButton": "Botó Veure",
|
||||||
"enterPetname": "Introduïu PETNAME",
|
"enterPetname": "Introduïu PETNAME",
|
||||||
"enterNotes": "Introduïu notes",
|
"enterNotes": "Introduïu notes",
|
||||||
"These access keys may be used": "Es poden utilitzar aquestes tecles d'accés, típicament amb Alt + Maj + tecla o Alt + clau"
|
"These access keys may be used": "Es poden utilitzar aquestes tecles d'accés, típicament amb Alt + Maj + tecla o Alt + clau",
|
||||||
|
"Show numbers of accounts within instance metadata": "Mostra el nombre de comptes a les metadades de la instància",
|
||||||
|
"Show version number within instance metadata": "Mostra el número de versió a les metadades de la instància"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Gweld y botwm",
|
"viewButton": "Gweld y botwm",
|
||||||
"enterPetname": "Rhowch enw PETName",
|
"enterPetname": "Rhowch enw PETName",
|
||||||
"enterNotes": "Rhowch nodiadau",
|
"enterNotes": "Rhowch nodiadau",
|
||||||
"These access keys may be used": "Gellir defnyddio'r allweddi mynediad hyn, fel arfer gyda ALT + Shift + Allwedd Allwedd neu ALT +"
|
"These access keys may be used": "Gellir defnyddio'r allweddi mynediad hyn, fel arfer gyda ALT + Shift + Allwedd Allwedd neu ALT +",
|
||||||
|
"Show numbers of accounts within instance metadata": "Dangos nifer y cyfrifon o fewn metadata",
|
||||||
|
"Show version number within instance metadata": "Dangos rhif y fersiwn o fewn metadata"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Schaltfläche anzeigen",
|
"viewButton": "Schaltfläche anzeigen",
|
||||||
"enterPetname": "Petname eingeben",
|
"enterPetname": "Petname eingeben",
|
||||||
"enterNotes": "Notizen eingeben",
|
"enterNotes": "Notizen eingeben",
|
||||||
"These access keys may be used": "Diese Zugriffstasten können verwendet werden, typischerweise mit ALT + SHIFT + -Taste oder ALT + -Taste"
|
"These access keys may be used": "Diese Zugriffstasten können verwendet werden, typischerweise mit ALT + SHIFT + -Taste oder ALT + -Taste",
|
||||||
|
"Show numbers of accounts within instance metadata": "Anzahl der Konten in Instanzmetadaten anzeigen",
|
||||||
|
"Show version number within instance metadata": "Versionsnummer in Instanzmetadaten anzeigen"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@
|
||||||
"View": "View",
|
"View": "View",
|
||||||
"Stop blocking": "Stop blocking",
|
"Stop blocking": "Stop blocking",
|
||||||
"Enter an emoji name to search for": "Enter an emoji name to search for",
|
"Enter an emoji name to search for": "Enter an emoji name to search for",
|
||||||
"Enter an address, shared item, !history, #hashtag, *skill or :emoji: to search for": "Enter an address, shared item, !history, #hashtag, *skill or :emoji: to search for",
|
"Enter an address, shared item, !history, #hashtag, *skill or :emoji: to search for": "Enter an address, shared item, -save, !history, #hashtag, *skill or :emoji: to search for",
|
||||||
"Go Back": "◀",
|
"Go Back": "◀",
|
||||||
"Moderation Information": "Moderation Information",
|
"Moderation Information": "Moderation Information",
|
||||||
"Suspended accounts": "Suspended accounts",
|
"Suspended accounts": "Suspended accounts",
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "View button",
|
"viewButton": "View button",
|
||||||
"enterPetname": "Enter petname",
|
"enterPetname": "Enter petname",
|
||||||
"enterNotes": "Enter notes",
|
"enterNotes": "Enter notes",
|
||||||
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key"
|
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key",
|
||||||
|
"Show numbers of accounts within instance metadata": "Show numbers of accounts within instance metadata",
|
||||||
|
"Show version number within instance metadata": "Show version number within instance metadata"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Botón de vista",
|
"viewButton": "Botón de vista",
|
||||||
"enterPetname": "Entrar en nombre de pettname",
|
"enterPetname": "Entrar en nombre de pettname",
|
||||||
"enterNotes": "Ingresar notas",
|
"enterNotes": "Ingresar notas",
|
||||||
"These access keys may be used": "Se pueden usar estas teclas de acceso, típicamente con teclas ALT + MAYÚS + teclas o ALT +"
|
"These access keys may be used": "Se pueden usar estas teclas de acceso, típicamente con teclas ALT + MAYÚS + teclas o ALT +",
|
||||||
|
"Show numbers of accounts within instance metadata": "Muestra el número de cuentas dentro de los metadatos de la instancia.",
|
||||||
|
"Show version number within instance metadata": "Mostrar el número de versión dentro de los metadatos de la instancia"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Bouton d'affichage",
|
"viewButton": "Bouton d'affichage",
|
||||||
"enterPetname": "Entrez PETNAME",
|
"enterPetname": "Entrez PETNAME",
|
||||||
"enterNotes": "Faire entrer des notes",
|
"enterNotes": "Faire entrer des notes",
|
||||||
"These access keys may be used": "Ces touches d'accès peuvent être utilisées typiquement avec une touche Alt + Maj + ou Alt +"
|
"These access keys may be used": "Ces touches d'accès peuvent être utilisées typiquement avec une touche Alt + Maj + ou Alt +",
|
||||||
|
"Show numbers of accounts within instance metadata": "Afficher le nombre de comptes dans les métadonnées de l'instance",
|
||||||
|
"Show version number within instance metadata": "Afficher le numéro de version dans les métadonnées de l'instance"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Féach an cnaipe",
|
"viewButton": "Féach an cnaipe",
|
||||||
"enterPetname": "Cuir isteach PetName",
|
"enterPetname": "Cuir isteach PetName",
|
||||||
"enterNotes": "Cuir nótaí isteach",
|
"enterNotes": "Cuir nótaí isteach",
|
||||||
"These access keys may be used": "Is féidir na heochracha rochtana seo a úsáid, de ghnáth le Alt + Shift + Eochair nó Alt + Eochair"
|
"These access keys may be used": "Is féidir na heochracha rochtana seo a úsáid, de ghnáth le Alt + Shift + Eochair nó Alt + Eochair",
|
||||||
|
"Show numbers of accounts within instance metadata": "Taispeáin líon na gcuntas laistigh de mheiteashonraí",
|
||||||
|
"Show version number within instance metadata": "Taispeáin uimhir an leagain laistigh de mheiteashonraí"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "देखें बटन",
|
"viewButton": "देखें बटन",
|
||||||
"enterPetname": "PETNAME दर्ज करें",
|
"enterPetname": "PETNAME दर्ज करें",
|
||||||
"enterNotes": "नोट्स दर्ज करें",
|
"enterNotes": "नोट्स दर्ज करें",
|
||||||
"These access keys may be used": "इन एक्सेस कुंजियों का उपयोग किया जा सकता है, आमतौर पर Alt + Shift + कुंजी या Alt + कुंजी के साथ"
|
"These access keys may be used": "इन एक्सेस कुंजियों का उपयोग किया जा सकता है, आमतौर पर Alt + Shift + कुंजी या Alt + कुंजी के साथ",
|
||||||
|
"Show numbers of accounts within instance metadata": "उदाहरण मेटाडेटा के भीतर खातों की संख्या दिखाएं",
|
||||||
|
"Show version number within instance metadata": "उदाहरण मेटाडेटा के भीतर संस्करण संख्या दिखाएं"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Visualizza il pulsante",
|
"viewButton": "Visualizza il pulsante",
|
||||||
"enterPetname": "Inserisci PetName",
|
"enterPetname": "Inserisci PetName",
|
||||||
"enterNotes": "Inserisci le note",
|
"enterNotes": "Inserisci le note",
|
||||||
"These access keys may be used": "Questi tasti di accesso possono essere utilizzati, in genere con tasto ALT + MAIUSC + o ALT + Key"
|
"These access keys may be used": "Questi tasti di accesso possono essere utilizzati, in genere con tasto ALT + MAIUSC + o ALT + Key",
|
||||||
|
"Show numbers of accounts within instance metadata": "Mostra il numero di account all'interno dei metadati dell'istanza",
|
||||||
|
"Show version number within instance metadata": "Mostra il numero di versione nei metadati dell'istanza"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "ボタンを見る",
|
"viewButton": "ボタンを見る",
|
||||||
"enterPetname": "PetNameを入力してください",
|
"enterPetname": "PetNameを入力してください",
|
||||||
"enterNotes": "ノートを入力してください",
|
"enterNotes": "ノートを入力してください",
|
||||||
"These access keys may be used": "これらのアクセスキーは、通常はAlt + Shift +キーまたはAlt +キーを使用して使用できます。"
|
"These access keys may be used": "これらのアクセスキーは、通常はAlt + Shift +キーまたはAlt +キーを使用して使用できます。",
|
||||||
|
"Show numbers of accounts within instance metadata": "インスタンスメタデータ内のアカウント数を表示する",
|
||||||
|
"Show version number within instance metadata": "インスタンスメタデータ内にバージョン番号を表示する"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Bişkoja View",
|
"viewButton": "Bişkoja View",
|
||||||
"enterPetname": "Porê binivîse",
|
"enterPetname": "Porê binivîse",
|
||||||
"enterNotes": "Nîşan binivîse",
|
"enterNotes": "Nîşan binivîse",
|
||||||
"These access keys may be used": "Dibe ku ev keysên gihîştinê bikar bînin, bi gelemperî bi alt + shift + key an alt + key"
|
"These access keys may be used": "Dibe ku ev keysên gihîştinê bikar bînin, bi gelemperî bi alt + shift + key an alt + key",
|
||||||
|
"Show numbers of accounts within instance metadata": "Di nav metadata mînakê de hejmarên hesaban nîşan bidin",
|
||||||
|
"Show version number within instance metadata": "Di nav metadata mînakê de nimreya guhertoyê nîşan bide"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -433,5 +433,7 @@
|
||||||
"viewButton": "View button",
|
"viewButton": "View button",
|
||||||
"enterPetname": "Enter petname",
|
"enterPetname": "Enter petname",
|
||||||
"enterNotes": "Enter notes",
|
"enterNotes": "Enter notes",
|
||||||
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key"
|
"These access keys may be used": "These access keys may be used, typically with ALT + SHIFT + key or ALT + key",
|
||||||
|
"Show numbers of accounts within instance metadata": "Show numbers of accounts within instance metadata",
|
||||||
|
"Show version number within instance metadata": "Show version number within instance metadata"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Botão de visualização",
|
"viewButton": "Botão de visualização",
|
||||||
"enterPetname": "Digite Petname",
|
"enterPetname": "Digite Petname",
|
||||||
"enterNotes": "Digite notas",
|
"enterNotes": "Digite notas",
|
||||||
"These access keys may be used": "Essas teclas de acesso podem ser usadas, normalmente com tecla Alt + Shift + Key ou Alt +"
|
"These access keys may be used": "Essas teclas de acesso podem ser usadas, normalmente com tecla Alt + Shift + Key ou Alt +",
|
||||||
|
"Show numbers of accounts within instance metadata": "Mostra o número de contas nos metadados da instância",
|
||||||
|
"Show version number within instance metadata": "Mostrar o número da versão nos metadados da instância"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "Кнопка просмотра",
|
"viewButton": "Кнопка просмотра",
|
||||||
"enterPetname": "Введите petname",
|
"enterPetname": "Введите petname",
|
||||||
"enterNotes": "Введите ноты",
|
"enterNotes": "Введите ноты",
|
||||||
"These access keys may be used": "Эти ключевые ключи доступа могут быть использованы, обычно с ALT + Shift + Key или Alt + Key"
|
"These access keys may be used": "Эти ключевые ключи доступа могут быть использованы, обычно с ALT + Shift + Key или Alt + Key",
|
||||||
|
"Show numbers of accounts within instance metadata": "Показать количество учетных записей в метаданных экземпляра",
|
||||||
|
"Show version number within instance metadata": "Показать номер версии в метаданных экземпляра"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -437,5 +437,7 @@
|
||||||
"viewButton": "查看按钮",
|
"viewButton": "查看按钮",
|
||||||
"enterPetname": "进入宠物名",
|
"enterPetname": "进入宠物名",
|
||||||
"enterNotes": "输入笔记",
|
"enterNotes": "输入笔记",
|
||||||
"These access keys may be used": "可以使用这些访问密钥,通常使用Alt + Shift +键或ALT +键"
|
"These access keys may be used": "可以使用这些访问密钥,通常使用Alt + Shift +键或ALT +键",
|
||||||
|
"Show numbers of accounts within instance metadata": "显示实例元数据中的帐户数",
|
||||||
|
"Show version number within instance metadata": "在实例元数据中显示版本号"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
utils.py
56
utils.py
|
|
@ -1678,6 +1678,59 @@ def isNewsPost(postJsonObject: {}) -> bool:
|
||||||
return postJsonObject.get('news')
|
return postJsonObject.get('news')
|
||||||
|
|
||||||
|
|
||||||
|
def _searchVirtualBoxPosts(baseDir: str, nickname: str, domain: str,
|
||||||
|
searchStr: str, maxResults: int,
|
||||||
|
boxName: str) -> []:
|
||||||
|
"""Searches through a virtual box, which is typically an index on the inbox
|
||||||
|
"""
|
||||||
|
indexFilename = \
|
||||||
|
baseDir + '/accounts/' + nickname + '@' + domain + '/' + \
|
||||||
|
boxName + '.index'
|
||||||
|
if boxName == 'bookmarks':
|
||||||
|
boxName = 'inbox'
|
||||||
|
path = baseDir + '/accounts/' + nickname + '@' + domain + '/' + boxName
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
return []
|
||||||
|
|
||||||
|
searchStr = searchStr.lower().strip()
|
||||||
|
|
||||||
|
if '+' in searchStr:
|
||||||
|
searchWords = searchStr.split('+')
|
||||||
|
for index in range(len(searchWords)):
|
||||||
|
searchWords[index] = searchWords[index].strip()
|
||||||
|
print('SEARCH: ' + str(searchWords))
|
||||||
|
else:
|
||||||
|
searchWords = [searchStr]
|
||||||
|
|
||||||
|
res = []
|
||||||
|
with open(indexFilename, 'r') as indexFile:
|
||||||
|
postFilename = 'start'
|
||||||
|
while postFilename:
|
||||||
|
postFilename = indexFile.readline()
|
||||||
|
if not postFilename:
|
||||||
|
break
|
||||||
|
if '.json' not in postFilename:
|
||||||
|
break
|
||||||
|
postFilename = path + '/' + postFilename.strip()
|
||||||
|
if not os.path.isfile(postFilename):
|
||||||
|
continue
|
||||||
|
with open(postFilename, 'r') as postFile:
|
||||||
|
data = postFile.read().lower()
|
||||||
|
|
||||||
|
notFound = False
|
||||||
|
for keyword in searchWords:
|
||||||
|
if keyword not in data:
|
||||||
|
notFound = True
|
||||||
|
break
|
||||||
|
if notFound:
|
||||||
|
continue
|
||||||
|
|
||||||
|
res.append(postFilename)
|
||||||
|
if len(res) >= maxResults:
|
||||||
|
return res
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
def searchBoxPosts(baseDir: str, nickname: str, domain: str,
|
def searchBoxPosts(baseDir: str, nickname: str, domain: str,
|
||||||
searchStr: str, maxResults: int,
|
searchStr: str, maxResults: int,
|
||||||
boxName='outbox') -> []:
|
boxName='outbox') -> []:
|
||||||
|
|
@ -1686,6 +1739,9 @@ def searchBoxPosts(baseDir: str, nickname: str, domain: str,
|
||||||
"""
|
"""
|
||||||
path = baseDir + '/accounts/' + nickname + '@' + domain + '/' + boxName
|
path = baseDir + '/accounts/' + nickname + '@' + domain + '/' + boxName
|
||||||
if not os.path.isdir(path):
|
if not os.path.isdir(path):
|
||||||
|
if os.path.isfile(path + '.index'):
|
||||||
|
return _searchVirtualBoxPosts(baseDir, nickname, domain,
|
||||||
|
searchStr, maxResults, boxName)
|
||||||
return []
|
return []
|
||||||
searchStr = searchStr.lower().strip()
|
searchStr = searchStr.lower().strip()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1350,6 +1350,33 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
instanceStr += \
|
instanceStr += \
|
||||||
' <br><label class="labels">' + \
|
' <br><label class="labels">' + \
|
||||||
translate['Security'] + '</label><br>\n'
|
translate['Security'] + '</label><br>\n'
|
||||||
|
|
||||||
|
nodeInfoStr = \
|
||||||
|
translate['Show numbers of accounts within instance metadata']
|
||||||
|
if getConfigParam(baseDir, "showNodeInfoAccounts"):
|
||||||
|
instanceStr += \
|
||||||
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
|
'name="showNodeInfoAccounts" checked> ' + \
|
||||||
|
nodeInfoStr + '<br>\n'
|
||||||
|
else:
|
||||||
|
instanceStr += \
|
||||||
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
|
'name="showNodeInfoAccounts"> ' + \
|
||||||
|
nodeInfoStr + '<br>\n'
|
||||||
|
|
||||||
|
nodeInfoStr = \
|
||||||
|
translate['Show version number within instance metadata']
|
||||||
|
if getConfigParam(baseDir, "showNodeInfoVersion"):
|
||||||
|
instanceStr += \
|
||||||
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
|
'name="showNodeInfoVersion" checked> ' + \
|
||||||
|
nodeInfoStr + '<br>\n'
|
||||||
|
else:
|
||||||
|
instanceStr += \
|
||||||
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
|
'name="showNodeInfoVersion"> ' + \
|
||||||
|
nodeInfoStr + '<br>\n'
|
||||||
|
|
||||||
if getConfigParam(baseDir, "verifyAllSignatures"):
|
if getConfigParam(baseDir, "verifyAllSignatures"):
|
||||||
instanceStr += \
|
instanceStr += \
|
||||||
' <input type="checkbox" class="profilecheckbox" ' + \
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
|
|
@ -1360,6 +1387,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
' <input type="checkbox" class="profilecheckbox" ' + \
|
' <input type="checkbox" class="profilecheckbox" ' + \
|
||||||
'name="verifyallsignatures"> ' + \
|
'name="verifyallsignatures"> ' + \
|
||||||
translate['Verify all signatures'] + '<br>\n'
|
translate['Verify all signatures'] + '<br>\n'
|
||||||
|
|
||||||
instanceStr += translate['Enabling broch mode'] + '<br>\n'
|
instanceStr += translate['Enabling broch mode'] + '<br>\n'
|
||||||
if getConfigParam(baseDir, "brochMode"):
|
if getConfigParam(baseDir, "brochMode"):
|
||||||
instanceStr += \
|
instanceStr += \
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool,
|
allowLocalNetworkAccess: bool,
|
||||||
themeName: str) -> str:
|
themeName: str, boxName: str) -> str:
|
||||||
"""Show a page containing search results for your post history
|
"""Show a page containing search results for your post history
|
||||||
"""
|
"""
|
||||||
if historysearch.startswith('!'):
|
if historysearch.startswith('!'):
|
||||||
|
|
@ -546,7 +546,7 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
|
|
||||||
boxFilenames = \
|
boxFilenames = \
|
||||||
searchBoxPosts(baseDir, nickname, domain,
|
searchBoxPosts(baseDir, nickname, domain,
|
||||||
historysearch, postsPerPage)
|
historysearch, postsPerPage, boxName)
|
||||||
|
|
||||||
cssFilename = baseDir + '/epicyon-profile.css'
|
cssFilename = baseDir + '/epicyon-profile.css'
|
||||||
if os.path.isfile(baseDir + '/epicyon.css'):
|
if os.path.isfile(baseDir + '/epicyon.css'):
|
||||||
|
|
@ -560,10 +560,13 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
# add the page title
|
# add the page title
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
|
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
|
||||||
|
historySearchTitle = '🔍 ' + translate['Your Posts']
|
||||||
|
if boxName == 'bookmarks':
|
||||||
|
historySearchTitle = '🔍 ' + translate['Bookmarks']
|
||||||
|
|
||||||
historySearchForm += \
|
historySearchForm += \
|
||||||
'<center><h1><a href="' + actor + '/search">' + \
|
'<center><h1><a href="' + actor + '/search">' + \
|
||||||
translate['Your Posts'] + \
|
historySearchTitle + '</a></h1></center>'
|
||||||
'</a></h1></center>'
|
|
||||||
|
|
||||||
if len(boxFilenames) == 0:
|
if len(boxFilenames) == 0:
|
||||||
historySearchForm += \
|
historySearchForm += \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue