forked from indymedia/epicyon
Enforce convention of underscore before local function names
parent
0cf0841402
commit
5cd9aa8d66
|
|
@ -15,7 +15,7 @@ from utils import domainPermitted
|
||||||
from utils import followPerson
|
from utils import followPerson
|
||||||
|
|
||||||
|
|
||||||
def createAcceptReject(baseDir: str, federationList: [],
|
def _createAcceptReject(baseDir: str, federationList: [],
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str,
|
toUrl: str, ccUrl: str, httpPrefix: str,
|
||||||
objectJson: {}, acceptType: str) -> {}:
|
objectJson: {}, acceptType: str) -> {}:
|
||||||
|
|
@ -51,7 +51,7 @@ def createAccept(baseDir: str, federationList: [],
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str,
|
toUrl: str, ccUrl: str, httpPrefix: str,
|
||||||
objectJson: {}) -> {}:
|
objectJson: {}) -> {}:
|
||||||
return createAcceptReject(baseDir, federationList,
|
return _createAcceptReject(baseDir, federationList,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
toUrl, ccUrl, httpPrefix,
|
toUrl, ccUrl, httpPrefix,
|
||||||
objectJson, 'Accept')
|
objectJson, 'Accept')
|
||||||
|
|
@ -61,13 +61,13 @@ def createReject(baseDir: str, federationList: [],
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str,
|
toUrl: str, ccUrl: str, httpPrefix: str,
|
||||||
objectJson: {}) -> {}:
|
objectJson: {}) -> {}:
|
||||||
return createAcceptReject(baseDir, federationList,
|
return _createAcceptReject(baseDir, federationList,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
toUrl, ccUrl,
|
toUrl, ccUrl,
|
||||||
httpPrefix, objectJson, 'Reject')
|
httpPrefix, objectJson, 'Reject')
|
||||||
|
|
||||||
|
|
||||||
def acceptFollow(baseDir: str, domain: str, messageJson: {},
|
def _acceptFollow(baseDir: str, domain: str, messageJson: {},
|
||||||
federationList: [], debug: bool) -> None:
|
federationList: [], debug: bool) -> None:
|
||||||
"""Receiving a follow Accept activity
|
"""Receiving a follow Accept activity
|
||||||
"""
|
"""
|
||||||
|
|
@ -204,7 +204,7 @@ def receiveAcceptReject(session, baseDir: str,
|
||||||
' does not contain a nickname. ' +
|
' does not contain a nickname. ' +
|
||||||
'Assuming single user instance.')
|
'Assuming single user instance.')
|
||||||
# receive follow accept
|
# receive follow accept
|
||||||
acceptFollow(baseDir, domain, messageJson, federationList, debug)
|
_acceptFollow(baseDir, domain, messageJson, federationList, debug)
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Uh, ' + messageJson['type'] + ', I guess')
|
print('DEBUG: Uh, ' + messageJson['type'] + ', I guess')
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
12
auth.py
12
auth.py
|
|
@ -14,7 +14,7 @@ import secrets
|
||||||
from utils import isSystemAccount
|
from utils import isSystemAccount
|
||||||
|
|
||||||
|
|
||||||
def hashPassword(password: str) -> str:
|
def _hashPassword(password: str) -> str:
|
||||||
"""Hash a password for storing
|
"""Hash a password for storing
|
||||||
"""
|
"""
|
||||||
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
|
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
|
||||||
|
|
@ -25,7 +25,7 @@ def hashPassword(password: str) -> str:
|
||||||
return (salt + pwdhash).decode('ascii')
|
return (salt + pwdhash).decode('ascii')
|
||||||
|
|
||||||
|
|
||||||
def getPasswordHash(salt: str, providedPassword: str) -> str:
|
def _getPasswordHash(salt: str, providedPassword: str) -> str:
|
||||||
"""Returns the hash of a password
|
"""Returns the hash of a password
|
||||||
"""
|
"""
|
||||||
pwdhash = hashlib.pbkdf2_hmac('sha512',
|
pwdhash = hashlib.pbkdf2_hmac('sha512',
|
||||||
|
|
@ -57,7 +57,7 @@ def constantTimeStringCheck(string1: str, string2: str) -> bool:
|
||||||
return matched
|
return matched
|
||||||
|
|
||||||
|
|
||||||
def verifyPassword(storedPassword: str, providedPassword: str) -> bool:
|
def _verifyPassword(storedPassword: str, providedPassword: str) -> bool:
|
||||||
"""Verify a stored password against one provided by user
|
"""Verify a stored password against one provided by user
|
||||||
"""
|
"""
|
||||||
if not storedPassword:
|
if not storedPassword:
|
||||||
|
|
@ -66,7 +66,7 @@ def verifyPassword(storedPassword: str, providedPassword: str) -> bool:
|
||||||
return False
|
return False
|
||||||
salt = storedPassword[:64]
|
salt = storedPassword[:64]
|
||||||
storedPassword = storedPassword[64:]
|
storedPassword = storedPassword[64:]
|
||||||
pwHash = getPasswordHash(salt, providedPassword)
|
pwHash = _getPasswordHash(salt, providedPassword)
|
||||||
return constantTimeStringCheck(pwHash, storedPassword)
|
return constantTimeStringCheck(pwHash, storedPassword)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -137,7 +137,7 @@ def authorizeBasic(baseDir: str, path: str, authHeader: str,
|
||||||
if line.startswith(nickname+':'):
|
if line.startswith(nickname+':'):
|
||||||
storedPassword = \
|
storedPassword = \
|
||||||
line.split(':')[1].replace('\n', '').replace('\r', '')
|
line.split(':')[1].replace('\n', '').replace('\r', '')
|
||||||
success = verifyPassword(storedPassword, providedPassword)
|
success = _verifyPassword(storedPassword, providedPassword)
|
||||||
if not success:
|
if not success:
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Password check failed for ' + nickname)
|
print('DEBUG: Password check failed for ' + nickname)
|
||||||
|
|
@ -159,7 +159,7 @@ def storeBasicCredentials(baseDir: str, nickname: str, password: str) -> bool:
|
||||||
os.mkdir(baseDir + '/accounts')
|
os.mkdir(baseDir + '/accounts')
|
||||||
|
|
||||||
passwordFile = baseDir + '/accounts/passwords'
|
passwordFile = baseDir + '/accounts/passwords'
|
||||||
storeStr = nickname + ':' + hashPassword(password)
|
storeStr = nickname + ':' + _hashPassword(password)
|
||||||
if os.path.isfile(passwordFile):
|
if os.path.isfile(passwordFile):
|
||||||
if nickname + ':' in open(passwordFile).read():
|
if nickname + ':' in open(passwordFile).read():
|
||||||
with open(passwordFile, "r") as fin:
|
with open(passwordFile, "r") as fin:
|
||||||
|
|
|
||||||
43
blog.py
43
blog.py
|
|
@ -26,7 +26,7 @@ from newswire import rss2Header
|
||||||
from newswire import rss2Footer
|
from newswire import rss2Footer
|
||||||
|
|
||||||
|
|
||||||
def noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
def _noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postId: str, depth=0) -> int:
|
postId: str, depth=0) -> int:
|
||||||
"""Returns the number of replies on the post
|
"""Returns the number of replies on the post
|
||||||
|
|
@ -66,7 +66,8 @@ def noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
replyPostId = replyPostId.replace('.json', '')
|
replyPostId = replyPostId.replace('.json', '')
|
||||||
if locatePost(baseDir, nickname, domain, replyPostId):
|
if locatePost(baseDir, nickname, domain, replyPostId):
|
||||||
replyPostId = replyPostId.replace('.replies', '')
|
replyPostId = replyPostId.replace('.replies', '')
|
||||||
replies += 1 + noOfBlogReplies(baseDir, httpPrefix, translate,
|
replies += \
|
||||||
|
1 + _noOfBlogReplies(baseDir, httpPrefix, translate,
|
||||||
nickname, domain, domainFull,
|
nickname, domain, domainFull,
|
||||||
replyPostId, depth+1)
|
replyPostId, depth+1)
|
||||||
else:
|
else:
|
||||||
|
|
@ -86,7 +87,7 @@ def noOfBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
return replies
|
return replies
|
||||||
|
|
||||||
|
|
||||||
def getBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
def _getBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postId: str, depth=0) -> str:
|
postId: str, depth=0) -> str:
|
||||||
"""Returns a string containing html blog posts
|
"""Returns a string containing html blog posts
|
||||||
|
|
@ -136,7 +137,7 @@ def getBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
continue
|
continue
|
||||||
with open(postFilename, "r") as postFile:
|
with open(postFilename, "r") as postFile:
|
||||||
repliesStr += postFile.read() + '\n'
|
repliesStr += postFile.read() + '\n'
|
||||||
rply = getBlogReplies(baseDir, httpPrefix, translate,
|
rply = _getBlogReplies(baseDir, httpPrefix, translate,
|
||||||
nickname, domain, domainFull,
|
nickname, domain, domainFull,
|
||||||
replyPostId, depth+1)
|
replyPostId, depth+1)
|
||||||
if rply not in repliesStr:
|
if rply not in repliesStr:
|
||||||
|
|
@ -152,7 +153,7 @@ def getBlogReplies(baseDir: str, httpPrefix: str, translate: {},
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def htmlBlogPostContent(authorized: bool,
|
def _htmlBlogPostContent(authorized: bool,
|
||||||
baseDir: str, httpPrefix: str, translate: {},
|
baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
|
|
@ -269,7 +270,7 @@ def htmlBlogPostContent(authorized: bool,
|
||||||
'/users/' + nickname + '">' + translate['About the author'] + \
|
'/users/' + nickname + '">' + translate['About the author'] + \
|
||||||
'</a></p>\n'
|
'</a></p>\n'
|
||||||
|
|
||||||
replies = noOfBlogReplies(baseDir, httpPrefix, translate,
|
replies = _noOfBlogReplies(baseDir, httpPrefix, translate,
|
||||||
nickname, domain, domainFull,
|
nickname, domain, domainFull,
|
||||||
postJsonObject['object']['id'])
|
postJsonObject['object']['id'])
|
||||||
|
|
||||||
|
|
@ -288,11 +289,11 @@ def htmlBlogPostContent(authorized: bool,
|
||||||
else:
|
else:
|
||||||
blogStr += blogSeparator + '<h1>' + translate['Replies'] + '</h1>\n'
|
blogStr += blogSeparator + '<h1>' + translate['Replies'] + '</h1>\n'
|
||||||
if not titleStr:
|
if not titleStr:
|
||||||
blogStr += getBlogReplies(baseDir, httpPrefix, translate,
|
blogStr += _getBlogReplies(baseDir, httpPrefix, translate,
|
||||||
nickname, domain, domainFull,
|
nickname, domain, domainFull,
|
||||||
postJsonObject['object']['id'])
|
postJsonObject['object']['id'])
|
||||||
else:
|
else:
|
||||||
blogRepliesStr = getBlogReplies(baseDir, httpPrefix, translate,
|
blogRepliesStr = _getBlogReplies(baseDir, httpPrefix, translate,
|
||||||
nickname, domain, domainFull,
|
nickname, domain, domainFull,
|
||||||
postJsonObject['object']['id'])
|
postJsonObject['object']['id'])
|
||||||
blogStr += blogRepliesStr.replace('>' + titleStr + '<', '')
|
blogStr += blogRepliesStr.replace('>' + titleStr + '<', '')
|
||||||
|
|
@ -300,7 +301,7 @@ def htmlBlogPostContent(authorized: bool,
|
||||||
return blogStr
|
return blogStr
|
||||||
|
|
||||||
|
|
||||||
def htmlBlogPostRSS2(authorized: bool,
|
def _htmlBlogPostRSS2(authorized: bool,
|
||||||
baseDir: str, httpPrefix: str, translate: {},
|
baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
|
|
@ -331,7 +332,7 @@ def htmlBlogPostRSS2(authorized: bool,
|
||||||
return rssStr
|
return rssStr
|
||||||
|
|
||||||
|
|
||||||
def htmlBlogPostRSS3(authorized: bool,
|
def _htmlBlogPostRSS3(authorized: bool,
|
||||||
baseDir: str, httpPrefix: str, translate: {},
|
baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
|
|
@ -359,7 +360,7 @@ def htmlBlogPostRSS3(authorized: bool,
|
||||||
return rssStr
|
return rssStr
|
||||||
|
|
||||||
|
|
||||||
def htmlBlogRemoveCwButton(blogStr: str, translate: {}) -> str:
|
def _htmlBlogRemoveCwButton(blogStr: str, translate: {}) -> str:
|
||||||
"""Removes the CW button from blog posts, where the
|
"""Removes the CW button from blog posts, where the
|
||||||
summary field is instead used as the blog title
|
summary field is instead used as the blog title
|
||||||
"""
|
"""
|
||||||
|
|
@ -383,9 +384,9 @@ def htmlBlogPost(authorized: bool,
|
||||||
if os.path.isfile(baseDir + '/blog.css'):
|
if os.path.isfile(baseDir + '/blog.css'):
|
||||||
cssFilename = baseDir + '/blog.css'
|
cssFilename = baseDir + '/blog.css'
|
||||||
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
||||||
htmlBlogRemoveCwButton(blogStr, translate)
|
_htmlBlogRemoveCwButton(blogStr, translate)
|
||||||
|
|
||||||
blogStr += htmlBlogPostContent(authorized, baseDir,
|
blogStr += _htmlBlogPostContent(authorized, baseDir,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, postJsonObject,
|
domainFull, postJsonObject,
|
||||||
|
|
@ -428,7 +429,7 @@ def htmlBlogPage(authorized: bool, session,
|
||||||
if os.path.isfile(baseDir + '/epicyon.css'):
|
if os.path.isfile(baseDir + '/epicyon.css'):
|
||||||
cssFilename = baseDir + '/epicyon.css'
|
cssFilename = baseDir + '/epicyon.css'
|
||||||
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
||||||
htmlBlogRemoveCwButton(blogStr, translate)
|
_htmlBlogRemoveCwButton(blogStr, translate)
|
||||||
|
|
||||||
blogsIndex = baseDir + '/accounts/' + \
|
blogsIndex = baseDir + '/accounts/' + \
|
||||||
nickname + '@' + domain + '/tlblogs.index'
|
nickname + '@' + domain + '/tlblogs.index'
|
||||||
|
|
@ -472,7 +473,7 @@ def htmlBlogPage(authorized: bool, session,
|
||||||
if item['type'] != 'Create':
|
if item['type'] != 'Create':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
blogStr += htmlBlogPostContent(authorized, baseDir,
|
blogStr += _htmlBlogPostContent(authorized, baseDir,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, item,
|
domainFull, item,
|
||||||
|
|
@ -544,7 +545,7 @@ def htmlBlogPageRSS2(authorized: bool, session,
|
||||||
continue
|
continue
|
||||||
|
|
||||||
blogRSS2 += \
|
blogRSS2 += \
|
||||||
htmlBlogPostRSS2(authorized, baseDir,
|
_htmlBlogPostRSS2(authorized, baseDir,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, item,
|
domainFull, item,
|
||||||
|
|
@ -590,7 +591,7 @@ def htmlBlogPageRSS3(authorized: bool, session,
|
||||||
continue
|
continue
|
||||||
|
|
||||||
blogRSS3 += \
|
blogRSS3 += \
|
||||||
htmlBlogPostRSS3(authorized, baseDir,
|
_htmlBlogPostRSS3(authorized, baseDir,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, item,
|
domainFull, item,
|
||||||
|
|
@ -599,7 +600,7 @@ def htmlBlogPageRSS3(authorized: bool, session,
|
||||||
return blogRSS3
|
return blogRSS3
|
||||||
|
|
||||||
|
|
||||||
def noOfBlogAccounts(baseDir: str) -> int:
|
def _noOfBlogAccounts(baseDir: str) -> int:
|
||||||
"""Returns the number of blog accounts
|
"""Returns the number of blog accounts
|
||||||
"""
|
"""
|
||||||
ctr = 0
|
ctr = 0
|
||||||
|
|
@ -617,7 +618,7 @@ def noOfBlogAccounts(baseDir: str) -> int:
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
||||||
def singleBlogAccountNickname(baseDir: str) -> str:
|
def _singleBlogAccountNickname(baseDir: str) -> str:
|
||||||
"""Returns the nickname of a single blog account
|
"""Returns the nickname of a single blog account
|
||||||
"""
|
"""
|
||||||
for subdir, dirs, files in os.walk(baseDir + '/accounts'):
|
for subdir, dirs, files in os.walk(baseDir + '/accounts'):
|
||||||
|
|
@ -647,8 +648,8 @@ def htmlBlogView(authorized: bool,
|
||||||
cssFilename = baseDir + '/epicyon.css'
|
cssFilename = baseDir + '/epicyon.css'
|
||||||
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
blogStr = htmlHeaderWithExternalStyle(cssFilename)
|
||||||
|
|
||||||
if noOfBlogAccounts(baseDir) <= 1:
|
if _noOfBlogAccounts(baseDir) <= 1:
|
||||||
nickname = singleBlogAccountNickname(baseDir)
|
nickname = _singleBlogAccountNickname(baseDir)
|
||||||
if nickname:
|
if nickname:
|
||||||
return htmlBlogPage(authorized, session,
|
return htmlBlogPage(authorized, session,
|
||||||
baseDir, httpPrefix, translate,
|
baseDir, httpPrefix, translate,
|
||||||
|
|
|
||||||
34
blurhash.py
34
blurhash.py
|
|
@ -39,7 +39,7 @@ alphabet = \
|
||||||
alphabet_values = dict(zip(alphabet, range(len(alphabet))))
|
alphabet_values = dict(zip(alphabet, range(len(alphabet))))
|
||||||
|
|
||||||
|
|
||||||
def base83_encode(value, length):
|
def _base83_encode(value, length):
|
||||||
"""
|
"""
|
||||||
Decodes an integer to a base83 string, as used in blurhash.
|
Decodes an integer to a base83 string, as used in blurhash.
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ def base83_encode(value, length):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def srgb_to_linear(value):
|
def _srgb_to_linear(value):
|
||||||
"""
|
"""
|
||||||
srgb 0-255 integer to linear 0.0-1.0 floating point conversion.
|
srgb 0-255 integer to linear 0.0-1.0 floating point conversion.
|
||||||
"""
|
"""
|
||||||
|
|
@ -67,14 +67,14 @@ def srgb_to_linear(value):
|
||||||
return math.pow((value + 0.055) / 1.055, 2.4)
|
return math.pow((value + 0.055) / 1.055, 2.4)
|
||||||
|
|
||||||
|
|
||||||
def sign_pow(value, exp):
|
def _sign_pow(value, exp):
|
||||||
"""
|
"""
|
||||||
Sign-preserving exponentiation.
|
Sign-preserving exponentiation.
|
||||||
"""
|
"""
|
||||||
return math.copysign(math.pow(abs(value), exp), value)
|
return math.copysign(math.pow(abs(value), exp), value)
|
||||||
|
|
||||||
|
|
||||||
def linear_to_srgb(value):
|
def _linear_to_srgb(value):
|
||||||
"""
|
"""
|
||||||
linear 0.0-1.0 floating point to srgb 0-255 integer conversion.
|
linear 0.0-1.0 floating point to srgb 0-255 integer conversion.
|
||||||
"""
|
"""
|
||||||
|
|
@ -113,9 +113,9 @@ def blurhash_encode(image, components_x=4, components_y=4, linear=False):
|
||||||
image_linear_line = []
|
image_linear_line = []
|
||||||
for x in range(int(width)):
|
for x in range(int(width)):
|
||||||
image_linear_line.append([
|
image_linear_line.append([
|
||||||
srgb_to_linear(image[y][x][0]),
|
_srgb_to_linear(image[y][x][0]),
|
||||||
srgb_to_linear(image[y][x][1]),
|
_srgb_to_linear(image[y][x][1]),
|
||||||
srgb_to_linear(image[y][x][2])
|
_srgb_to_linear(image[y][x][2])
|
||||||
])
|
])
|
||||||
image_linear.append(image_linear_line)
|
image_linear.append(image_linear_line)
|
||||||
else:
|
else:
|
||||||
|
|
@ -149,9 +149,9 @@ def blurhash_encode(image, components_x=4, components_y=4, linear=False):
|
||||||
abs(component[1]), abs(component[2]))
|
abs(component[1]), abs(component[2]))
|
||||||
|
|
||||||
# Encode components
|
# Encode components
|
||||||
dc_value = (linear_to_srgb(components[0][0]) << 16) + \
|
dc_value = (_linear_to_srgb(components[0][0]) << 16) + \
|
||||||
(linear_to_srgb(components[0][1]) << 8) + \
|
(_linear_to_srgb(components[0][1]) << 8) + \
|
||||||
linear_to_srgb(components[0][2])
|
_linear_to_srgb(components[0][2])
|
||||||
|
|
||||||
quant_max_ac_component = int(max(0, min(82,
|
quant_max_ac_component = int(max(0, min(82,
|
||||||
math.floor(max_ac_component *
|
math.floor(max_ac_component *
|
||||||
|
|
@ -163,9 +163,9 @@ def blurhash_encode(image, components_x=4, components_y=4, linear=False):
|
||||||
r2 = r / ac_component_norm_factor
|
r2 = r / ac_component_norm_factor
|
||||||
g2 = g / ac_component_norm_factor
|
g2 = g / ac_component_norm_factor
|
||||||
b2 = b / ac_component_norm_factor
|
b2 = b / ac_component_norm_factor
|
||||||
r3 = math.floor(sign_pow(r2, 0.5) * 9.0 + 9.5)
|
r3 = math.floor(_sign_pow(r2, 0.5) * 9.0 + 9.5)
|
||||||
g3 = math.floor(sign_pow(g2, 0.5) * 9.0 + 9.5)
|
g3 = math.floor(_sign_pow(g2, 0.5) * 9.0 + 9.5)
|
||||||
b3 = math.floor(sign_pow(b2, 0.5) * 9.0 + 9.5)
|
b3 = math.floor(_sign_pow(b2, 0.5) * 9.0 + 9.5)
|
||||||
ac_values.append(
|
ac_values.append(
|
||||||
int(max(0.0, min(18.0, r3))) * 19 * 19 +
|
int(max(0.0, min(18.0, r3))) * 19 * 19 +
|
||||||
int(max(0.0, min(18.0, g3))) * 19 +
|
int(max(0.0, min(18.0, g3))) * 19 +
|
||||||
|
|
@ -174,10 +174,10 @@ def blurhash_encode(image, components_x=4, components_y=4, linear=False):
|
||||||
|
|
||||||
# Build final blurhash
|
# Build final blurhash
|
||||||
blurhash = ""
|
blurhash = ""
|
||||||
blurhash += base83_encode((components_x - 1) + (components_y - 1) * 9, 1)
|
blurhash += _base83_encode((components_x - 1) + (components_y - 1) * 9, 1)
|
||||||
blurhash += base83_encode(quant_max_ac_component, 1)
|
blurhash += _base83_encode(quant_max_ac_component, 1)
|
||||||
blurhash += base83_encode(dc_value, 4)
|
blurhash += _base83_encode(dc_value, 4)
|
||||||
for ac_value in ac_values:
|
for ac_value in ac_values:
|
||||||
blurhash += base83_encode(ac_value, 2)
|
blurhash += _base83_encode(ac_value, 2)
|
||||||
|
|
||||||
return blurhash
|
return blurhash
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ def undoBookmarksCollectionEntry(recentPostsCache: {},
|
||||||
def bookmarkedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool:
|
def bookmarkedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool:
|
||||||
"""Returns True if the given post is bookmarked by the given person
|
"""Returns True if the given post is bookmarked by the given person
|
||||||
"""
|
"""
|
||||||
if noOfBookmarks(postJsonObject) == 0:
|
if _noOfBookmarks(postJsonObject) == 0:
|
||||||
return False
|
return False
|
||||||
actorMatch = domain + '/users/' + nickname
|
actorMatch = domain + '/users/' + nickname
|
||||||
for item in postJsonObject['object']['bookmarks']['items']:
|
for item in postJsonObject['object']['bookmarks']['items']:
|
||||||
|
|
@ -116,7 +116,7 @@ def bookmarkedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def noOfBookmarks(postJsonObject: {}) -> int:
|
def _noOfBookmarks(postJsonObject: {}) -> int:
|
||||||
"""Returns the number of bookmarks ona given post
|
"""Returns the number of bookmarks ona given post
|
||||||
"""
|
"""
|
||||||
if not postJsonObject.get('object'):
|
if not postJsonObject.get('object'):
|
||||||
|
|
|
||||||
32
content.py
32
content.py
|
|
@ -33,7 +33,7 @@ def removeHtmlTag(htmlStr: str, tag: str) -> str:
|
||||||
return htmlStr
|
return htmlStr
|
||||||
|
|
||||||
|
|
||||||
def removeQuotesWithinQuotes(content: str) -> str:
|
def _removeQuotesWithinQuotes(content: str) -> str:
|
||||||
"""Removes any blockquote inside blockquote
|
"""Removes any blockquote inside blockquote
|
||||||
"""
|
"""
|
||||||
if '<blockquote>' not in content:
|
if '<blockquote>' not in content:
|
||||||
|
|
@ -96,7 +96,7 @@ def htmlReplaceEmailQuote(content: str) -> str:
|
||||||
else:
|
else:
|
||||||
lineStr = lineStr.replace('>', '<br>')
|
lineStr = lineStr.replace('>', '<br>')
|
||||||
newContent += '<p>' + lineStr + '</blockquote></p>'
|
newContent += '<p>' + lineStr + '</blockquote></p>'
|
||||||
return removeQuotesWithinQuotes(newContent)
|
return _removeQuotesWithinQuotes(newContent)
|
||||||
|
|
||||||
|
|
||||||
def htmlReplaceQuoteMarks(content: str) -> str:
|
def htmlReplaceQuoteMarks(content: str) -> str:
|
||||||
|
|
@ -314,7 +314,7 @@ def replaceEmojiFromTags(content: str, tag: [], messageType: str) -> str:
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def addMusicTag(content: str, tag: str) -> str:
|
def _addMusicTag(content: str, tag: str) -> str:
|
||||||
"""If a music link is found then ensure that the post is
|
"""If a music link is found then ensure that the post is
|
||||||
tagged appropriately
|
tagged appropriately
|
||||||
"""
|
"""
|
||||||
|
|
@ -416,7 +416,7 @@ def validHashTag(hashtag: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def addHashTags(wordStr: str, httpPrefix: str, domain: str,
|
def _addHashTags(wordStr: str, httpPrefix: str, domain: str,
|
||||||
replaceHashTags: {}, postHashtags: {}) -> bool:
|
replaceHashTags: {}, postHashtags: {}) -> bool:
|
||||||
"""Detects hashtags and adds them to the replacements dict
|
"""Detects hashtags and adds them to the replacements dict
|
||||||
Also updates the hashtags list to be added to the post
|
Also updates the hashtags list to be added to the post
|
||||||
|
|
@ -438,7 +438,7 @@ def addHashTags(wordStr: str, httpPrefix: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def addEmoji(baseDir: str, wordStr: str,
|
def _addEmoji(baseDir: str, wordStr: str,
|
||||||
httpPrefix: str, domain: str,
|
httpPrefix: str, domain: str,
|
||||||
replaceEmoji: {}, postTags: {},
|
replaceEmoji: {}, postTags: {},
|
||||||
emojiDict: {}) -> bool:
|
emojiDict: {}) -> bool:
|
||||||
|
|
@ -489,7 +489,7 @@ def tagExists(tagType: str, tagName: str, tags: {}) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def addMention(wordStr: str, httpPrefix: str, following: str,
|
def _addMention(wordStr: str, httpPrefix: str, following: str,
|
||||||
replaceMentions: {}, recipients: [], tags: {}) -> bool:
|
replaceMentions: {}, recipients: [], tags: {}) -> bool:
|
||||||
"""Detects mentions and adds them to the replacements dict and
|
"""Detects mentions and adds them to the replacements dict and
|
||||||
recipients list
|
recipients list
|
||||||
|
|
@ -672,7 +672,7 @@ def removeLongWords(content: str, maxWordLength: int,
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def loadAutoTags(baseDir: str, nickname: str, domain: str) -> []:
|
def _loadAutoTags(baseDir: str, nickname: str, domain: str) -> []:
|
||||||
"""Loads automatic tags file and returns a list containing
|
"""Loads automatic tags file and returns a list containing
|
||||||
the lines of the file
|
the lines of the file
|
||||||
"""
|
"""
|
||||||
|
|
@ -685,7 +685,7 @@ def loadAutoTags(baseDir: str, nickname: str, domain: str) -> []:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def autoTag(baseDir: str, nickname: str, domain: str,
|
def _autoTag(baseDir: str, nickname: str, domain: str,
|
||||||
wordStr: str, autoTagList: [],
|
wordStr: str, autoTagList: [],
|
||||||
appendTags: []):
|
appendTags: []):
|
||||||
"""Generates a list of tags to be automatically appended to the content
|
"""Generates a list of tags to be automatically appended to the content
|
||||||
|
|
@ -719,7 +719,7 @@ def addHtmlTags(baseDir: str, httpPrefix: str,
|
||||||
maxWordLength = 40
|
maxWordLength = 40
|
||||||
content = content.replace('\r', '')
|
content = content.replace('\r', '')
|
||||||
content = content.replace('\n', ' --linebreak-- ')
|
content = content.replace('\n', ' --linebreak-- ')
|
||||||
content = addMusicTag(content, 'nowplaying')
|
content = _addMusicTag(content, 'nowplaying')
|
||||||
contentSimplified = \
|
contentSimplified = \
|
||||||
content.replace(',', ' ').replace(';', ' ').replace('- ', ' ')
|
content.replace(',', ' ').replace(';', ' ').replace('- ', ' ')
|
||||||
contentSimplified = contentSimplified.replace('. ', ' ').strip()
|
contentSimplified = contentSimplified.replace('. ', ' ').strip()
|
||||||
|
|
@ -760,7 +760,7 @@ def addHtmlTags(baseDir: str, httpPrefix: str,
|
||||||
# extract mentions and tags from words
|
# extract mentions and tags from words
|
||||||
longWordsList = []
|
longWordsList = []
|
||||||
prevWordStr = ''
|
prevWordStr = ''
|
||||||
autoTagsList = loadAutoTags(baseDir, nickname, domain)
|
autoTagsList = _loadAutoTags(baseDir, nickname, domain)
|
||||||
appendTags = []
|
appendTags = []
|
||||||
for wordStr in words:
|
for wordStr in words:
|
||||||
wordLen = len(wordStr)
|
wordLen = len(wordStr)
|
||||||
|
|
@ -769,12 +769,12 @@ def addHtmlTags(baseDir: str, httpPrefix: str,
|
||||||
longWordsList.append(wordStr)
|
longWordsList.append(wordStr)
|
||||||
firstChar = wordStr[0]
|
firstChar = wordStr[0]
|
||||||
if firstChar == '@':
|
if firstChar == '@':
|
||||||
if addMention(wordStr, httpPrefix, following,
|
if _addMention(wordStr, httpPrefix, following,
|
||||||
replaceMentions, recipients, hashtags):
|
replaceMentions, recipients, hashtags):
|
||||||
prevWordStr = ''
|
prevWordStr = ''
|
||||||
continue
|
continue
|
||||||
elif firstChar == '#':
|
elif firstChar == '#':
|
||||||
if addHashTags(wordStr, httpPrefix, originalDomain,
|
if _addHashTags(wordStr, httpPrefix, originalDomain,
|
||||||
replaceHashTags, hashtags):
|
replaceHashTags, hashtags):
|
||||||
prevWordStr = ''
|
prevWordStr = ''
|
||||||
continue
|
continue
|
||||||
|
|
@ -791,16 +791,16 @@ def addHtmlTags(baseDir: str, httpPrefix: str,
|
||||||
emojiDict = loadJson(baseDir + '/emoji/emoji.json')
|
emojiDict = loadJson(baseDir + '/emoji/emoji.json')
|
||||||
|
|
||||||
# print('TAG: looking up emoji for :'+wordStr2+':')
|
# print('TAG: looking up emoji for :'+wordStr2+':')
|
||||||
addEmoji(baseDir, ':' + wordStr2 + ':', httpPrefix,
|
_addEmoji(baseDir, ':' + wordStr2 + ':', httpPrefix,
|
||||||
originalDomain, replaceEmoji, hashtags,
|
originalDomain, replaceEmoji, hashtags,
|
||||||
emojiDict)
|
emojiDict)
|
||||||
else:
|
else:
|
||||||
if autoTag(baseDir, nickname, domain, wordStr,
|
if _autoTag(baseDir, nickname, domain, wordStr,
|
||||||
autoTagsList, appendTags):
|
autoTagsList, appendTags):
|
||||||
prevWordStr = ''
|
prevWordStr = ''
|
||||||
continue
|
continue
|
||||||
if prevWordStr:
|
if prevWordStr:
|
||||||
if autoTag(baseDir, nickname, domain,
|
if _autoTag(baseDir, nickname, domain,
|
||||||
prevWordStr + ' ' + wordStr,
|
prevWordStr + ' ' + wordStr,
|
||||||
autoTagsList, appendTags):
|
autoTagsList, appendTags):
|
||||||
prevWordStr = ''
|
prevWordStr = ''
|
||||||
|
|
@ -810,7 +810,7 @@ def addHtmlTags(baseDir: str, httpPrefix: str,
|
||||||
# add any auto generated tags
|
# add any auto generated tags
|
||||||
for appended in appendTags:
|
for appended in appendTags:
|
||||||
content = content + ' ' + appended
|
content = content + ' ' + appended
|
||||||
addHashTags(appended, httpPrefix, originalDomain,
|
_addHashTags(appended, httpPrefix, originalDomain,
|
||||||
replaceHashTags, hashtags)
|
replaceHashTags, hashtags)
|
||||||
|
|
||||||
# replace words with their html versions
|
# replace words with their html versions
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ __email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
|
|
||||||
def getDonationTypes() -> str:
|
def _getDonationTypes() -> str:
|
||||||
return ('patreon', 'paypal', 'gofundme', 'liberapay',
|
return ('patreon', 'paypal', 'gofundme', 'liberapay',
|
||||||
'kickstarter', 'indiegogo', 'crowdsupply',
|
'kickstarter', 'indiegogo', 'crowdsupply',
|
||||||
'subscribestar')
|
'subscribestar')
|
||||||
|
|
@ -18,7 +18,7 @@ def getDonationUrl(actorJson: {}) -> str:
|
||||||
"""
|
"""
|
||||||
if not actorJson.get('attachment'):
|
if not actorJson.get('attachment'):
|
||||||
return ''
|
return ''
|
||||||
donationType = getDonationTypes()
|
donationType = _getDonationTypes()
|
||||||
for propertyValue in actorJson['attachment']:
|
for propertyValue in actorJson['attachment']:
|
||||||
if not propertyValue.get('name'):
|
if not propertyValue.get('name'):
|
||||||
continue
|
continue
|
||||||
|
|
@ -54,7 +54,7 @@ def setDonationUrl(actorJson: {}, donateUrl: str) -> None:
|
||||||
if not actorJson.get('attachment'):
|
if not actorJson.get('attachment'):
|
||||||
actorJson['attachment'] = []
|
actorJson['attachment'] = []
|
||||||
|
|
||||||
donationType = getDonationTypes()
|
donationType = _getDonationTypes()
|
||||||
donateName = None
|
donateName = None
|
||||||
for paymentService in donationType:
|
for paymentService in donationType:
|
||||||
if paymentService in donateUrl:
|
if paymentService in donateUrl:
|
||||||
|
|
|
||||||
10
filters.py
10
filters.py
|
|
@ -79,7 +79,7 @@ def removeGlobalFilter(baseDir: str, words: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def isTwitterPost(content: str) -> bool:
|
def _isTwitterPost(content: str) -> bool:
|
||||||
"""Returns true if the given post content is a retweet or twitter crosspost
|
"""Returns true if the given post content is a retweet or twitter crosspost
|
||||||
"""
|
"""
|
||||||
if '/twitter.' in content or '@twitter.' in content:
|
if '/twitter.' in content or '@twitter.' in content:
|
||||||
|
|
@ -89,7 +89,7 @@ def isTwitterPost(content: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def isFilteredBase(filename: str, content: str) -> bool:
|
def _isFilteredBase(filename: str, content: str) -> bool:
|
||||||
"""Uses the given file containing filtered words to check
|
"""Uses the given file containing filtered words to check
|
||||||
the given content
|
the given content
|
||||||
"""
|
"""
|
||||||
|
|
@ -122,7 +122,7 @@ def isFiltered(baseDir: str, nickname: str, domain: str, content: str) -> bool:
|
||||||
words must be present although not necessarily adjacent
|
words must be present although not necessarily adjacent
|
||||||
"""
|
"""
|
||||||
globalFiltersFilename = baseDir + '/accounts/filters.txt'
|
globalFiltersFilename = baseDir + '/accounts/filters.txt'
|
||||||
if isFilteredBase(globalFiltersFilename, content):
|
if _isFilteredBase(globalFiltersFilename, content):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not nickname or not domain:
|
if not nickname or not domain:
|
||||||
|
|
@ -132,9 +132,9 @@ def isFiltered(baseDir: str, nickname: str, domain: str, content: str) -> bool:
|
||||||
removeTwitter = baseDir + '/accounts/' + \
|
removeTwitter = baseDir + '/accounts/' + \
|
||||||
nickname + '@' + domain + '/.removeTwitter'
|
nickname + '@' + domain + '/.removeTwitter'
|
||||||
if os.path.isfile(removeTwitter):
|
if os.path.isfile(removeTwitter):
|
||||||
if isTwitterPost(content):
|
if _isTwitterPost(content):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
accountFiltersFilename = baseDir + '/accounts/' + \
|
accountFiltersFilename = baseDir + '/accounts/' + \
|
||||||
nickname + '@' + domain + '/filters.txt'
|
nickname + '@' + domain + '/filters.txt'
|
||||||
return isFilteredBase(accountFiltersFilename, content)
|
return _isFilteredBase(accountFiltersFilename, content)
|
||||||
|
|
|
||||||
46
follow.py
46
follow.py
|
|
@ -65,7 +65,7 @@ def createInitialLastSeen(baseDir: str, httpPrefix: str) -> None:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def preApprovedFollower(baseDir: str,
|
def _preApprovedFollower(baseDir: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
approveHandle: str,
|
approveHandle: str,
|
||||||
allowNewsFollowers: bool) -> bool:
|
allowNewsFollowers: bool) -> bool:
|
||||||
|
|
@ -84,7 +84,7 @@ def preApprovedFollower(baseDir: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def removeFromFollowBase(baseDir: str,
|
def _removeFromFollowBase(baseDir: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
acceptOrDenyHandle: str, followFile: str,
|
acceptOrDenyHandle: str, followFile: str,
|
||||||
debug: bool) -> None:
|
debug: bool) -> None:
|
||||||
|
|
@ -114,16 +114,16 @@ def removeFromFollowRequests(baseDir: str,
|
||||||
denyHandle: str, debug: bool) -> None:
|
denyHandle: str, debug: bool) -> None:
|
||||||
"""Removes a handle from follow requests
|
"""Removes a handle from follow requests
|
||||||
"""
|
"""
|
||||||
removeFromFollowBase(baseDir, nickname, domain,
|
_removeFromFollowBase(baseDir, nickname, domain,
|
||||||
denyHandle, 'followrequests', debug)
|
denyHandle, 'followrequests', debug)
|
||||||
|
|
||||||
|
|
||||||
def removeFromFollowRejects(baseDir: str,
|
def _removeFromFollowRejects(baseDir: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
acceptHandle: str, debug: bool) -> None:
|
acceptHandle: str, debug: bool) -> None:
|
||||||
"""Removes a handle from follow rejects
|
"""Removes a handle from follow rejects
|
||||||
"""
|
"""
|
||||||
removeFromFollowBase(baseDir, nickname, domain,
|
_removeFromFollowBase(baseDir, nickname, domain,
|
||||||
acceptHandle, 'followrejects', debug)
|
acceptHandle, 'followrejects', debug)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ def followerOfPerson(baseDir: str, nickname: str, domain: str,
|
||||||
federationList, debug, 'followers.txt')
|
federationList, debug, 'followers.txt')
|
||||||
|
|
||||||
|
|
||||||
def isFollowerOfPerson(baseDir: str, nickname: str, domain: str,
|
def _isFollowerOfPerson(baseDir: str, nickname: str, domain: str,
|
||||||
followerNickname: str, followerDomain: str) -> bool:
|
followerNickname: str, followerDomain: str) -> bool:
|
||||||
"""is the given nickname a follower of followerNickname?
|
"""is the given nickname a follower of followerNickname?
|
||||||
"""
|
"""
|
||||||
|
|
@ -291,7 +291,7 @@ def clearFollowers(baseDir: str, nickname: str, domain: str) -> None:
|
||||||
clearFollows(baseDir, nickname, domain, 'followers.txt')
|
clearFollows(baseDir, nickname, domain, 'followers.txt')
|
||||||
|
|
||||||
|
|
||||||
def getNoOfFollows(baseDir: str, nickname: str, domain: str,
|
def _getNoOfFollows(baseDir: str, nickname: str, domain: str,
|
||||||
authenticated: bool,
|
authenticated: bool,
|
||||||
followFile='following.txt') -> int:
|
followFile='following.txt') -> int:
|
||||||
"""Returns the number of follows or followers
|
"""Returns the number of follows or followers
|
||||||
|
|
@ -324,11 +324,11 @@ def getNoOfFollows(baseDir: str, nickname: str, domain: str,
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
||||||
def getNoOfFollowers(baseDir: str,
|
def _getNoOfFollowers(baseDir: str,
|
||||||
nickname: str, domain: str, authenticated: bool) -> int:
|
nickname: str, domain: str, authenticated: bool) -> int:
|
||||||
"""Returns the number of followers of the given person
|
"""Returns the number of followers of the given person
|
||||||
"""
|
"""
|
||||||
return getNoOfFollows(baseDir, nickname, domain,
|
return _getNoOfFollows(baseDir, nickname, domain,
|
||||||
authenticated, 'followers.txt')
|
authenticated, 'followers.txt')
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -382,7 +382,7 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str,
|
||||||
httpPrefix + '://' + domain + '/users/' + \
|
httpPrefix + '://' + domain + '/users/' + \
|
||||||
nickname + '/' + followFile
|
nickname + '/' + followFile
|
||||||
totalStr = \
|
totalStr = \
|
||||||
getNoOfFollows(baseDir, nickname, domain, authenticated)
|
_getNoOfFollows(baseDir, nickname, domain, authenticated)
|
||||||
following = {
|
following = {
|
||||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
'first': firstStr,
|
'first': firstStr,
|
||||||
|
|
@ -463,14 +463,14 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str,
|
||||||
return following
|
return following
|
||||||
|
|
||||||
|
|
||||||
def followApprovalRequired(baseDir: str, nicknameToFollow: str,
|
def _followApprovalRequired(baseDir: str, nicknameToFollow: str,
|
||||||
domainToFollow: str, debug: bool,
|
domainToFollow: str, debug: bool,
|
||||||
followRequestHandle: str,
|
followRequestHandle: str,
|
||||||
allowNewsFollowers: bool) -> bool:
|
allowNewsFollowers: bool) -> bool:
|
||||||
""" Returns the policy for follower approvals
|
""" Returns the policy for follower approvals
|
||||||
"""
|
"""
|
||||||
# has this handle already been manually approved?
|
# has this handle already been manually approved?
|
||||||
if preApprovedFollower(baseDir, nicknameToFollow, domainToFollow,
|
if _preApprovedFollower(baseDir, nicknameToFollow, domainToFollow,
|
||||||
followRequestHandle, allowNewsFollowers):
|
followRequestHandle, allowNewsFollowers):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
@ -494,7 +494,7 @@ def followApprovalRequired(baseDir: str, nicknameToFollow: str,
|
||||||
return manuallyApproveFollows
|
return manuallyApproveFollows
|
||||||
|
|
||||||
|
|
||||||
def noOfFollowRequests(baseDir: str,
|
def _noOfFollowRequests(baseDir: str,
|
||||||
nicknameToFollow: str, domainToFollow: str,
|
nicknameToFollow: str, domainToFollow: str,
|
||||||
nickname: str, domain: str, fromPort: int,
|
nickname: str, domain: str, fromPort: int,
|
||||||
followType: str) -> int:
|
followType: str) -> int:
|
||||||
|
|
@ -521,7 +521,7 @@ def noOfFollowRequests(baseDir: str,
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
||||||
def storeFollowRequest(baseDir: str,
|
def _storeFollowRequest(baseDir: str,
|
||||||
nicknameToFollow: str, domainToFollow: str, port: int,
|
nicknameToFollow: str, domainToFollow: str, port: int,
|
||||||
nickname: str, domain: str, fromPort: int,
|
nickname: str, domain: str, fromPort: int,
|
||||||
followJson: {},
|
followJson: {},
|
||||||
|
|
@ -668,7 +668,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
nicknameToFollow)
|
nicknameToFollow)
|
||||||
return True
|
return True
|
||||||
if maxFollowers > 0:
|
if maxFollowers > 0:
|
||||||
if getNoOfFollowers(baseDir,
|
if _getNoOfFollowers(baseDir,
|
||||||
nicknameToFollow, domainToFollow,
|
nicknameToFollow, domainToFollow,
|
||||||
True) > maxFollowers:
|
True) > maxFollowers:
|
||||||
print('WARN: ' + nicknameToFollow +
|
print('WARN: ' + nicknameToFollow +
|
||||||
|
|
@ -682,7 +682,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
baseDir + '/accounts/' + handleToFollow)
|
baseDir + '/accounts/' + handleToFollow)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if isFollowerOfPerson(baseDir,
|
if _isFollowerOfPerson(baseDir,
|
||||||
nicknameToFollow, domainToFollowFull,
|
nicknameToFollow, domainToFollowFull,
|
||||||
nickname, domainFull):
|
nickname, domainFull):
|
||||||
if debug:
|
if debug:
|
||||||
|
|
@ -693,26 +693,26 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
|
|
||||||
# what is the followers policy?
|
# what is the followers policy?
|
||||||
approveHandle = nickname + '@' + domainFull
|
approveHandle = nickname + '@' + domainFull
|
||||||
if followApprovalRequired(baseDir, nicknameToFollow,
|
if _followApprovalRequired(baseDir, nicknameToFollow,
|
||||||
domainToFollow, debug, approveHandle,
|
domainToFollow, debug, approveHandle,
|
||||||
allowNewsFollowers):
|
allowNewsFollowers):
|
||||||
print('Follow approval is required')
|
print('Follow approval is required')
|
||||||
if domain.endswith('.onion'):
|
if domain.endswith('.onion'):
|
||||||
if noOfFollowRequests(baseDir,
|
if _noOfFollowRequests(baseDir,
|
||||||
nicknameToFollow, domainToFollow,
|
nicknameToFollow, domainToFollow,
|
||||||
nickname, domain, fromPort,
|
nickname, domain, fromPort,
|
||||||
'onion') > 5:
|
'onion') > 5:
|
||||||
print('Too many follow requests from onion addresses')
|
print('Too many follow requests from onion addresses')
|
||||||
return False
|
return False
|
||||||
elif domain.endswith('.i2p'):
|
elif domain.endswith('.i2p'):
|
||||||
if noOfFollowRequests(baseDir,
|
if _noOfFollowRequests(baseDir,
|
||||||
nicknameToFollow, domainToFollow,
|
nicknameToFollow, domainToFollow,
|
||||||
nickname, domain, fromPort,
|
nickname, domain, fromPort,
|
||||||
'i2p') > 5:
|
'i2p') > 5:
|
||||||
print('Too many follow requests from i2p addresses')
|
print('Too many follow requests from i2p addresses')
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if noOfFollowRequests(baseDir,
|
if _noOfFollowRequests(baseDir,
|
||||||
nicknameToFollow, domainToFollow,
|
nicknameToFollow, domainToFollow,
|
||||||
nickname, domain, fromPort,
|
nickname, domain, fromPort,
|
||||||
'') > 10:
|
'') > 10:
|
||||||
|
|
@ -720,7 +720,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print('Storing follow request for approval')
|
print('Storing follow request for approval')
|
||||||
return storeFollowRequest(baseDir,
|
return _storeFollowRequest(baseDir,
|
||||||
nicknameToFollow, domainToFollow, port,
|
nicknameToFollow, domainToFollow, port,
|
||||||
nickname, domain, fromPort,
|
nickname, domain, fromPort,
|
||||||
messageJson, debug, messageJson['actor'])
|
messageJson, debug, messageJson['actor'])
|
||||||
|
|
@ -920,13 +920,13 @@ def sendFollowRequest(session, baseDir: str,
|
||||||
'object': followedId
|
'object': followedId
|
||||||
}
|
}
|
||||||
|
|
||||||
if followApprovalRequired(baseDir, nickname, domain, debug,
|
if _followApprovalRequired(baseDir, nickname, domain, debug,
|
||||||
followHandle, allowNewsFollowers):
|
followHandle, allowNewsFollowers):
|
||||||
# Remove any follow requests rejected for the account being followed.
|
# Remove any follow requests rejected for the account being followed.
|
||||||
# It's assumed that if you are following someone then you are
|
# It's assumed that if you are following someone then you are
|
||||||
# ok with them following back. If this isn't the case then a rejected
|
# ok with them following back. If this isn't the case then a rejected
|
||||||
# follow request will block them again.
|
# follow request will block them again.
|
||||||
removeFromFollowRejects(baseDir,
|
_removeFromFollowRejects(baseDir,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
followHandle, debug)
|
followHandle, debug)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ def receivingCalendarEvents(baseDir: str, nickname: str, domain: str,
|
||||||
return handle + '\n' in open(calendarFilename).read()
|
return handle + '\n' in open(calendarFilename).read()
|
||||||
|
|
||||||
|
|
||||||
def receiveCalendarEvents(baseDir: str, nickname: str, domain: str,
|
def _receiveCalendarEvents(baseDir: str, nickname: str, domain: str,
|
||||||
followingNickname: str,
|
followingNickname: str,
|
||||||
followingDomain: str,
|
followingDomain: str,
|
||||||
add: bool) -> None:
|
add: bool) -> None:
|
||||||
|
|
@ -100,12 +100,12 @@ def receiveCalendarEvents(baseDir: str, nickname: str, domain: str,
|
||||||
def addPersonToCalendar(baseDir: str, nickname: str, domain: str,
|
def addPersonToCalendar(baseDir: str, nickname: str, domain: str,
|
||||||
followingNickname: str,
|
followingNickname: str,
|
||||||
followingDomain: str) -> None:
|
followingDomain: str) -> None:
|
||||||
receiveCalendarEvents(baseDir, nickname, domain,
|
_receiveCalendarEvents(baseDir, nickname, domain,
|
||||||
followingNickname, followingDomain, True)
|
followingNickname, followingDomain, True)
|
||||||
|
|
||||||
|
|
||||||
def removePersonFromCalendar(baseDir: str, nickname: str, domain: str,
|
def removePersonFromCalendar(baseDir: str, nickname: str, domain: str,
|
||||||
followingNickname: str,
|
followingNickname: str,
|
||||||
followingDomain: str) -> None:
|
followingDomain: str) -> None:
|
||||||
receiveCalendarEvents(baseDir, nickname, domain,
|
_receiveCalendarEvents(baseDir, nickname, domain,
|
||||||
followingNickname, followingDomain, False)
|
followingNickname, followingDomain, False)
|
||||||
|
|
|
||||||
24
git.py
24
git.py
|
|
@ -10,7 +10,7 @@ import os
|
||||||
import html
|
import html
|
||||||
|
|
||||||
|
|
||||||
def gitFormatContent(content: str) -> str:
|
def _gitFormatContent(content: str) -> str:
|
||||||
""" replace html formatting, so that it's more
|
""" replace html formatting, so that it's more
|
||||||
like the original patch file
|
like the original patch file
|
||||||
"""
|
"""
|
||||||
|
|
@ -22,7 +22,7 @@ def gitFormatContent(content: str) -> str:
|
||||||
return patchStr
|
return patchStr
|
||||||
|
|
||||||
|
|
||||||
def getGitProjectName(baseDir: str, nickname: str, domain: str,
|
def _getGitProjectName(baseDir: str, nickname: str, domain: str,
|
||||||
subject: str) -> str:
|
subject: str) -> str:
|
||||||
"""Returns the project name for a git patch
|
"""Returns the project name for a git patch
|
||||||
The project name should be contained within the subject line
|
The project name should be contained within the subject line
|
||||||
|
|
@ -71,13 +71,13 @@ def isGitPatch(baseDir: str, nickname: str, domain: str,
|
||||||
return False
|
return False
|
||||||
if checkProjectName:
|
if checkProjectName:
|
||||||
projectName = \
|
projectName = \
|
||||||
getGitProjectName(baseDir, nickname, domain, subject)
|
_getGitProjectName(baseDir, nickname, domain, subject)
|
||||||
if not projectName:
|
if not projectName:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def getGitHash(patchStr: str) -> str:
|
def _getGitHash(patchStr: str) -> str:
|
||||||
"""Returns the commit hash from a given patch
|
"""Returns the commit hash from a given patch
|
||||||
"""
|
"""
|
||||||
patchLines = patchStr.split('\n')
|
patchLines = patchStr.split('\n')
|
||||||
|
|
@ -91,7 +91,7 @@ def getGitHash(patchStr: str) -> str:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def getPatchDescription(patchStr: str) -> str:
|
def _getPatchDescription(patchStr: str) -> str:
|
||||||
"""Returns the description from a given patch
|
"""Returns the description from a given patch
|
||||||
"""
|
"""
|
||||||
patchLines = patchStr.split('\n')
|
patchLines = patchStr.split('\n')
|
||||||
|
|
@ -134,8 +134,8 @@ def convertPostToPatch(baseDir: str, nickname: str, domain: str,
|
||||||
postJsonObject['object']['content'],
|
postJsonObject['object']['content'],
|
||||||
False):
|
False):
|
||||||
return False
|
return False
|
||||||
patchStr = gitFormatContent(postJsonObject['object']['content'])
|
patchStr = _gitFormatContent(postJsonObject['object']['content'])
|
||||||
commitHash = getGitHash(patchStr)
|
commitHash = _getGitHash(patchStr)
|
||||||
if not commitHash:
|
if not commitHash:
|
||||||
return False
|
return False
|
||||||
postJsonObject['object']['type'] = 'Patch'
|
postJsonObject['object']['type'] = 'Patch'
|
||||||
|
|
@ -146,7 +146,7 @@ def convertPostToPatch(baseDir: str, nickname: str, domain: str,
|
||||||
postJsonObject['object']['hash'] = commitHash
|
postJsonObject['object']['hash'] = commitHash
|
||||||
postJsonObject['object']['description'] = {
|
postJsonObject['object']['description'] = {
|
||||||
"mediaType": "text/plain",
|
"mediaType": "text/plain",
|
||||||
"content": getPatchDescription(patchStr)
|
"content": _getPatchDescription(patchStr)
|
||||||
}
|
}
|
||||||
# remove content map
|
# remove content map
|
||||||
if postJsonObject['object'].get('contentMap'):
|
if postJsonObject['object'].get('contentMap'):
|
||||||
|
|
@ -155,7 +155,7 @@ def convertPostToPatch(baseDir: str, nickname: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def gitAddFromHandle(patchStr: str, handle: str) -> str:
|
def _gitAddFromHandle(patchStr: str, handle: str) -> str:
|
||||||
"""Adds the activitypub handle of the sender to the patch
|
"""Adds the activitypub handle of the sender to the patch
|
||||||
"""
|
"""
|
||||||
fromStr = 'AP-signed-off-by: '
|
fromStr = 'AP-signed-off-by: '
|
||||||
|
|
@ -181,7 +181,7 @@ def receiveGitPatch(baseDir: str, nickname: str, domain: str,
|
||||||
messageType, subject, content):
|
messageType, subject, content):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
patchStr = gitFormatContent(content)
|
patchStr = _gitFormatContent(content)
|
||||||
|
|
||||||
patchLines = patchStr.split('\n')
|
patchLines = patchStr.split('\n')
|
||||||
patchFilename = None
|
patchFilename = None
|
||||||
|
|
@ -197,7 +197,7 @@ def receiveGitPatch(baseDir: str, nickname: str, domain: str,
|
||||||
patchSubject = patchSubject.replace('[PATCH]', '').strip()
|
patchSubject = patchSubject.replace('[PATCH]', '').strip()
|
||||||
patchSubject = patchSubject.replace(' ', '_')
|
patchSubject = patchSubject.replace(' ', '_')
|
||||||
projectName = \
|
projectName = \
|
||||||
getGitProjectName(baseDir, nickname, domain, subject)
|
_getGitProjectName(baseDir, nickname, domain, subject)
|
||||||
if not os.path.isdir(patchesDir):
|
if not os.path.isdir(patchesDir):
|
||||||
os.mkdir(patchesDir)
|
os.mkdir(patchesDir)
|
||||||
projectDir = patchesDir + '/' + projectName
|
projectDir = patchesDir + '/' + projectName
|
||||||
|
|
@ -209,7 +209,7 @@ def receiveGitPatch(baseDir: str, nickname: str, domain: str,
|
||||||
if not patchFilename:
|
if not patchFilename:
|
||||||
return False
|
return False
|
||||||
patchStr = \
|
patchStr = \
|
||||||
gitAddFromHandle(patchStr, '@' + fromNickname + '@' + fromDomain)
|
_gitAddFromHandle(patchStr, '@' + fromNickname + '@' + fromDomain)
|
||||||
with open(patchFilename, 'w+') as patchFile:
|
with open(patchFilename, 'w+') as patchFile:
|
||||||
patchFile.write(patchStr)
|
patchFile.write(patchStr)
|
||||||
patchNotifyFilename = \
|
patchNotifyFilename = \
|
||||||
|
|
|
||||||
32
happening.py
32
happening.py
|
|
@ -17,7 +17,7 @@ from utils import daysInMonth
|
||||||
from utils import mergeDicts
|
from utils import mergeDicts
|
||||||
|
|
||||||
|
|
||||||
def validUuid(testUuid: str, version=4):
|
def _validUuid(testUuid: str, version=4):
|
||||||
"""Check if uuid_to_test is a valid UUID
|
"""Check if uuid_to_test is a valid UUID
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -28,7 +28,7 @@ def validUuid(testUuid: str, version=4):
|
||||||
return str(uuid_obj) == testUuid
|
return str(uuid_obj) == testUuid
|
||||||
|
|
||||||
|
|
||||||
def removeEventFromTimeline(eventId: str, tlEventsFilename: str) -> None:
|
def _removeEventFromTimeline(eventId: str, tlEventsFilename: str) -> None:
|
||||||
"""Removes the given event Id from the timeline
|
"""Removes the given event Id from the timeline
|
||||||
"""
|
"""
|
||||||
if eventId + '\n' not in open(tlEventsFilename).read():
|
if eventId + '\n' not in open(tlEventsFilename).read():
|
||||||
|
|
@ -71,7 +71,7 @@ def saveEventPost(baseDir: str, handle: str, postId: str,
|
||||||
|
|
||||||
if eventJson.get('name') and eventJson.get('actor') and \
|
if eventJson.get('name') and eventJson.get('actor') and \
|
||||||
eventJson.get('uuid') and eventJson.get('content'):
|
eventJson.get('uuid') and eventJson.get('content'):
|
||||||
if not validUuid(eventJson['uuid']):
|
if not _validUuid(eventJson['uuid']):
|
||||||
return False
|
return False
|
||||||
print('Mobilizon type event')
|
print('Mobilizon type event')
|
||||||
# if this is a full description of an event then save it
|
# if this is a full description of an event then save it
|
||||||
|
|
@ -92,7 +92,7 @@ def saveEventPost(baseDir: str, handle: str, postId: str,
|
||||||
tlEventsFilename = baseDir + '/accounts/' + handle + '/events.txt'
|
tlEventsFilename = baseDir + '/accounts/' + handle + '/events.txt'
|
||||||
|
|
||||||
if os.path.isfile(tlEventsFilename):
|
if os.path.isfile(tlEventsFilename):
|
||||||
removeEventFromTimeline(eventId, tlEventsFilename)
|
_removeEventFromTimeline(eventId, tlEventsFilename)
|
||||||
try:
|
try:
|
||||||
with open(tlEventsFilename, 'r+') as tlEventsFile:
|
with open(tlEventsFilename, 'r+') as tlEventsFile:
|
||||||
content = tlEventsFile.read()
|
content = tlEventsFile.read()
|
||||||
|
|
@ -146,7 +146,7 @@ def saveEventPost(baseDir: str, handle: str, postId: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def isHappeningEvent(tag: {}) -> bool:
|
def _isHappeningEvent(tag: {}) -> bool:
|
||||||
"""Is this tag an Event or Place ActivityStreams type?
|
"""Is this tag an Event or Place ActivityStreams type?
|
||||||
"""
|
"""
|
||||||
if not tag.get('type'):
|
if not tag.get('type'):
|
||||||
|
|
@ -156,7 +156,7 @@ def isHappeningEvent(tag: {}) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def isHappeningPost(postJsonObject: {}) -> bool:
|
def _isHappeningPost(postJsonObject: {}) -> bool:
|
||||||
"""Is this a post with tags?
|
"""Is this a post with tags?
|
||||||
"""
|
"""
|
||||||
if not postJsonObject:
|
if not postJsonObject:
|
||||||
|
|
@ -208,13 +208,13 @@ def getTodaysEvents(baseDir: str, nickname: str, domain: str,
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
if not isHappeningPost(postJsonObject):
|
if not _isHappeningPost(postJsonObject):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postEvent = []
|
postEvent = []
|
||||||
dayOfMonth = None
|
dayOfMonth = None
|
||||||
for tag in postJsonObject['object']['tag']:
|
for tag in postJsonObject['object']['tag']:
|
||||||
if not isHappeningEvent(tag):
|
if not _isHappeningEvent(tag):
|
||||||
continue
|
continue
|
||||||
# this tag is an event or a place
|
# this tag is an event or a place
|
||||||
if tag['type'] == 'Event':
|
if tag['type'] == 'Event':
|
||||||
|
|
@ -275,11 +275,11 @@ def todaysEventsCheck(baseDir: str, nickname: str, domain: str) -> bool:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
if not isHappeningPost(postJsonObject):
|
if not _isHappeningPost(postJsonObject):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for tag in postJsonObject['object']['tag']:
|
for tag in postJsonObject['object']['tag']:
|
||||||
if not isHappeningEvent(tag):
|
if not _isHappeningEvent(tag):
|
||||||
continue
|
continue
|
||||||
# this tag is an event or a place
|
# this tag is an event or a place
|
||||||
if tag['type'] != 'Event':
|
if tag['type'] != 'Event':
|
||||||
|
|
@ -322,11 +322,11 @@ def thisWeeksEventsCheck(baseDir: str, nickname: str, domain: str) -> bool:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
if not isHappeningPost(postJsonObject):
|
if not _isHappeningPost(postJsonObject):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for tag in postJsonObject['object']['tag']:
|
for tag in postJsonObject['object']['tag']:
|
||||||
if not isHappeningEvent(tag):
|
if not _isHappeningEvent(tag):
|
||||||
continue
|
continue
|
||||||
# this tag is an event or a place
|
# this tag is an event or a place
|
||||||
if tag['type'] != 'Event':
|
if tag['type'] != 'Event':
|
||||||
|
|
@ -377,14 +377,14 @@ def getThisWeeksEvents(baseDir: str, nickname: str, domain: str) -> {}:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
if not isHappeningPost(postJsonObject):
|
if not _isHappeningPost(postJsonObject):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postEvent = []
|
postEvent = []
|
||||||
dayOfMonth = None
|
dayOfMonth = None
|
||||||
weekDayIndex = None
|
weekDayIndex = None
|
||||||
for tag in postJsonObject['object']['tag']:
|
for tag in postJsonObject['object']['tag']:
|
||||||
if not isHappeningEvent(tag):
|
if not _isHappeningEvent(tag):
|
||||||
continue
|
continue
|
||||||
# this tag is an event or a place
|
# this tag is an event or a place
|
||||||
if tag['type'] == 'Event':
|
if tag['type'] == 'Event':
|
||||||
|
|
@ -462,13 +462,13 @@ def getCalendarEvents(baseDir: str, nickname: str, domain: str,
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
if not isHappeningPost(postJsonObject):
|
if not _isHappeningPost(postJsonObject):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
postEvent = []
|
postEvent = []
|
||||||
dayOfMonth = None
|
dayOfMonth = None
|
||||||
for tag in postJsonObject['object']['tag']:
|
for tag in postJsonObject['object']['tag']:
|
||||||
if not isHappeningEvent(tag):
|
if not _isHappeningEvent(tag):
|
||||||
continue
|
continue
|
||||||
# this tag is an event or a place
|
# this tag is an event or a place
|
||||||
if tag['type'] == 'Event':
|
if tag['type'] == 'Event':
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ def createSignedHeader(privateKeyPem: str, nickname: str,
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
|
|
||||||
def verifyRecentSignature(signedDateStr: str) -> bool:
|
def _verifyRecentSignature(signedDateStr: str) -> bool:
|
||||||
"""Checks whether the given time taken from the header is within
|
"""Checks whether the given time taken from the header is within
|
||||||
12 hours of the current time
|
12 hours of the current time
|
||||||
"""
|
"""
|
||||||
|
|
@ -219,7 +219,7 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict,
|
||||||
else:
|
else:
|
||||||
if headers.get(signedHeader):
|
if headers.get(signedHeader):
|
||||||
if signedHeader == 'date':
|
if signedHeader == 'date':
|
||||||
if not verifyRecentSignature(headers[signedHeader]):
|
if not _verifyRecentSignature(headers[signedHeader]):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' +
|
print('DEBUG: ' +
|
||||||
'verifyPostHeaders date is not recent ' +
|
'verifyPostHeaders date is not recent ' +
|
||||||
|
|
@ -230,7 +230,7 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict,
|
||||||
else:
|
else:
|
||||||
signedHeaderCap = signedHeader.capitalize()
|
signedHeaderCap = signedHeader.capitalize()
|
||||||
if signedHeaderCap == 'Date':
|
if signedHeaderCap == 'Date':
|
||||||
if not verifyRecentSignature(headers[signedHeaderCap]):
|
if not _verifyRecentSignature(headers[signedHeaderCap]):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' +
|
print('DEBUG: ' +
|
||||||
'verifyPostHeaders date is not recent ' +
|
'verifyPostHeaders date is not recent ' +
|
||||||
|
|
|
||||||
158
inbox.py
158
inbox.py
|
|
@ -138,7 +138,7 @@ def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
|
||||||
setHashtagCategory(baseDir, tagName, categoryStr)
|
setHashtagCategory(baseDir, tagName, categoryStr)
|
||||||
|
|
||||||
|
|
||||||
def inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
translate: {},
|
translate: {},
|
||||||
baseDir: str, httpPrefix: str,
|
baseDir: str, httpPrefix: str,
|
||||||
session, cachedWebfingers: {}, personCache: {},
|
session, cachedWebfingers: {}, personCache: {},
|
||||||
|
|
@ -451,7 +451,7 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str,
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def inboxPostRecipientsAdd(baseDir: str, httpPrefix: str, toList: [],
|
def _inboxPostRecipientsAdd(baseDir: str, httpPrefix: str, toList: [],
|
||||||
recipientsDict: {},
|
recipientsDict: {},
|
||||||
domainMatch: str, domain: str,
|
domainMatch: str, domain: str,
|
||||||
actor: str, debug: bool) -> bool:
|
actor: str, debug: bool) -> bool:
|
||||||
|
|
@ -485,7 +485,7 @@ def inboxPostRecipientsAdd(baseDir: str, httpPrefix: str, toList: [],
|
||||||
return followerRecipients, recipientsDict
|
return followerRecipients, recipientsDict
|
||||||
|
|
||||||
|
|
||||||
def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
def _inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
debug: bool) -> ([], []):
|
debug: bool) -> ([], []):
|
||||||
"""Returns dictionaries containing the recipients of the given post
|
"""Returns dictionaries containing the recipients of the given post
|
||||||
|
|
@ -520,7 +520,7 @@ def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: resolving "to"')
|
print('DEBUG: resolving "to"')
|
||||||
includesFollowers, recipientsDict = \
|
includesFollowers, recipientsDict = \
|
||||||
inboxPostRecipientsAdd(baseDir, httpPrefix,
|
_inboxPostRecipientsAdd(baseDir, httpPrefix,
|
||||||
recipientsList,
|
recipientsList,
|
||||||
recipientsDict,
|
recipientsDict,
|
||||||
domainMatch, domainBase,
|
domainMatch, domainBase,
|
||||||
|
|
@ -537,7 +537,7 @@ def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
else:
|
else:
|
||||||
recipientsList = [postJsonObject['object']['cc']]
|
recipientsList = [postJsonObject['object']['cc']]
|
||||||
includesFollowers, recipientsDict = \
|
includesFollowers, recipientsDict = \
|
||||||
inboxPostRecipientsAdd(baseDir, httpPrefix,
|
_inboxPostRecipientsAdd(baseDir, httpPrefix,
|
||||||
recipientsList,
|
recipientsList,
|
||||||
recipientsDict,
|
recipientsDict,
|
||||||
domainMatch, domainBase,
|
domainMatch, domainBase,
|
||||||
|
|
@ -562,7 +562,7 @@ def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
else:
|
else:
|
||||||
recipientsList = [postJsonObject['to']]
|
recipientsList = [postJsonObject['to']]
|
||||||
includesFollowers, recipientsDict = \
|
includesFollowers, recipientsDict = \
|
||||||
inboxPostRecipientsAdd(baseDir, httpPrefix,
|
_inboxPostRecipientsAdd(baseDir, httpPrefix,
|
||||||
recipientsList,
|
recipientsList,
|
||||||
recipientsDict,
|
recipientsDict,
|
||||||
domainMatch, domainBase,
|
domainMatch, domainBase,
|
||||||
|
|
@ -576,7 +576,7 @@ def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
else:
|
else:
|
||||||
recipientsList = [postJsonObject['cc']]
|
recipientsList = [postJsonObject['cc']]
|
||||||
includesFollowers, recipientsDict = \
|
includesFollowers, recipientsDict = \
|
||||||
inboxPostRecipientsAdd(baseDir, httpPrefix,
|
_inboxPostRecipientsAdd(baseDir, httpPrefix,
|
||||||
recipientsList,
|
recipientsList,
|
||||||
recipientsDict,
|
recipientsDict,
|
||||||
domainMatch, domainBase,
|
domainMatch, domainBase,
|
||||||
|
|
@ -596,7 +596,7 @@ def inboxPostRecipients(baseDir: str, postJsonObject: {},
|
||||||
return recipientsDict, recipientsDictFollowers
|
return recipientsDict, recipientsDictFollowers
|
||||||
|
|
||||||
|
|
||||||
def receiveUndoFollow(session, baseDir: str, httpPrefix: str,
|
def _receiveUndoFollow(session, baseDir: str, httpPrefix: str,
|
||||||
port: int, messageJson: {},
|
port: int, messageJson: {},
|
||||||
federationList: [],
|
federationList: [],
|
||||||
debug: bool) -> bool:
|
debug: bool) -> bool:
|
||||||
|
|
@ -653,7 +653,7 @@ def receiveUndoFollow(session, baseDir: str, httpPrefix: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def receiveUndo(session, baseDir: str, httpPrefix: str,
|
def _receiveUndo(session, baseDir: str, httpPrefix: str,
|
||||||
port: int, sendThreads: [], postLog: [],
|
port: int, sendThreads: [], postLog: [],
|
||||||
cachedWebfingers: {}, personCache: {},
|
cachedWebfingers: {}, personCache: {},
|
||||||
messageJson: {}, federationList: [],
|
messageJson: {}, federationList: [],
|
||||||
|
|
@ -698,13 +698,13 @@ def receiveUndo(session, baseDir: str, httpPrefix: str,
|
||||||
' object within object is not a string')
|
' object within object is not a string')
|
||||||
return False
|
return False
|
||||||
if messageJson['object']['type'] == 'Follow':
|
if messageJson['object']['type'] == 'Follow':
|
||||||
return receiveUndoFollow(session, baseDir, httpPrefix,
|
return _receiveUndoFollow(session, baseDir, httpPrefix,
|
||||||
port, messageJson,
|
port, messageJson,
|
||||||
federationList, debug)
|
federationList, debug)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def receiveEventPost(recentPostsCache: {}, session, baseDir: str,
|
def _receiveEventPost(recentPostsCache: {}, session, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
personCache: {}, messageJson: {}, federationList: [],
|
personCache: {}, messageJson: {}, federationList: [],
|
||||||
|
|
@ -723,11 +723,12 @@ def receiveEventPost(recentPostsCache: {}, session, baseDir: str,
|
||||||
saveEventPost(baseDir, handle, postId, messageJson['object'])
|
saveEventPost(baseDir, handle, postId, messageJson['object'])
|
||||||
|
|
||||||
|
|
||||||
def personReceiveUpdate(baseDir: str,
|
def _personReceiveUpdate(baseDir: str,
|
||||||
domain: str, port: int,
|
domain: str, port: int,
|
||||||
updateNickname: str, updateDomain: str,
|
updateNickname: str, updateDomain: str,
|
||||||
updatePort: int,
|
updatePort: int,
|
||||||
personJson: {}, personCache: {}, debug: bool) -> bool:
|
personJson: {}, personCache: {},
|
||||||
|
debug: bool) -> bool:
|
||||||
"""Changes an actor. eg: avatar or display name change
|
"""Changes an actor. eg: avatar or display name change
|
||||||
"""
|
"""
|
||||||
print('Receiving actor update for ' + personJson['url'] +
|
print('Receiving actor update for ' + personJson['url'] +
|
||||||
|
|
@ -795,8 +796,9 @@ def personReceiveUpdate(baseDir: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveUpdateToQuestion(recentPostsCache: {}, messageJson: {},
|
def _receiveUpdateToQuestion(recentPostsCache: {}, messageJson: {},
|
||||||
baseDir: str, nickname: str, domain: str) -> None:
|
baseDir: str,
|
||||||
|
nickname: str, domain: str) -> None:
|
||||||
"""Updating a question as new votes arrive
|
"""Updating a question as new votes arrive
|
||||||
"""
|
"""
|
||||||
# message url of the question
|
# message url of the question
|
||||||
|
|
@ -832,7 +834,7 @@ def receiveUpdateToQuestion(recentPostsCache: {}, messageJson: {},
|
||||||
removePostFromCache(messageJson, recentPostsCache)
|
removePostFromCache(messageJson, recentPostsCache)
|
||||||
|
|
||||||
|
|
||||||
def receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
def _receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
personCache: {}, messageJson: {}, federationList: [],
|
personCache: {}, messageJson: {}, federationList: [],
|
||||||
|
|
@ -867,7 +869,7 @@ def receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if messageJson['object']['type'] == 'Question':
|
if messageJson['object']['type'] == 'Question':
|
||||||
receiveUpdateToQuestion(recentPostsCache, messageJson,
|
_receiveUpdateToQuestion(recentPostsCache, messageJson,
|
||||||
baseDir, nickname, domain)
|
baseDir, nickname, domain)
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Question update was received')
|
print('DEBUG: Question update was received')
|
||||||
|
|
@ -880,7 +882,7 @@ def receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
if updateNickname:
|
if updateNickname:
|
||||||
updateDomain, updatePort = \
|
updateDomain, updatePort = \
|
||||||
getDomainFromActor(messageJson['id'])
|
getDomainFromActor(messageJson['id'])
|
||||||
if personReceiveUpdate(baseDir, domain, port,
|
if _personReceiveUpdate(baseDir, domain, port,
|
||||||
updateNickname, updateDomain,
|
updateNickname, updateDomain,
|
||||||
updatePort, messageJson,
|
updatePort, messageJson,
|
||||||
personCache, debug):
|
personCache, debug):
|
||||||
|
|
@ -901,7 +903,7 @@ def receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
if updateNickname:
|
if updateNickname:
|
||||||
updateDomain, updatePort = \
|
updateDomain, updatePort = \
|
||||||
getDomainFromActor(messageJson['actor'])
|
getDomainFromActor(messageJson['actor'])
|
||||||
if personReceiveUpdate(baseDir,
|
if _personReceiveUpdate(baseDir,
|
||||||
domain, port,
|
domain, port,
|
||||||
updateNickname, updateDomain,
|
updateNickname, updateDomain,
|
||||||
updatePort,
|
updatePort,
|
||||||
|
|
@ -914,7 +916,7 @@ def receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def receiveLike(recentPostsCache: {},
|
def _receiveLike(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
onionDomain: str,
|
onionDomain: str,
|
||||||
|
|
@ -968,7 +970,7 @@ def receiveLike(recentPostsCache: {},
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: liked post found in inbox')
|
print('DEBUG: liked post found in inbox')
|
||||||
|
|
||||||
if not alreadyLiked(baseDir,
|
if not _alreadyLiked(baseDir,
|
||||||
handle.split('@')[0],
|
handle.split('@')[0],
|
||||||
handle.split('@')[1],
|
handle.split('@')[1],
|
||||||
messageJson['object'],
|
messageJson['object'],
|
||||||
|
|
@ -976,12 +978,12 @@ def receiveLike(recentPostsCache: {},
|
||||||
updateLikesCollection(recentPostsCache, baseDir, postFilename,
|
updateLikesCollection(recentPostsCache, baseDir, postFilename,
|
||||||
messageJson['object'],
|
messageJson['object'],
|
||||||
messageJson['actor'], domain, debug)
|
messageJson['actor'], domain, debug)
|
||||||
likeNotify(baseDir, domain, onionDomain, handle,
|
_likeNotify(baseDir, domain, onionDomain, handle,
|
||||||
messageJson['actor'], messageJson['object'])
|
messageJson['actor'], messageJson['object'])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveUndoLike(recentPostsCache: {},
|
def _receiveUndoLike(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
|
|
@ -1042,7 +1044,7 @@ def receiveUndoLike(recentPostsCache: {},
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveBookmark(recentPostsCache: {},
|
def _receiveBookmark(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
|
|
@ -1108,7 +1110,7 @@ def receiveBookmark(recentPostsCache: {},
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveUndoBookmark(recentPostsCache: {},
|
def _receiveUndoBookmark(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
|
|
@ -1177,7 +1179,7 @@ def receiveUndoBookmark(recentPostsCache: {},
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveDelete(session, handle: str, isGroup: bool, baseDir: str,
|
def _receiveDelete(session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
personCache: {}, messageJson: {}, federationList: [],
|
personCache: {}, messageJson: {}, federationList: [],
|
||||||
|
|
@ -1263,9 +1265,10 @@ def receiveDelete(session, handle: str, isGroup: bool, baseDir: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveAnnounce(recentPostsCache: {},
|
def _receiveAnnounce(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, onionDomain: str, port: int,
|
httpPrefix: str,
|
||||||
|
domain: str, onionDomain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
personCache: {}, messageJson: {}, federationList: [],
|
personCache: {}, messageJson: {}, federationList: [],
|
||||||
debug: bool, translate: {},
|
debug: bool, translate: {},
|
||||||
|
|
@ -1410,7 +1413,7 @@ def receiveAnnounce(recentPostsCache: {},
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def receiveUndoAnnounce(recentPostsCache: {},
|
def _receiveUndoAnnounce(recentPostsCache: {},
|
||||||
session, handle: str, isGroup: bool, baseDir: str,
|
session, handle: str, isGroup: bool, baseDir: str,
|
||||||
httpPrefix: str, domain: str, port: int,
|
httpPrefix: str, domain: str, port: int,
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
|
|
@ -1482,7 +1485,7 @@ def jsonPostAllowsComments(postJsonObject: {}) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def postAllowsComments(postFilename: str) -> bool:
|
def _postAllowsComments(postFilename: str) -> bool:
|
||||||
"""Returns true if the given post allows comments/replies
|
"""Returns true if the given post allows comments/replies
|
||||||
"""
|
"""
|
||||||
postJsonObject = loadJson(postFilename)
|
postJsonObject = loadJson(postFilename)
|
||||||
|
|
@ -1533,7 +1536,7 @@ def populateReplies(baseDir: str, httpPrefix: str, domain: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: post may have expired - ' + replyTo)
|
print('DEBUG: post may have expired - ' + replyTo)
|
||||||
return False
|
return False
|
||||||
if not postAllowsComments(postFilename):
|
if not _postAllowsComments(postFilename):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: post does not allow comments - ' + replyTo)
|
print('DEBUG: post does not allow comments - ' + replyTo)
|
||||||
return False
|
return False
|
||||||
|
|
@ -1555,19 +1558,19 @@ def populateReplies(baseDir: str, httpPrefix: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def estimateNumberOfMentions(content: str) -> int:
|
def _estimateNumberOfMentions(content: str) -> int:
|
||||||
"""Returns a rough estimate of the number of mentions
|
"""Returns a rough estimate of the number of mentions
|
||||||
"""
|
"""
|
||||||
return int(content.count('@') / 2)
|
return int(content.count('@') / 2)
|
||||||
|
|
||||||
|
|
||||||
def estimateNumberOfEmoji(content: str) -> int:
|
def _estimateNumberOfEmoji(content: str) -> int:
|
||||||
"""Returns a rough estimate of the number of emoji
|
"""Returns a rough estimate of the number of emoji
|
||||||
"""
|
"""
|
||||||
return int(content.count(':') / 2)
|
return int(content.count(':') / 2)
|
||||||
|
|
||||||
|
|
||||||
def validPostContent(baseDir: str, nickname: str, domain: str,
|
def _validPostContent(baseDir: str, nickname: str, domain: str,
|
||||||
messageJson: {}, maxMentions: int, maxEmoji: int,
|
messageJson: {}, maxMentions: int, maxEmoji: int,
|
||||||
allowLocalNetworkAccess: bool) -> bool:
|
allowLocalNetworkAccess: bool) -> bool:
|
||||||
"""Is the content of a received post valid?
|
"""Is the content of a received post valid?
|
||||||
|
|
@ -1615,14 +1618,14 @@ def validPostContent(baseDir: str, nickname: str, domain: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# check (rough) number of mentions
|
# check (rough) number of mentions
|
||||||
mentionsEst = estimateNumberOfMentions(messageJson['object']['content'])
|
mentionsEst = _estimateNumberOfMentions(messageJson['object']['content'])
|
||||||
if mentionsEst > maxMentions:
|
if mentionsEst > maxMentions:
|
||||||
if messageJson['object'].get('id'):
|
if messageJson['object'].get('id'):
|
||||||
print('REJECT HELLTHREAD: ' + messageJson['object']['id'])
|
print('REJECT HELLTHREAD: ' + messageJson['object']['id'])
|
||||||
print('REJECT HELLTHREAD: Too many mentions in post - ' +
|
print('REJECT HELLTHREAD: Too many mentions in post - ' +
|
||||||
messageJson['object']['content'])
|
messageJson['object']['content'])
|
||||||
return False
|
return False
|
||||||
if estimateNumberOfEmoji(messageJson['object']['content']) > maxEmoji:
|
if _estimateNumberOfEmoji(messageJson['object']['content']) > maxEmoji:
|
||||||
if messageJson['object'].get('id'):
|
if messageJson['object'].get('id'):
|
||||||
print('REJECT EMOJI OVERLOAD: ' + messageJson['object']['id'])
|
print('REJECT EMOJI OVERLOAD: ' + messageJson['object']['id'])
|
||||||
print('REJECT EMOJI OVERLOAD: Too many emoji in post - ' +
|
print('REJECT EMOJI OVERLOAD: Too many emoji in post - ' +
|
||||||
|
|
@ -1650,7 +1653,7 @@ def validPostContent(baseDir: str, nickname: str, domain: str,
|
||||||
postPostFilename = locatePost(baseDir, nickname, domain,
|
postPostFilename = locatePost(baseDir, nickname, domain,
|
||||||
originalPostId)
|
originalPostId)
|
||||||
if postPostFilename:
|
if postPostFilename:
|
||||||
if not postAllowsComments(postPostFilename):
|
if not _postAllowsComments(postPostFilename):
|
||||||
print('REJECT: reply to post which does not ' +
|
print('REJECT: reply to post which does not ' +
|
||||||
'allow comments: ' + originalPostId)
|
'allow comments: ' + originalPostId)
|
||||||
return False
|
return False
|
||||||
|
|
@ -1658,7 +1661,7 @@ def validPostContent(baseDir: str, nickname: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
|
def _obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
|
||||||
domain: str, onionDomain: str, personCache: {},
|
domain: str, onionDomain: str, personCache: {},
|
||||||
postJsonObject: {}, debug: bool) -> None:
|
postJsonObject: {}, debug: bool) -> None:
|
||||||
"""Tries to obtain the actor for the person being replied to
|
"""Tries to obtain the actor for the person being replied to
|
||||||
|
|
@ -1708,7 +1711,7 @@ def obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
|
|
||||||
def dmNotify(baseDir: str, handle: str, url: str) -> None:
|
def _dmNotify(baseDir: str, handle: str, url: str) -> None:
|
||||||
"""Creates a notification that a new DM has arrived
|
"""Creates a notification that a new DM has arrived
|
||||||
"""
|
"""
|
||||||
accountDir = baseDir + '/accounts/' + handle
|
accountDir = baseDir + '/accounts/' + handle
|
||||||
|
|
@ -1720,7 +1723,7 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None:
|
||||||
fp.write(url)
|
fp.write(url)
|
||||||
|
|
||||||
|
|
||||||
def alreadyLiked(baseDir: str, nickname: str, domain: str,
|
def _alreadyLiked(baseDir: str, nickname: str, domain: str,
|
||||||
postUrl: str, likerActor: str) -> bool:
|
postUrl: str, likerActor: str) -> bool:
|
||||||
"""Is the given post already liked by the given handle?
|
"""Is the given post already liked by the given handle?
|
||||||
"""
|
"""
|
||||||
|
|
@ -1751,7 +1754,7 @@ def alreadyLiked(baseDir: str, nickname: str, domain: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def likeNotify(baseDir: str, domain: str, onionDomain: str,
|
def _likeNotify(baseDir: str, domain: str, onionDomain: str,
|
||||||
handle: str, actor: str, url: str) -> None:
|
handle: str, actor: str, url: str) -> None:
|
||||||
"""Creates a notification that a like has arrived
|
"""Creates a notification that a like has arrived
|
||||||
"""
|
"""
|
||||||
|
|
@ -1784,7 +1787,7 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str,
|
||||||
if likerNickname and likerDomain:
|
if likerNickname and likerDomain:
|
||||||
likerHandle = likerNickname + '@' + likerDomain
|
likerHandle = likerNickname + '@' + likerDomain
|
||||||
else:
|
else:
|
||||||
print('likeNotify likerHandle: ' +
|
print('_likeNotify likerHandle: ' +
|
||||||
str(likerNickname) + '@' + str(likerDomain))
|
str(likerNickname) + '@' + str(likerDomain))
|
||||||
likerHandle = actor
|
likerHandle = actor
|
||||||
if likerHandle != handle:
|
if likerHandle != handle:
|
||||||
|
|
@ -1813,7 +1816,7 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str,
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def replyNotify(baseDir: str, handle: str, url: str) -> None:
|
def _replyNotify(baseDir: str, handle: str, url: str) -> None:
|
||||||
"""Creates a notification that a new reply has arrived
|
"""Creates a notification that a new reply has arrived
|
||||||
"""
|
"""
|
||||||
accountDir = baseDir + '/accounts/' + handle
|
accountDir = baseDir + '/accounts/' + handle
|
||||||
|
|
@ -1825,7 +1828,7 @@ def replyNotify(baseDir: str, handle: str, url: str) -> None:
|
||||||
fp.write(url)
|
fp.write(url)
|
||||||
|
|
||||||
|
|
||||||
def gitPatchNotify(baseDir: str, handle: str,
|
def _gitPatchNotify(baseDir: str, handle: str,
|
||||||
subject: str, content: str,
|
subject: str, content: str,
|
||||||
fromNickname: str, fromDomain: str) -> None:
|
fromNickname: str, fromDomain: str) -> None:
|
||||||
"""Creates a notification that a new git patch has arrived
|
"""Creates a notification that a new git patch has arrived
|
||||||
|
|
@ -1840,7 +1843,7 @@ def gitPatchNotify(baseDir: str, handle: str,
|
||||||
fp.write('git ' + handle + ' ' + subject)
|
fp.write('git ' + handle + ' ' + subject)
|
||||||
|
|
||||||
|
|
||||||
def groupHandle(baseDir: str, handle: str) -> bool:
|
def _groupHandle(baseDir: str, handle: str) -> bool:
|
||||||
"""Is the given account handle a group?
|
"""Is the given account handle a group?
|
||||||
"""
|
"""
|
||||||
actorFile = baseDir + '/accounts/' + handle + '.json'
|
actorFile = baseDir + '/accounts/' + handle + '.json'
|
||||||
|
|
@ -1852,7 +1855,7 @@ def groupHandle(baseDir: str, handle: str) -> bool:
|
||||||
return actorJson['type'] == 'Group'
|
return actorJson['type'] == 'Group'
|
||||||
|
|
||||||
|
|
||||||
def getGroupName(baseDir: str, handle: str) -> str:
|
def _getGroupName(baseDir: str, handle: str) -> str:
|
||||||
"""Returns the preferred name of a group
|
"""Returns the preferred name of a group
|
||||||
"""
|
"""
|
||||||
actorFile = baseDir + '/accounts/' + handle + '.json'
|
actorFile = baseDir + '/accounts/' + handle + '.json'
|
||||||
|
|
@ -1864,7 +1867,7 @@ def getGroupName(baseDir: str, handle: str) -> str:
|
||||||
return actorJson['name']
|
return actorJson['name']
|
||||||
|
|
||||||
|
|
||||||
def sendToGroupMembers(session, baseDir: str, handle: str, port: int,
|
def _sendToGroupMembers(session, baseDir: str, handle: str, port: int,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
httpPrefix: str, federationList: [],
|
httpPrefix: str, federationList: [],
|
||||||
sendThreads: [], postLog: [], cachedWebfingers: {},
|
sendThreads: [], postLog: [], cachedWebfingers: {},
|
||||||
|
|
@ -1877,7 +1880,7 @@ def sendToGroupMembers(session, baseDir: str, handle: str, port: int,
|
||||||
if not postJsonObject.get('object'):
|
if not postJsonObject.get('object'):
|
||||||
return
|
return
|
||||||
nickname = handle.split('@')[0]
|
nickname = handle.split('@')[0]
|
||||||
# groupname = getGroupName(baseDir, handle)
|
# groupname = _getGroupName(baseDir, handle)
|
||||||
domain = handle.split('@')[1]
|
domain = handle.split('@')[1]
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
# set sender
|
# set sender
|
||||||
|
|
@ -1941,7 +1944,8 @@ def sendToGroupMembers(session, baseDir: str, handle: str, port: int,
|
||||||
personCache, debug, __version__)
|
personCache, debug, __version__)
|
||||||
|
|
||||||
|
|
||||||
def inboxUpdateCalendar(baseDir: str, handle: str, postJsonObject: {}) -> None:
|
def _inboxUpdateCalendar(baseDir: str, handle: str,
|
||||||
|
postJsonObject: {}) -> None:
|
||||||
"""Detects whether the tag list on a post contains calendar events
|
"""Detects whether the tag list on a post contains calendar events
|
||||||
and if so saves the post id to a file in the calendar directory
|
and if so saves the post id to a file in the calendar directory
|
||||||
for the account
|
for the account
|
||||||
|
|
@ -2017,7 +2021,7 @@ def inboxUpdateIndex(boxname: str, baseDir: str, handle: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def updateLastSeen(baseDir: str, handle: str, actor: str) -> None:
|
def _updateLastSeen(baseDir: str, handle: str, actor: str) -> None:
|
||||||
"""Updates the time when the given handle last saw the given actor
|
"""Updates the time when the given handle last saw the given actor
|
||||||
This can later be used to indicate if accounts are dormant/abandoned/moved
|
This can later be used to indicate if accounts are dormant/abandoned/moved
|
||||||
"""
|
"""
|
||||||
|
|
@ -2049,7 +2053,7 @@ def updateLastSeen(baseDir: str, handle: str, actor: str) -> None:
|
||||||
lastSeenFile.write(str(daysSinceEpoch))
|
lastSeenFile.write(str(daysSinceEpoch))
|
||||||
|
|
||||||
|
|
||||||
def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
session, keyId: str, handle: str, messageJson: {},
|
session, keyId: str, handle: str, messageJson: {},
|
||||||
baseDir: str, httpPrefix: str, sendThreads: [],
|
baseDir: str, httpPrefix: str, sendThreads: [],
|
||||||
postLog: [], cachedWebfingers: {}, personCache: {},
|
postLog: [], cachedWebfingers: {}, personCache: {},
|
||||||
|
|
@ -2069,11 +2073,11 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
if '#' in actor:
|
if '#' in actor:
|
||||||
actor = keyId.split('#')[0]
|
actor = keyId.split('#')[0]
|
||||||
|
|
||||||
updateLastSeen(baseDir, handle, actor)
|
_updateLastSeen(baseDir, handle, actor)
|
||||||
|
|
||||||
isGroup = groupHandle(baseDir, handle)
|
isGroup = _groupHandle(baseDir, handle)
|
||||||
|
|
||||||
if receiveLike(recentPostsCache,
|
if _receiveLike(recentPostsCache,
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
|
|
@ -2088,7 +2092,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('DEBUG: Like accepted from ' + actor)
|
print('DEBUG: Like accepted from ' + actor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiveUndoLike(recentPostsCache,
|
if _receiveUndoLike(recentPostsCache,
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
|
|
@ -2102,7 +2106,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('DEBUG: Undo like accepted from ' + actor)
|
print('DEBUG: Undo like accepted from ' + actor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiveBookmark(recentPostsCache,
|
if _receiveBookmark(recentPostsCache,
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
|
|
@ -2116,7 +2120,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('DEBUG: Bookmark accepted from ' + actor)
|
print('DEBUG: Bookmark accepted from ' + actor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiveUndoBookmark(recentPostsCache,
|
if _receiveUndoBookmark(recentPostsCache,
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
|
|
@ -2130,9 +2134,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('DEBUG: Undo bookmark accepted from ' + actor)
|
print('DEBUG: Undo bookmark accepted from ' + actor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# labelAccusatoryPost(messageJson, translate)
|
if _receiveAnnounce(recentPostsCache,
|
||||||
|
|
||||||
if receiveAnnounce(recentPostsCache,
|
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, onionDomain, port,
|
domain, onionDomain, port,
|
||||||
|
|
@ -2146,7 +2148,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Announce accepted from ' + actor)
|
print('DEBUG: Announce accepted from ' + actor)
|
||||||
|
|
||||||
if receiveUndoAnnounce(recentPostsCache,
|
if _receiveUndoAnnounce(recentPostsCache,
|
||||||
session, handle, isGroup,
|
session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
|
|
@ -2160,7 +2162,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('DEBUG: Undo announce accepted from ' + actor)
|
print('DEBUG: Undo announce accepted from ' + actor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if receiveDelete(session, handle, isGroup,
|
if _receiveDelete(session, handle, isGroup,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
sendThreads, postLog,
|
sendThreads, postLog,
|
||||||
|
|
@ -2188,7 +2190,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
postJsonObject = messageJson
|
postJsonObject = messageJson
|
||||||
|
|
||||||
nickname = handle.split('@')[0]
|
nickname = handle.split('@')[0]
|
||||||
if validPostContent(baseDir, nickname, domain,
|
if _validPostContent(baseDir, nickname, domain,
|
||||||
postJsonObject, maxMentions, maxEmoji,
|
postJsonObject, maxMentions, maxEmoji,
|
||||||
allowLocalNetworkAccess):
|
allowLocalNetworkAccess):
|
||||||
|
|
||||||
|
|
@ -2213,7 +2215,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
jsonObj['summary'],
|
jsonObj['summary'],
|
||||||
jsonObj['content'],
|
jsonObj['content'],
|
||||||
fromNickname, fromDomain):
|
fromNickname, fromDomain):
|
||||||
gitPatchNotify(baseDir, handle,
|
_gitPatchNotify(baseDir, handle,
|
||||||
jsonObj['summary'],
|
jsonObj['summary'],
|
||||||
jsonObj['content'],
|
jsonObj['content'],
|
||||||
fromNickname, fromDomain)
|
fromNickname, fromDomain)
|
||||||
|
|
@ -2293,7 +2295,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
return False
|
return False
|
||||||
# dm index will be updated
|
# dm index will be updated
|
||||||
updateIndexList.append('dm')
|
updateIndexList.append('dm')
|
||||||
dmNotify(baseDir, handle,
|
_dmNotify(baseDir, handle,
|
||||||
httpPrefix + '://' + domain + '/users/' +
|
httpPrefix + '://' + domain + '/users/' +
|
||||||
nickname + '/dm')
|
nickname + '/dm')
|
||||||
|
|
||||||
|
|
@ -2313,7 +2315,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
if isinstance(inReplyTo, str):
|
if isinstance(inReplyTo, str):
|
||||||
if not isMuted(baseDir, nickname, domain,
|
if not isMuted(baseDir, nickname, domain,
|
||||||
inReplyTo):
|
inReplyTo):
|
||||||
replyNotify(baseDir, handle,
|
_replyNotify(baseDir, handle,
|
||||||
httpPrefix + '://' + domain +
|
httpPrefix + '://' + domain +
|
||||||
'/users/' + nickname +
|
'/users/' + nickname +
|
||||||
'/tlreplies')
|
'/tlreplies')
|
||||||
|
|
@ -2333,7 +2335,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
updateIndexList.append('tlevents')
|
updateIndexList.append('tlevents')
|
||||||
|
|
||||||
# get the avatar for a reply/announce
|
# get the avatar for a reply/announce
|
||||||
obtainAvatarForReplyPost(session, baseDir,
|
_obtainAvatarForReplyPost(session, baseDir,
|
||||||
httpPrefix, domain, onionDomain,
|
httpPrefix, domain, onionDomain,
|
||||||
personCache, postJsonObject, debug)
|
personCache, postJsonObject, debug)
|
||||||
|
|
||||||
|
|
@ -2359,7 +2361,7 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
print('Saving inbox post as html to cache')
|
print('Saving inbox post as html to cache')
|
||||||
|
|
||||||
htmlCacheStartTime = time.time()
|
htmlCacheStartTime = time.time()
|
||||||
inboxStorePostToHtmlCache(recentPostsCache,
|
_inboxStorePostToHtmlCache(recentPostsCache,
|
||||||
maxRecentPosts,
|
maxRecentPosts,
|
||||||
translate, baseDir,
|
translate, baseDir,
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
|
|
@ -2379,13 +2381,13 @@ def inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
' post as html to cache in ' +
|
' post as html to cache in ' +
|
||||||
timeDiff + ' mS')
|
timeDiff + ' mS')
|
||||||
|
|
||||||
inboxUpdateCalendar(baseDir, handle, postJsonObject)
|
_inboxUpdateCalendar(baseDir, handle, postJsonObject)
|
||||||
|
|
||||||
storeHashTags(baseDir, handle.split('@')[0], postJsonObject)
|
storeHashTags(baseDir, handle.split('@')[0], postJsonObject)
|
||||||
|
|
||||||
# send the post out to group members
|
# send the post out to group members
|
||||||
if isGroup:
|
if isGroup:
|
||||||
sendToGroupMembers(session, baseDir, handle, port,
|
_sendToGroupMembers(session, baseDir, handle, port,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
httpPrefix, federationList, sendThreads,
|
httpPrefix, federationList, sendThreads,
|
||||||
postLog, cachedWebfingers, personCache,
|
postLog, cachedWebfingers, personCache,
|
||||||
|
|
@ -2420,7 +2422,7 @@ def clearQueueItems(baseDir: str, queue: []) -> None:
|
||||||
print('Removed ' + str(ctr) + ' inbox queue items')
|
print('Removed ' + str(ctr) + ' inbox queue items')
|
||||||
|
|
||||||
|
|
||||||
def restoreQueueItems(baseDir: str, queue: []) -> None:
|
def _restoreQueueItems(baseDir: str, queue: []) -> None:
|
||||||
"""Checks the queue for each account and appends filenames
|
"""Checks the queue for each account and appends filenames
|
||||||
"""
|
"""
|
||||||
queue.clear()
|
queue.clear()
|
||||||
|
|
@ -2483,7 +2485,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
|
|
||||||
# if queue processing was interrupted (eg server crash)
|
# if queue processing was interrupted (eg server crash)
|
||||||
# then this loads any outstanding items back into the queue
|
# then this loads any outstanding items back into the queue
|
||||||
restoreQueueItems(baseDir, queue)
|
_restoreQueueItems(baseDir, queue)
|
||||||
|
|
||||||
# keep track of numbers of incoming posts per day
|
# keep track of numbers of incoming posts per day
|
||||||
quotasLastUpdateDaily = int(time.time())
|
quotasLastUpdateDaily = int(time.time())
|
||||||
|
|
@ -2515,7 +2517,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
queueRestoreCtr += 1
|
queueRestoreCtr += 1
|
||||||
if queueRestoreCtr >= 30:
|
if queueRestoreCtr >= 30:
|
||||||
queueRestoreCtr = 0
|
queueRestoreCtr = 0
|
||||||
restoreQueueItems(baseDir, queue)
|
_restoreQueueItems(baseDir, queue)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
currTime = int(time.time())
|
currTime = int(time.time())
|
||||||
|
|
@ -2731,7 +2733,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
# if queueJson['post'].get('id'):
|
# if queueJson['post'].get('id'):
|
||||||
# queueJson['post']['id']=queueJson['id']
|
# queueJson['post']['id']=queueJson['id']
|
||||||
|
|
||||||
if receiveUndo(session,
|
if _receiveUndo(session,
|
||||||
baseDir, httpPrefix, port,
|
baseDir, httpPrefix, port,
|
||||||
sendThreads, postLog,
|
sendThreads, postLog,
|
||||||
cachedWebfingers,
|
cachedWebfingers,
|
||||||
|
|
@ -2782,7 +2784,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
queue.pop(0)
|
queue.pop(0)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if receiveEventPost(recentPostsCache, session,
|
if _receiveEventPost(recentPostsCache, session,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
sendThreads, postLog,
|
sendThreads, postLog,
|
||||||
|
|
@ -2799,7 +2801,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
queue.pop(0)
|
queue.pop(0)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if receiveUpdate(recentPostsCache, session,
|
if _receiveUpdate(recentPostsCache, session,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
domain, port,
|
domain, port,
|
||||||
sendThreads, postLog,
|
sendThreads, postLog,
|
||||||
|
|
@ -2818,7 +2820,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
|
|
||||||
# get recipients list
|
# get recipients list
|
||||||
recipientsDict, recipientsDictFollowers = \
|
recipientsDict, recipientsDictFollowers = \
|
||||||
inboxPostRecipients(baseDir, queueJson['post'],
|
_inboxPostRecipients(baseDir, queueJson['post'],
|
||||||
httpPrefix, domain, port, debug)
|
httpPrefix, domain, port, debug)
|
||||||
if len(recipientsDict.items()) == 0 and \
|
if len(recipientsDict.items()) == 0 and \
|
||||||
len(recipientsDictFollowers.items()) == 0:
|
len(recipientsDictFollowers.items()) == 0:
|
||||||
|
|
@ -2866,7 +2868,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
for handle, capsId in recipientsDict.items():
|
for handle, capsId in recipientsDict.items():
|
||||||
destination = \
|
destination = \
|
||||||
queueJson['destination'].replace(inboxHandle, handle)
|
queueJson['destination'].replace(inboxHandle, handle)
|
||||||
inboxAfterInitial(recentPostsCache,
|
_inboxAfterInitial(recentPostsCache,
|
||||||
maxRecentPosts,
|
maxRecentPosts,
|
||||||
session, keyId, handle,
|
session, keyId, handle,
|
||||||
queueJson['post'],
|
queueJson['post'],
|
||||||
|
|
|
||||||
36
jsonldsig.py
36
jsonldsig.py
|
|
@ -28,21 +28,21 @@ import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
def b64safeEncode(payload: {}) -> str:
|
def _b64safeEncode(payload: {}) -> str:
|
||||||
"""
|
"""
|
||||||
b64 url safe encoding with the padding removed.
|
b64 url safe encoding with the padding removed.
|
||||||
"""
|
"""
|
||||||
return base64.urlsafe_b64encode(payload).rstrip(b'=')
|
return base64.urlsafe_b64encode(payload).rstrip(b'=')
|
||||||
|
|
||||||
|
|
||||||
def b64safeDecode(payload: {}) -> str:
|
def _b64safeDecode(payload: {}) -> str:
|
||||||
"""
|
"""
|
||||||
b64 url safe decoding with the padding added.
|
b64 url safe decoding with the padding added.
|
||||||
"""
|
"""
|
||||||
return base64.urlsafe_b64decode(payload + b'=' * (4 - len(payload) % 4))
|
return base64.urlsafe_b64decode(payload + b'=' * (4 - len(payload) % 4))
|
||||||
|
|
||||||
|
|
||||||
def normalizeJson(payload: {}) -> str:
|
def _normalizeJson(payload: {}) -> str:
|
||||||
"""
|
"""
|
||||||
Normalize with URDNA2015
|
Normalize with URDNA2015
|
||||||
"""
|
"""
|
||||||
|
|
@ -50,7 +50,7 @@ def normalizeJson(payload: {}) -> str:
|
||||||
sort_keys=True).encode('utf-8')
|
sort_keys=True).encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
def signRs256(payload: {}, privateKeyPem: str) -> str:
|
def _signRs256(payload: {}, privateKeyPem: str) -> str:
|
||||||
"""
|
"""
|
||||||
Produce a RS256 signature of the payload
|
Produce a RS256 signature of the payload
|
||||||
"""
|
"""
|
||||||
|
|
@ -60,7 +60,7 @@ def signRs256(payload: {}, privateKeyPem: str) -> str:
|
||||||
return signature
|
return signature
|
||||||
|
|
||||||
|
|
||||||
def verifyRs256(payload: {}, signature: str, publicKeyPem: str) -> bool:
|
def _verifyRs256(payload: {}, signature: str, publicKeyPem: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Verifies a RS256 signature
|
Verifies a RS256 signature
|
||||||
"""
|
"""
|
||||||
|
|
@ -69,7 +69,7 @@ def verifyRs256(payload: {}, signature: str, publicKeyPem: str) -> bool:
|
||||||
return verifier.verify(SHA256.new(payload), signature)
|
return verifier.verify(SHA256.new(payload), signature)
|
||||||
|
|
||||||
|
|
||||||
def signJws(payload: {}, privateKeyPem: str) -> str:
|
def _signJws(payload: {}, privateKeyPem: str) -> str:
|
||||||
"""
|
"""
|
||||||
Prepare payload to sign
|
Prepare payload to sign
|
||||||
"""
|
"""
|
||||||
|
|
@ -78,28 +78,28 @@ def signJws(payload: {}, privateKeyPem: str) -> str:
|
||||||
'b64': False,
|
'b64': False,
|
||||||
'crit': ['b64']
|
'crit': ['b64']
|
||||||
}
|
}
|
||||||
normalizedJson = normalizeJson(header)
|
normalizedJson = _normalizeJson(header)
|
||||||
encodedHeader = b64safeEncode(normalizedJson)
|
encodedHeader = _b64safeEncode(normalizedJson)
|
||||||
preparedPayload = b'.'.join([encodedHeader, payload])
|
preparedPayload = b'.'.join([encodedHeader, payload])
|
||||||
|
|
||||||
signature = signRs256(preparedPayload, privateKeyPem)
|
signature = _signRs256(preparedPayload, privateKeyPem)
|
||||||
encodedSignature = b64safeEncode(signature)
|
encodedSignature = _b64safeEncode(signature)
|
||||||
jwsSignature = b'..'.join([encodedHeader, encodedSignature])
|
jwsSignature = b'..'.join([encodedHeader, encodedSignature])
|
||||||
|
|
||||||
return jwsSignature
|
return jwsSignature
|
||||||
|
|
||||||
|
|
||||||
def verifyJws(payload: {}, jwsSignature: str, publicKeyPem: str) -> bool:
|
def _verifyJws(payload: {}, jwsSignature: str, publicKeyPem: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Verifies a signature using the given public key
|
Verifies a signature using the given public key
|
||||||
"""
|
"""
|
||||||
encodedHeader, encodedSignature = jwsSignature.split(b'..')
|
encodedHeader, encodedSignature = jwsSignature.split(b'..')
|
||||||
signature = b64safeDecode(encodedSignature)
|
signature = _b64safeDecode(encodedSignature)
|
||||||
payload = b'.'.join([encodedHeader, payload])
|
payload = b'.'.join([encodedHeader, payload])
|
||||||
return verifyRs256(payload, signature, publicKeyPem)
|
return _verifyRs256(payload, signature, publicKeyPem)
|
||||||
|
|
||||||
|
|
||||||
def jsonldNormalize(jldDocument: str):
|
def _jsonldNormalize(jldDocument: str):
|
||||||
"""
|
"""
|
||||||
Normalize and hash the json-ld document
|
Normalize and hash the json-ld document
|
||||||
"""
|
"""
|
||||||
|
|
@ -117,8 +117,8 @@ def jsonldSign(jldDocument: {}, privateKeyPem: str) -> {}:
|
||||||
Produces a signed JSON-LD document with a Json Web Signature
|
Produces a signed JSON-LD document with a Json Web Signature
|
||||||
"""
|
"""
|
||||||
jldDocument = deepcopy(jldDocument)
|
jldDocument = deepcopy(jldDocument)
|
||||||
normalizedJldHash = jsonldNormalize(jldDocument)
|
normalizedJldHash = _jsonldNormalize(jldDocument)
|
||||||
jwsSignature = signJws(normalizedJldHash, privateKeyPem)
|
jwsSignature = _signJws(normalizedJldHash, privateKeyPem)
|
||||||
|
|
||||||
# construct the signature document and add it to jsonld
|
# construct the signature document and add it to jsonld
|
||||||
signature = {
|
signature = {
|
||||||
|
|
@ -138,9 +138,9 @@ def jsonldVerify(signedJldDocument: {}, publicKeyPem: str) -> bool:
|
||||||
signedJldDocument = deepcopy(signedJldDocument)
|
signedJldDocument = deepcopy(signedJldDocument)
|
||||||
signature = signedJldDocument.pop('signature')
|
signature = signedJldDocument.pop('signature')
|
||||||
jwsSignature = signature['signatureValue'].encode('utf-8')
|
jwsSignature = signature['signatureValue'].encode('utf-8')
|
||||||
normalizedJldHash = jsonldNormalize(signedJldDocument)
|
normalizedJldHash = _jsonldNormalize(signedJldDocument)
|
||||||
|
|
||||||
return verifyJws(normalizedJldHash, jwsSignature, publicKeyPem)
|
return _verifyJws(normalizedJldHash, jwsSignature, publicKeyPem)
|
||||||
|
|
||||||
|
|
||||||
def testSignJsonld(jldDocument: {}, privateKeyPem: str) -> {}:
|
def testSignJsonld(jldDocument: {}, privateKeyPem: str) -> {}:
|
||||||
|
|
|
||||||
4
like.py
4
like.py
|
|
@ -50,7 +50,7 @@ def noOfLikes(postJsonObject: {}) -> int:
|
||||||
return len(postJsonObject['object']['likes']['items'])
|
return len(postJsonObject['object']['likes']['items'])
|
||||||
|
|
||||||
|
|
||||||
def like(recentPostsCache: {},
|
def _like(recentPostsCache: {},
|
||||||
session, baseDir: str, federationList: [],
|
session, baseDir: str, federationList: [],
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
ccList: [], httpPrefix: str,
|
ccList: [], httpPrefix: str,
|
||||||
|
|
@ -134,7 +134,7 @@ def likePost(recentPostsCache: {},
|
||||||
actorLiked = httpPrefix + '://' + likeDomain + '/users/' + likeNickname
|
actorLiked = httpPrefix + '://' + likeDomain + '/users/' + likeNickname
|
||||||
objectUrl = actorLiked + '/statuses/' + str(likeStatusNumber)
|
objectUrl = actorLiked + '/statuses/' + str(likeStatusNumber)
|
||||||
|
|
||||||
return like(recentPostsCache,
|
return _like(recentPostsCache,
|
||||||
session, baseDir, federationList, nickname, domain, port,
|
session, baseDir, federationList, nickname, domain, port,
|
||||||
ccList, httpPrefix, objectUrl, actorLiked, clientToServer,
|
ccList, httpPrefix, objectUrl, actorLiked, clientToServer,
|
||||||
sendThreads, postLog, personCache, cachedWebfingers,
|
sendThreads, postLog, personCache, cachedWebfingers,
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ def manualDenyFollowRequest(session, baseDir: str,
|
||||||
print('Follow request from ' + denyHandle + ' was denied.')
|
print('Follow request from ' + denyHandle + ' was denied.')
|
||||||
|
|
||||||
|
|
||||||
def approveFollowerHandle(accountDir: str, approveHandle: str) -> None:
|
def _approveFollowerHandle(accountDir: str, approveHandle: str) -> None:
|
||||||
""" Record manually approved handles so that if they unfollow and then
|
""" Record manually approved handles so that if they unfollow and then
|
||||||
re-follow later then they don't need to be manually approved again
|
re-follow later then they don't need to be manually approved again
|
||||||
"""
|
"""
|
||||||
|
|
@ -203,7 +203,7 @@ def manualApproveFollowRequest(session, baseDir: str,
|
||||||
# in followers.txt
|
# in followers.txt
|
||||||
if approveHandleFull in open(followersFilename).read():
|
if approveHandleFull in open(followersFilename).read():
|
||||||
# mark this handle as approved for following
|
# mark this handle as approved for following
|
||||||
approveFollowerHandle(accountDir, approveHandle)
|
_approveFollowerHandle(accountDir, approveHandle)
|
||||||
# update the follow requests with the handles not yet approved
|
# update the follow requests with the handles not yet approved
|
||||||
os.rename(approveFollowsFilename + '.new', approveFollowsFilename)
|
os.rename(approveFollowsFilename + '.new', approveFollowsFilename)
|
||||||
# remove the .follow file
|
# remove the .follow file
|
||||||
|
|
|
||||||
12
media.py
12
media.py
|
|
@ -56,12 +56,12 @@ def removeMetaData(imageFilename: str, outputFilename: str) -> None:
|
||||||
os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec
|
os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec
|
||||||
|
|
||||||
|
|
||||||
def getImageHash(imageFilename: str) -> str:
|
def _getImageHash(imageFilename: str) -> str:
|
||||||
value = numpy.array(Image.open(imageFilename).convert("RGB"))
|
value = numpy.array(Image.open(imageFilename).convert("RGB"))
|
||||||
return blurhash_encode(value)
|
return blurhash_encode(value)
|
||||||
|
|
||||||
|
|
||||||
def isMedia(imageFilename: str) -> bool:
|
def _isMedia(imageFilename: str) -> bool:
|
||||||
permittedMedia = getMediaExtensions()
|
permittedMedia = getMediaExtensions()
|
||||||
for m in permittedMedia:
|
for m in permittedMedia:
|
||||||
if imageFilename.endswith('.' + m):
|
if imageFilename.endswith('.' + m):
|
||||||
|
|
@ -103,7 +103,7 @@ def getAttachmentMediaType(filename: str) -> str:
|
||||||
return mediaType
|
return mediaType
|
||||||
|
|
||||||
|
|
||||||
def updateEtag(mediaFilename: str) -> None:
|
def _updateEtag(mediaFilename: str) -> None:
|
||||||
""" calculate the etag, which is a sha1 of the data
|
""" calculate the etag, which is a sha1 of the data
|
||||||
"""
|
"""
|
||||||
# only create etags for media
|
# only create etags for media
|
||||||
|
|
@ -143,7 +143,7 @@ def attachMedia(baseDir: str, httpPrefix: str, domain: str, port: int,
|
||||||
Blurhash is optional, since low power systems may take a long
|
Blurhash is optional, since low power systems may take a long
|
||||||
time to calculate it
|
time to calculate it
|
||||||
"""
|
"""
|
||||||
if not isMedia(imageFilename):
|
if not _isMedia(imageFilename):
|
||||||
return postJson
|
return postJson
|
||||||
|
|
||||||
fileExtension = None
|
fileExtension = None
|
||||||
|
|
@ -182,7 +182,7 @@ def attachMedia(baseDir: str, httpPrefix: str, domain: str, port: int,
|
||||||
if mediaType.startswith('image/'):
|
if mediaType.startswith('image/'):
|
||||||
attachmentJson['focialPoint'] = [0.0, 0.0]
|
attachmentJson['focialPoint'] = [0.0, 0.0]
|
||||||
if useBlurhash:
|
if useBlurhash:
|
||||||
attachmentJson['blurhash'] = getImageHash(imageFilename)
|
attachmentJson['blurhash'] = _getImageHash(imageFilename)
|
||||||
postJson['attachment'] = [attachmentJson]
|
postJson['attachment'] = [attachmentJson]
|
||||||
|
|
||||||
if baseDir:
|
if baseDir:
|
||||||
|
|
@ -190,7 +190,7 @@ def attachMedia(baseDir: str, httpPrefix: str, domain: str, port: int,
|
||||||
removeMetaData(imageFilename, mediaFilename)
|
removeMetaData(imageFilename, mediaFilename)
|
||||||
else:
|
else:
|
||||||
copyfile(imageFilename, mediaFilename)
|
copyfile(imageFilename, mediaFilename)
|
||||||
updateEtag(mediaFilename)
|
_updateEtag(mediaFilename)
|
||||||
|
|
||||||
return postJson
|
return postJson
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ __status__ = "Production"
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
def migrateFollows(followFilename: str, oldHandle: str,
|
def _migrateFollows(followFilename: str, oldHandle: str,
|
||||||
newHandle: str) -> None:
|
newHandle: str) -> None:
|
||||||
"""Changes a handle within following or followers list
|
"""Changes a handle within following or followers list
|
||||||
"""
|
"""
|
||||||
|
|
@ -48,7 +48,7 @@ def migrateAccount(baseDir: str, oldHandle: str, newHandle: str) -> None:
|
||||||
if '@' in handle:
|
if '@' in handle:
|
||||||
accountDir = baseDir + '/accounts/' + handle
|
accountDir = baseDir + '/accounts/' + handle
|
||||||
followFilename = accountDir + '/following.txt'
|
followFilename = accountDir + '/following.txt'
|
||||||
migrateFollows(followFilename, oldHandle, newHandle)
|
_migrateFollows(followFilename, oldHandle, newHandle)
|
||||||
followFilename = accountDir + '/followers.txt'
|
followFilename = accountDir + '/followers.txt'
|
||||||
migrateFollows(followFilename, oldHandle, newHandle)
|
_migrateFollows(followFilename, oldHandle, newHandle)
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ from inbox import storeHashTags
|
||||||
from session import createSession
|
from session import createSession
|
||||||
|
|
||||||
|
|
||||||
def updateFeedsOutboxIndex(baseDir: str, domain: str, postId: str) -> None:
|
def _updateFeedsOutboxIndex(baseDir: str, domain: str, postId: str) -> None:
|
||||||
"""Updates the index used for imported RSS feeds
|
"""Updates the index used for imported RSS feeds
|
||||||
"""
|
"""
|
||||||
basePath = baseDir + '/accounts/news@' + domain
|
basePath = baseDir + '/accounts/news@' + domain
|
||||||
|
|
@ -59,7 +59,7 @@ def updateFeedsOutboxIndex(baseDir: str, domain: str, postId: str) -> None:
|
||||||
feedsFile.close()
|
feedsFile.close()
|
||||||
|
|
||||||
|
|
||||||
def saveArrivedTime(baseDir: str, postFilename: str, arrived: str) -> None:
|
def _saveArrivedTime(baseDir: str, postFilename: str, arrived: str) -> None:
|
||||||
"""Saves the time when an rss post arrived to a file
|
"""Saves the time when an rss post arrived to a file
|
||||||
"""
|
"""
|
||||||
arrivedFile = open(postFilename + '.arrived', 'w+')
|
arrivedFile = open(postFilename + '.arrived', 'w+')
|
||||||
|
|
@ -68,7 +68,7 @@ def saveArrivedTime(baseDir: str, postFilename: str, arrived: str) -> None:
|
||||||
arrivedFile.close()
|
arrivedFile.close()
|
||||||
|
|
||||||
|
|
||||||
def removeControlCharacters(content: str) -> str:
|
def _removeControlCharacters(content: str) -> str:
|
||||||
"""Remove escaped html
|
"""Remove escaped html
|
||||||
"""
|
"""
|
||||||
if '&' in content:
|
if '&' in content:
|
||||||
|
|
@ -227,7 +227,7 @@ def hashtagRuleTree(operators: [],
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
|
||||||
def newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
|
def _newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
|
||||||
hashtags: [], httpPrefix: str,
|
hashtags: [], httpPrefix: str,
|
||||||
domain: str, port: int,
|
domain: str, port: int,
|
||||||
personCache: {},
|
personCache: {},
|
||||||
|
|
@ -356,7 +356,7 @@ def newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def createNewsMirror(baseDir: str, domain: str,
|
def _createNewsMirror(baseDir: str, domain: str,
|
||||||
postIdNumber: str, url: str,
|
postIdNumber: str, url: str,
|
||||||
maxMirroredArticles: int) -> bool:
|
maxMirroredArticles: int) -> bool:
|
||||||
"""Creates a local mirror of a news article
|
"""Creates a local mirror of a news article
|
||||||
|
|
@ -446,7 +446,7 @@ def createNewsMirror(baseDir: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
def _convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
domain: str, port: int,
|
domain: str, port: int,
|
||||||
newswire: {},
|
newswire: {},
|
||||||
translate: {},
|
translate: {},
|
||||||
|
|
@ -497,7 +497,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
newswire[originalDateStr][3] = filename
|
newswire[originalDateStr][3] = filename
|
||||||
continue
|
continue
|
||||||
|
|
||||||
rssTitle = removeControlCharacters(item[0])
|
rssTitle = _removeControlCharacters(item[0])
|
||||||
url = item[1]
|
url = item[1]
|
||||||
if dangerousMarkup(url, allowLocalNetworkAccess) or \
|
if dangerousMarkup(url, allowLocalNetworkAccess) or \
|
||||||
dangerousMarkup(rssTitle, allowLocalNetworkAccess):
|
dangerousMarkup(rssTitle, allowLocalNetworkAccess):
|
||||||
|
|
@ -505,7 +505,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
rssDescription = ''
|
rssDescription = ''
|
||||||
|
|
||||||
# get the rss description if it exists
|
# get the rss description if it exists
|
||||||
rssDescription = removeControlCharacters(item[4])
|
rssDescription = _removeControlCharacters(item[4])
|
||||||
if rssDescription.startswith('<![CDATA['):
|
if rssDescription.startswith('<![CDATA['):
|
||||||
rssDescription = rssDescription.replace('<![CDATA[', '')
|
rssDescription = rssDescription.replace('<![CDATA[', '')
|
||||||
rssDescription = rssDescription.replace(']]>', '')
|
rssDescription = rssDescription.replace(']]>', '')
|
||||||
|
|
@ -555,7 +555,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if mirrored:
|
if mirrored:
|
||||||
if not createNewsMirror(baseDir, domain, statusNumber,
|
if not _createNewsMirror(baseDir, domain, statusNumber,
|
||||||
url, maxMirroredArticles):
|
url, maxMirroredArticles):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -590,7 +590,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
|
|
||||||
moderated = item[5]
|
moderated = item[5]
|
||||||
|
|
||||||
savePost = newswireHashtagProcessing(session, baseDir, blog, hashtags,
|
savePost = _newswireHashtagProcessing(session, baseDir, blog, hashtags,
|
||||||
httpPrefix, domain, port,
|
httpPrefix, domain, port,
|
||||||
personCache, cachedWebfingers,
|
personCache, cachedWebfingers,
|
||||||
federationList,
|
federationList,
|
||||||
|
|
@ -628,7 +628,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
blog['object']['content'] = content
|
blog['object']['content'] = content
|
||||||
|
|
||||||
# update the newswire tags if new ones have been found by
|
# update the newswire tags if new ones have been found by
|
||||||
# newswireHashtagProcessing
|
# _newswireHashtagProcessing
|
||||||
for tag in hashtags:
|
for tag in hashtags:
|
||||||
if tag not in newswire[originalDateStr][6]:
|
if tag not in newswire[originalDateStr][6]:
|
||||||
newswire[originalDateStr][6].append(tag)
|
newswire[originalDateStr][6].append(tag)
|
||||||
|
|
@ -637,13 +637,13 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
|
|
||||||
clearFromPostCaches(baseDir, recentPostsCache, postId)
|
clearFromPostCaches(baseDir, recentPostsCache, postId)
|
||||||
if saveJson(blog, filename):
|
if saveJson(blog, filename):
|
||||||
updateFeedsOutboxIndex(baseDir, domain, postId + '.json')
|
_updateFeedsOutboxIndex(baseDir, domain, postId + '.json')
|
||||||
|
|
||||||
# Save a file containing the time when the post arrived
|
# Save a file containing the time when the post arrived
|
||||||
# this can then later be used to construct the news timeline
|
# this can then later be used to construct the news timeline
|
||||||
# excluding items during the voting period
|
# excluding items during the voting period
|
||||||
if moderated:
|
if moderated:
|
||||||
saveArrivedTime(baseDir, filename,
|
_saveArrivedTime(baseDir, filename,
|
||||||
blog['object']['arrived'])
|
blog['object']['arrived'])
|
||||||
else:
|
else:
|
||||||
if os.path.isfile(filename + '.arrived'):
|
if os.path.isfile(filename + '.arrived'):
|
||||||
|
|
@ -658,7 +658,7 @@ def convertRSStoActivityPub(baseDir: str, httpPrefix: str,
|
||||||
newswire[originalDateStr][3] = filename
|
newswire[originalDateStr][3] = filename
|
||||||
|
|
||||||
|
|
||||||
def mergeWithPreviousNewswire(oldNewswire: {}, newNewswire: {}) -> None:
|
def _mergeWithPreviousNewswire(oldNewswire: {}, newNewswire: {}) -> None:
|
||||||
"""Preserve any votes or generated activitypub post filename
|
"""Preserve any votes or generated activitypub post filename
|
||||||
as rss feeds are updated
|
as rss feeds are updated
|
||||||
"""
|
"""
|
||||||
|
|
@ -707,14 +707,14 @@ def runNewswireDaemon(baseDir: str, httpd,
|
||||||
if os.path.isfile(newswireStateFilename):
|
if os.path.isfile(newswireStateFilename):
|
||||||
httpd.newswire = loadJson(newswireStateFilename)
|
httpd.newswire = loadJson(newswireStateFilename)
|
||||||
|
|
||||||
mergeWithPreviousNewswire(httpd.newswire, newNewswire)
|
_mergeWithPreviousNewswire(httpd.newswire, newNewswire)
|
||||||
|
|
||||||
httpd.newswire = newNewswire
|
httpd.newswire = newNewswire
|
||||||
if newNewswire:
|
if newNewswire:
|
||||||
saveJson(httpd.newswire, newswireStateFilename)
|
saveJson(httpd.newswire, newswireStateFilename)
|
||||||
print('Newswire updated')
|
print('Newswire updated')
|
||||||
|
|
||||||
convertRSStoActivityPub(baseDir,
|
_convertRSStoActivityPub(baseDir,
|
||||||
httpPrefix, domain, port,
|
httpPrefix, domain, port,
|
||||||
newNewswire, translate,
|
newNewswire, translate,
|
||||||
httpd.recentPostsCache,
|
httpd.recentPostsCache,
|
||||||
|
|
|
||||||
100
newswire.py
100
newswire.py
|
|
@ -29,7 +29,7 @@ from blocking import isBlockedHashtag
|
||||||
from filters import isFiltered
|
from filters import isFiltered
|
||||||
|
|
||||||
|
|
||||||
def removeCDATA(text: str) -> str:
|
def _removeCDATA(text: str) -> str:
|
||||||
"""Removes any CDATA from the given text
|
"""Removes any CDATA from the given text
|
||||||
"""
|
"""
|
||||||
if 'CDATA[' in text:
|
if 'CDATA[' in text:
|
||||||
|
|
@ -95,7 +95,7 @@ def getNewswireTags(text: str, maxTags: int) -> []:
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
|
||||||
def addNewswireDictEntry(baseDir: str, domain: str,
|
def _addNewswireDictEntry(baseDir: str, domain: str,
|
||||||
newswire: {}, dateStr: str,
|
newswire: {}, dateStr: str,
|
||||||
title: str, link: str,
|
title: str, link: str,
|
||||||
votesStatus: str, postFilename: str,
|
votesStatus: str, postFilename: str,
|
||||||
|
|
@ -143,7 +143,7 @@ def addNewswireDictEntry(baseDir: str, domain: str,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def validFeedDate(pubDate: str) -> bool:
|
def _validFeedDate(pubDate: str) -> bool:
|
||||||
# convert from YY-MM-DD HH:MM:SS+00:00 to
|
# convert from YY-MM-DD HH:MM:SS+00:00 to
|
||||||
# YY-MM-DDTHH:MM:SSZ
|
# YY-MM-DDTHH:MM:SSZ
|
||||||
postDate = pubDate.replace(' ', 'T').replace('+00:00', 'Z')
|
postDate = pubDate.replace(' ', 'T').replace('+00:00', 'Z')
|
||||||
|
|
@ -219,10 +219,10 @@ def loadHashtagCategories(baseDir: str, language: str) -> None:
|
||||||
|
|
||||||
with open(hashtagCategoriesFilename, 'r') as fp:
|
with open(hashtagCategoriesFilename, 'r') as fp:
|
||||||
xmlStr = fp.read()
|
xmlStr = fp.read()
|
||||||
xml2StrToHashtagCategories(baseDir, xmlStr, 1024, True)
|
_xml2StrToHashtagCategories(baseDir, xmlStr, 1024, True)
|
||||||
|
|
||||||
|
|
||||||
def xml2StrToHashtagCategories(baseDir: str, xmlStr: str,
|
def _xml2StrToHashtagCategories(baseDir: str, xmlStr: str,
|
||||||
maxCategoriesFeedItemSizeKb: int,
|
maxCategoriesFeedItemSizeKb: int,
|
||||||
force=False) -> None:
|
force=False) -> None:
|
||||||
"""Updates hashtag categories based upon an rss feed
|
"""Updates hashtag categories based upon an rss feed
|
||||||
|
|
@ -261,7 +261,7 @@ def xml2StrToHashtagCategories(baseDir: str, xmlStr: str,
|
||||||
setHashtagCategory(baseDir, hashtag, categoryStr, force)
|
setHashtagCategory(baseDir, hashtag, categoryStr, force)
|
||||||
|
|
||||||
|
|
||||||
def xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
def _xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
moderated: bool, mirrored: bool,
|
moderated: bool, mirrored: bool,
|
||||||
maxPostsPerSource: int,
|
maxPostsPerSource: int,
|
||||||
maxFeedItemSizeKb: int,
|
maxFeedItemSizeKb: int,
|
||||||
|
|
@ -274,7 +274,7 @@ def xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
# is this an rss feed containing hashtag categories?
|
# is this an rss feed containing hashtag categories?
|
||||||
if '<title>#categories</title>' in xmlStr:
|
if '<title>#categories</title>' in xmlStr:
|
||||||
xml2StrToHashtagCategories(baseDir, xmlStr,
|
_xml2StrToHashtagCategories(baseDir, xmlStr,
|
||||||
maxCategoriesFeedItemSizeKb)
|
maxCategoriesFeedItemSizeKb)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
@ -300,17 +300,17 @@ def xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
if '</pubDate>' not in rssItem:
|
if '</pubDate>' not in rssItem:
|
||||||
continue
|
continue
|
||||||
title = rssItem.split('<title>')[1]
|
title = rssItem.split('<title>')[1]
|
||||||
title = removeCDATA(title.split('</title>')[0])
|
title = _removeCDATA(title.split('</title>')[0])
|
||||||
description = ''
|
description = ''
|
||||||
if '<description>' in rssItem and '</description>' in rssItem:
|
if '<description>' in rssItem and '</description>' in rssItem:
|
||||||
description = rssItem.split('<description>')[1]
|
description = rssItem.split('<description>')[1]
|
||||||
description = removeCDATA(description.split('</description>')[0])
|
description = _removeCDATA(description.split('</description>')[0])
|
||||||
else:
|
else:
|
||||||
if '<media:description>' in rssItem and \
|
if '<media:description>' in rssItem and \
|
||||||
'</media:description>' in rssItem:
|
'</media:description>' in rssItem:
|
||||||
description = rssItem.split('<media:description>')[1]
|
description = rssItem.split('<media:description>')[1]
|
||||||
description = description.split('</media:description>')[0]
|
description = description.split('</media:description>')[0]
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
link = rssItem.split('<link>')[1]
|
link = rssItem.split('<link>')[1]
|
||||||
link = link.split('</link>')[0]
|
link = link.split('</link>')[0]
|
||||||
if '://' not in link:
|
if '://' not in link:
|
||||||
|
|
@ -325,10 +325,10 @@ def xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
pubDateStr = parseFeedDate(pubDate)
|
pubDateStr = parseFeedDate(pubDate)
|
||||||
if pubDateStr:
|
if pubDateStr:
|
||||||
if validFeedDate(pubDateStr):
|
if _validFeedDate(pubDateStr):
|
||||||
postFilename = ''
|
postFilename = ''
|
||||||
votesStatus = []
|
votesStatus = []
|
||||||
addNewswireDictEntry(baseDir, domain,
|
_addNewswireDictEntry(baseDir, domain,
|
||||||
result, pubDateStr,
|
result, pubDateStr,
|
||||||
title, link,
|
title, link,
|
||||||
votesStatus, postFilename,
|
votesStatus, postFilename,
|
||||||
|
|
@ -341,7 +341,7 @@ def xml2StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
def _xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
moderated: bool, mirrored: bool,
|
moderated: bool, mirrored: bool,
|
||||||
maxPostsPerSource: int,
|
maxPostsPerSource: int,
|
||||||
maxFeedItemSizeKb: int,
|
maxFeedItemSizeKb: int,
|
||||||
|
|
@ -356,7 +356,7 @@ def xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
# is this an rss feed containing hashtag categories?
|
# is this an rss feed containing hashtag categories?
|
||||||
if '<title>#categories</title>' in xmlStr:
|
if '<title>#categories</title>' in xmlStr:
|
||||||
xml2StrToHashtagCategories(baseDir, xmlStr,
|
_xml2StrToHashtagCategories(baseDir, xmlStr,
|
||||||
maxCategoriesFeedItemSizeKb)
|
maxCategoriesFeedItemSizeKb)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
@ -384,17 +384,17 @@ def xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
if '</dc:date>' not in rssItem:
|
if '</dc:date>' not in rssItem:
|
||||||
continue
|
continue
|
||||||
title = rssItem.split('<title>')[1]
|
title = rssItem.split('<title>')[1]
|
||||||
title = removeCDATA(title.split('</title>')[0])
|
title = _removeCDATA(title.split('</title>')[0])
|
||||||
description = ''
|
description = ''
|
||||||
if '<description>' in rssItem and '</description>' in rssItem:
|
if '<description>' in rssItem and '</description>' in rssItem:
|
||||||
description = rssItem.split('<description>')[1]
|
description = rssItem.split('<description>')[1]
|
||||||
description = removeCDATA(description.split('</description>')[0])
|
description = _removeCDATA(description.split('</description>')[0])
|
||||||
else:
|
else:
|
||||||
if '<media:description>' in rssItem and \
|
if '<media:description>' in rssItem and \
|
||||||
'</media:description>' in rssItem:
|
'</media:description>' in rssItem:
|
||||||
description = rssItem.split('<media:description>')[1]
|
description = rssItem.split('<media:description>')[1]
|
||||||
description = description.split('</media:description>')[0]
|
description = description.split('</media:description>')[0]
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
link = rssItem.split('<link>')[1]
|
link = rssItem.split('<link>')[1]
|
||||||
link = link.split('</link>')[0]
|
link = link.split('</link>')[0]
|
||||||
if '://' not in link:
|
if '://' not in link:
|
||||||
|
|
@ -409,10 +409,10 @@ def xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
pubDateStr = parseFeedDate(pubDate)
|
pubDateStr = parseFeedDate(pubDate)
|
||||||
if pubDateStr:
|
if pubDateStr:
|
||||||
if validFeedDate(pubDateStr):
|
if _validFeedDate(pubDateStr):
|
||||||
postFilename = ''
|
postFilename = ''
|
||||||
votesStatus = []
|
votesStatus = []
|
||||||
addNewswireDictEntry(baseDir, domain,
|
_addNewswireDictEntry(baseDir, domain,
|
||||||
result, pubDateStr,
|
result, pubDateStr,
|
||||||
title, link,
|
title, link,
|
||||||
votesStatus, postFilename,
|
votesStatus, postFilename,
|
||||||
|
|
@ -425,7 +425,7 @@ def xml1StrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def atomFeedToDict(baseDir: str, domain: str, xmlStr: str,
|
def _atomFeedToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
moderated: bool, mirrored: bool,
|
moderated: bool, mirrored: bool,
|
||||||
maxPostsPerSource: int,
|
maxPostsPerSource: int,
|
||||||
maxFeedItemSizeKb: int) -> {}:
|
maxFeedItemSizeKb: int) -> {}:
|
||||||
|
|
@ -456,17 +456,17 @@ def atomFeedToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
if '</updated>' not in atomItem:
|
if '</updated>' not in atomItem:
|
||||||
continue
|
continue
|
||||||
title = atomItem.split('<title>')[1]
|
title = atomItem.split('<title>')[1]
|
||||||
title = removeCDATA(title.split('</title>')[0])
|
title = _removeCDATA(title.split('</title>')[0])
|
||||||
description = ''
|
description = ''
|
||||||
if '<summary>' in atomItem and '</summary>' in atomItem:
|
if '<summary>' in atomItem and '</summary>' in atomItem:
|
||||||
description = atomItem.split('<summary>')[1]
|
description = atomItem.split('<summary>')[1]
|
||||||
description = removeCDATA(description.split('</summary>')[0])
|
description = _removeCDATA(description.split('</summary>')[0])
|
||||||
else:
|
else:
|
||||||
if '<media:description>' in atomItem and \
|
if '<media:description>' in atomItem and \
|
||||||
'</media:description>' in atomItem:
|
'</media:description>' in atomItem:
|
||||||
description = atomItem.split('<media:description>')[1]
|
description = atomItem.split('<media:description>')[1]
|
||||||
description = description.split('</media:description>')[0]
|
description = description.split('</media:description>')[0]
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
link = atomItem.split('<link>')[1]
|
link = atomItem.split('<link>')[1]
|
||||||
link = link.split('</link>')[0]
|
link = link.split('</link>')[0]
|
||||||
if '://' not in link:
|
if '://' not in link:
|
||||||
|
|
@ -481,10 +481,10 @@ def atomFeedToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
pubDateStr = parseFeedDate(pubDate)
|
pubDateStr = parseFeedDate(pubDate)
|
||||||
if pubDateStr:
|
if pubDateStr:
|
||||||
if validFeedDate(pubDateStr):
|
if _validFeedDate(pubDateStr):
|
||||||
postFilename = ''
|
postFilename = ''
|
||||||
votesStatus = []
|
votesStatus = []
|
||||||
addNewswireDictEntry(baseDir, domain,
|
_addNewswireDictEntry(baseDir, domain,
|
||||||
result, pubDateStr,
|
result, pubDateStr,
|
||||||
title, link,
|
title, link,
|
||||||
votesStatus, postFilename,
|
votesStatus, postFilename,
|
||||||
|
|
@ -497,7 +497,7 @@ def atomFeedToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def atomFeedYTToDict(baseDir: str, domain: str, xmlStr: str,
|
def _atomFeedYTToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
moderated: bool, mirrored: bool,
|
moderated: bool, mirrored: bool,
|
||||||
maxPostsPerSource: int,
|
maxPostsPerSource: int,
|
||||||
maxFeedItemSizeKb: int) -> {}:
|
maxFeedItemSizeKb: int) -> {}:
|
||||||
|
|
@ -532,17 +532,17 @@ def atomFeedYTToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
if '</yt:videoId>' not in atomItem:
|
if '</yt:videoId>' not in atomItem:
|
||||||
continue
|
continue
|
||||||
title = atomItem.split('<title>')[1]
|
title = atomItem.split('<title>')[1]
|
||||||
title = removeCDATA(title.split('</title>')[0])
|
title = _removeCDATA(title.split('</title>')[0])
|
||||||
description = ''
|
description = ''
|
||||||
if '<media:description>' in atomItem and \
|
if '<media:description>' in atomItem and \
|
||||||
'</media:description>' in atomItem:
|
'</media:description>' in atomItem:
|
||||||
description = atomItem.split('<media:description>')[1]
|
description = atomItem.split('<media:description>')[1]
|
||||||
description = description.split('</media:description>')[0]
|
description = description.split('</media:description>')[0]
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
elif '<summary>' in atomItem and '</summary>' in atomItem:
|
elif '<summary>' in atomItem and '</summary>' in atomItem:
|
||||||
description = atomItem.split('<summary>')[1]
|
description = atomItem.split('<summary>')[1]
|
||||||
description = description.split('</summary>')[0]
|
description = description.split('</summary>')[0]
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
link = atomItem.split('<yt:videoId>')[1]
|
link = atomItem.split('<yt:videoId>')[1]
|
||||||
link = link.split('</yt:videoId>')[0]
|
link = link.split('</yt:videoId>')[0]
|
||||||
link = 'https://www.youtube.com/watch?v=' + link.strip()
|
link = 'https://www.youtube.com/watch?v=' + link.strip()
|
||||||
|
|
@ -551,10 +551,10 @@ def atomFeedYTToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
|
|
||||||
pubDateStr = parseFeedDate(pubDate)
|
pubDateStr = parseFeedDate(pubDate)
|
||||||
if pubDateStr:
|
if pubDateStr:
|
||||||
if validFeedDate(pubDateStr):
|
if _validFeedDate(pubDateStr):
|
||||||
postFilename = ''
|
postFilename = ''
|
||||||
votesStatus = []
|
votesStatus = []
|
||||||
addNewswireDictEntry(baseDir, domain,
|
_addNewswireDictEntry(baseDir, domain,
|
||||||
result, pubDateStr,
|
result, pubDateStr,
|
||||||
title, link,
|
title, link,
|
||||||
votesStatus, postFilename,
|
votesStatus, postFilename,
|
||||||
|
|
@ -567,7 +567,7 @@ def atomFeedYTToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def xmlStrToDict(baseDir: str, domain: str, xmlStr: str,
|
def _xmlStrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
moderated: bool, mirrored: bool,
|
moderated: bool, mirrored: bool,
|
||||||
maxPostsPerSource: int,
|
maxPostsPerSource: int,
|
||||||
maxFeedItemSizeKb: int,
|
maxFeedItemSizeKb: int,
|
||||||
|
|
@ -576,27 +576,27 @@ def xmlStrToDict(baseDir: str, domain: str, xmlStr: str,
|
||||||
"""
|
"""
|
||||||
if '<yt:videoId>' in xmlStr and '<yt:channelId>' in xmlStr:
|
if '<yt:videoId>' in xmlStr and '<yt:channelId>' in xmlStr:
|
||||||
print('YouTube feed: reading')
|
print('YouTube feed: reading')
|
||||||
return atomFeedYTToDict(baseDir, domain,
|
return _atomFeedYTToDict(baseDir, domain,
|
||||||
xmlStr, moderated, mirrored,
|
xmlStr, moderated, mirrored,
|
||||||
maxPostsPerSource, maxFeedItemSizeKb)
|
maxPostsPerSource, maxFeedItemSizeKb)
|
||||||
elif 'rss version="2.0"' in xmlStr:
|
elif 'rss version="2.0"' in xmlStr:
|
||||||
return xml2StrToDict(baseDir, domain,
|
return _xml2StrToDict(baseDir, domain,
|
||||||
xmlStr, moderated, mirrored,
|
xmlStr, moderated, mirrored,
|
||||||
maxPostsPerSource, maxFeedItemSizeKb,
|
maxPostsPerSource, maxFeedItemSizeKb,
|
||||||
maxCategoriesFeedItemSizeKb)
|
maxCategoriesFeedItemSizeKb)
|
||||||
elif '<?xml version="1.0"' in xmlStr:
|
elif '<?xml version="1.0"' in xmlStr:
|
||||||
return xml1StrToDict(baseDir, domain,
|
return _xml1StrToDict(baseDir, domain,
|
||||||
xmlStr, moderated, mirrored,
|
xmlStr, moderated, mirrored,
|
||||||
maxPostsPerSource, maxFeedItemSizeKb,
|
maxPostsPerSource, maxFeedItemSizeKb,
|
||||||
maxCategoriesFeedItemSizeKb)
|
maxCategoriesFeedItemSizeKb)
|
||||||
elif 'xmlns="http://www.w3.org/2005/Atom"' in xmlStr:
|
elif 'xmlns="http://www.w3.org/2005/Atom"' in xmlStr:
|
||||||
return atomFeedToDict(baseDir, domain,
|
return _atomFeedToDict(baseDir, domain,
|
||||||
xmlStr, moderated, mirrored,
|
xmlStr, moderated, mirrored,
|
||||||
maxPostsPerSource, maxFeedItemSizeKb)
|
maxPostsPerSource, maxFeedItemSizeKb)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def YTchannelToAtomFeed(url: str) -> str:
|
def _YTchannelToAtomFeed(url: str) -> str:
|
||||||
"""Converts a YouTube channel url into an atom feed url
|
"""Converts a YouTube channel url into an atom feed url
|
||||||
"""
|
"""
|
||||||
if 'youtube.com/channel/' not in url:
|
if 'youtube.com/channel/' not in url:
|
||||||
|
|
@ -633,13 +633,13 @@ def getRSS(baseDir: str, domain: str, session, url: str,
|
||||||
'Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0'
|
'Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0'
|
||||||
if not session:
|
if not session:
|
||||||
print('WARN: no session specified for getRSS')
|
print('WARN: no session specified for getRSS')
|
||||||
url = YTchannelToAtomFeed(url)
|
url = _YTchannelToAtomFeed(url)
|
||||||
try:
|
try:
|
||||||
result = session.get(url, headers=sessionHeaders, params=sessionParams)
|
result = session.get(url, headers=sessionHeaders, params=sessionParams)
|
||||||
if result:
|
if result:
|
||||||
if int(len(result.text) / 1024) < maxFeedSizeKb and \
|
if int(len(result.text) / 1024) < maxFeedSizeKb and \
|
||||||
not containsInvalidChars(result.text):
|
not containsInvalidChars(result.text):
|
||||||
return xmlStrToDict(baseDir, domain, result.text,
|
return _xmlStrToDict(baseDir, domain, result.text,
|
||||||
moderated, mirrored,
|
moderated, mirrored,
|
||||||
maxPostsPerSource,
|
maxPostsPerSource,
|
||||||
maxFeedItemSizeKb,
|
maxFeedItemSizeKb,
|
||||||
|
|
@ -692,7 +692,7 @@ def getRSSfromDict(baseDir: str, newswire: {},
|
||||||
continue
|
continue
|
||||||
rssStr += '<item>\n'
|
rssStr += '<item>\n'
|
||||||
rssStr += ' <title>' + fields[0] + '</title>\n'
|
rssStr += ' <title>' + fields[0] + '</title>\n'
|
||||||
description = removeCDATA(firstParagraphFromString(fields[4]))
|
description = _removeCDATA(firstParagraphFromString(fields[4]))
|
||||||
rssStr += ' <description>' + description + '</description>\n'
|
rssStr += ' <description>' + description + '</description>\n'
|
||||||
url = fields[1]
|
url = fields[1]
|
||||||
if '://' not in url:
|
if '://' not in url:
|
||||||
|
|
@ -707,7 +707,7 @@ def getRSSfromDict(baseDir: str, newswire: {},
|
||||||
return rssStr
|
return rssStr
|
||||||
|
|
||||||
|
|
||||||
def isNewswireBlogPost(postJsonObject: {}) -> bool:
|
def _isNewswireBlogPost(postJsonObject: {}) -> bool:
|
||||||
"""Is the given object a blog post?
|
"""Is the given object a blog post?
|
||||||
There isn't any difference between a blog post and a newswire blog post
|
There isn't any difference between a blog post and a newswire blog post
|
||||||
but we may here need to check for different properties than
|
but we may here need to check for different properties than
|
||||||
|
|
@ -727,7 +727,7 @@ def isNewswireBlogPost(postJsonObject: {}) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def getHashtagsFromPost(postJsonObject: {}) -> []:
|
def _getHashtagsFromPost(postJsonObject: {}) -> []:
|
||||||
"""Returns a list of any hashtags within a post
|
"""Returns a list of any hashtags within a post
|
||||||
"""
|
"""
|
||||||
if not postJsonObject.get('object'):
|
if not postJsonObject.get('object'):
|
||||||
|
|
@ -753,7 +753,7 @@ def getHashtagsFromPost(postJsonObject: {}) -> []:
|
||||||
return tags
|
return tags
|
||||||
|
|
||||||
|
|
||||||
def addAccountBlogsToNewswire(baseDir: str, nickname: str, domain: str,
|
def _addAccountBlogsToNewswire(baseDir: str, nickname: str, domain: str,
|
||||||
newswire: {},
|
newswire: {},
|
||||||
maxBlogsPerAccount: int,
|
maxBlogsPerAccount: int,
|
||||||
indexFilename: str,
|
indexFilename: str,
|
||||||
|
|
@ -803,7 +803,7 @@ def addAccountBlogsToNewswire(baseDir: str, nickname: str, domain: str,
|
||||||
postJsonObject = None
|
postJsonObject = None
|
||||||
if fullPostFilename:
|
if fullPostFilename:
|
||||||
postJsonObject = loadJson(fullPostFilename)
|
postJsonObject = loadJson(fullPostFilename)
|
||||||
if isNewswireBlogPost(postJsonObject):
|
if _isNewswireBlogPost(postJsonObject):
|
||||||
published = postJsonObject['object']['published']
|
published = postJsonObject['object']['published']
|
||||||
published = published.replace('T', ' ')
|
published = published.replace('T', ' ')
|
||||||
published = published.replace('Z', '+00:00')
|
published = published.replace('Z', '+00:00')
|
||||||
|
|
@ -812,14 +812,14 @@ def addAccountBlogsToNewswire(baseDir: str, nickname: str, domain: str,
|
||||||
votes = loadJson(fullPostFilename + '.votes')
|
votes = loadJson(fullPostFilename + '.votes')
|
||||||
content = postJsonObject['object']['content']
|
content = postJsonObject['object']['content']
|
||||||
description = firstParagraphFromString(content)
|
description = firstParagraphFromString(content)
|
||||||
description = removeCDATA(description)
|
description = _removeCDATA(description)
|
||||||
addNewswireDictEntry(baseDir, domain,
|
_addNewswireDictEntry(baseDir, domain,
|
||||||
newswire, published,
|
newswire, published,
|
||||||
postJsonObject['object']['summary'],
|
postJsonObject['object']['summary'],
|
||||||
postJsonObject['object']['url'],
|
postJsonObject['object']['url'],
|
||||||
votes, fullPostFilename,
|
votes, fullPostFilename,
|
||||||
description, moderated, False,
|
description, moderated, False,
|
||||||
getHashtagsFromPost(postJsonObject),
|
_getHashtagsFromPost(postJsonObject),
|
||||||
maxTags)
|
maxTags)
|
||||||
|
|
||||||
ctr += 1
|
ctr += 1
|
||||||
|
|
@ -827,7 +827,7 @@ def addAccountBlogsToNewswire(baseDir: str, nickname: str, domain: str,
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def addBlogsToNewswire(baseDir: str, domain: str, newswire: {},
|
def _addBlogsToNewswire(baseDir: str, domain: str, newswire: {},
|
||||||
maxBlogsPerAccount: int,
|
maxBlogsPerAccount: int,
|
||||||
maxTags: int) -> None:
|
maxTags: int) -> None:
|
||||||
"""Adds blogs from each user account into the newswire
|
"""Adds blogs from each user account into the newswire
|
||||||
|
|
@ -857,7 +857,7 @@ def addBlogsToNewswire(baseDir: str, domain: str, newswire: {},
|
||||||
blogsIndex = accountDir + '/tlblogs.index'
|
blogsIndex = accountDir + '/tlblogs.index'
|
||||||
if os.path.isfile(blogsIndex):
|
if os.path.isfile(blogsIndex):
|
||||||
domain = handle.split('@')[1]
|
domain = handle.split('@')[1]
|
||||||
addAccountBlogsToNewswire(baseDir, nickname, domain,
|
_addAccountBlogsToNewswire(baseDir, nickname, domain,
|
||||||
newswire, maxBlogsPerAccount,
|
newswire, maxBlogsPerAccount,
|
||||||
blogsIndex, maxTags)
|
blogsIndex, maxTags)
|
||||||
break
|
break
|
||||||
|
|
@ -926,7 +926,7 @@ def getDictFromNewswire(session, baseDir: str, domain: str,
|
||||||
result[dateStr] = item
|
result[dateStr] = item
|
||||||
|
|
||||||
# add blogs from each user account
|
# add blogs from each user account
|
||||||
addBlogsToNewswire(baseDir, domain, result,
|
_addBlogsToNewswire(baseDir, domain, result,
|
||||||
maxPostsPerSource, maxTags)
|
maxPostsPerSource, maxTags)
|
||||||
|
|
||||||
# sort into chronological order, latest first
|
# sort into chronological order, latest first
|
||||||
|
|
|
||||||
14
person.py
14
person.py
|
|
@ -134,7 +134,7 @@ def setOrganizationScheme(baseDir: str, nickname: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def accountExists(baseDir: str, nickname: str, domain: str) -> bool:
|
def _accountExists(baseDir: str, nickname: str, domain: str) -> bool:
|
||||||
"""Returns true if the given account exists
|
"""Returns true if the given account exists
|
||||||
"""
|
"""
|
||||||
if ':' in domain:
|
if ':' in domain:
|
||||||
|
|
@ -201,7 +201,7 @@ def getDefaultPersonContext() -> str:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def createPersonBase(baseDir: str, nickname: str, domain: str, port: int,
|
def _createPersonBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
httpPrefix: str, saveToFile: bool,
|
httpPrefix: str, saveToFile: bool,
|
||||||
manualFollowerApproval: bool,
|
manualFollowerApproval: bool,
|
||||||
password=None) -> (str, str, {}, {}):
|
password=None) -> (str, str, {}, {}):
|
||||||
|
|
@ -377,7 +377,7 @@ def registerAccount(baseDir: str, httpPrefix: str, domain: str, port: int,
|
||||||
manualFollowerApproval: bool) -> bool:
|
manualFollowerApproval: bool) -> bool:
|
||||||
"""Registers a new account from the web interface
|
"""Registers a new account from the web interface
|
||||||
"""
|
"""
|
||||||
if accountExists(baseDir, nickname, domain):
|
if _accountExists(baseDir, nickname, domain):
|
||||||
return False
|
return False
|
||||||
if not validNickname(domain, nickname):
|
if not validNickname(domain, nickname):
|
||||||
print('REGISTER: Nickname ' + nickname + ' is invalid')
|
print('REGISTER: Nickname ' + nickname + ' is invalid')
|
||||||
|
|
@ -449,7 +449,7 @@ def createPerson(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
return None, None, None, None
|
return None, None, None, None
|
||||||
|
|
||||||
(privateKeyPem, publicKeyPem,
|
(privateKeyPem, publicKeyPem,
|
||||||
newPerson, webfingerEndpoint) = createPersonBase(baseDir, nickname,
|
newPerson, webfingerEndpoint) = _createPersonBase(baseDir, nickname,
|
||||||
domain, port,
|
domain, port,
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
saveToFile,
|
saveToFile,
|
||||||
|
|
@ -525,7 +525,7 @@ def createSharedInbox(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
httpPrefix: str) -> (str, str, {}, {}):
|
httpPrefix: str) -> (str, str, {}, {}):
|
||||||
"""Generates the shared inbox
|
"""Generates the shared inbox
|
||||||
"""
|
"""
|
||||||
return createPersonBase(baseDir, nickname, domain, port, httpPrefix,
|
return _createPersonBase(baseDir, nickname, domain, port, httpPrefix,
|
||||||
True, True, None)
|
True, True, None)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -845,7 +845,7 @@ def canRemovePost(baseDir: str, nickname: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def removeTagsForNickname(baseDir: str, nickname: str,
|
def _removeTagsForNickname(baseDir: str, nickname: str,
|
||||||
domain: str, port: int) -> None:
|
domain: str, port: int) -> None:
|
||||||
"""Removes tags for a nickname
|
"""Removes tags for a nickname
|
||||||
"""
|
"""
|
||||||
|
|
@ -900,7 +900,7 @@ def removeAccount(baseDir: str, nickname: str,
|
||||||
unsuspendAccount(baseDir, nickname)
|
unsuspendAccount(baseDir, nickname)
|
||||||
handle = nickname + '@' + domain
|
handle = nickname + '@' + domain
|
||||||
removePassword(baseDir, nickname)
|
removePassword(baseDir, nickname)
|
||||||
removeTagsForNickname(baseDir, nickname, domain, port)
|
_removeTagsForNickname(baseDir, nickname, domain, port)
|
||||||
if os.path.isdir(baseDir + '/deactivated/' + handle):
|
if os.path.isdir(baseDir + '/deactivated/' + handle):
|
||||||
shutil.rmtree(baseDir + '/deactivated/' + handle)
|
shutil.rmtree(baseDir + '/deactivated/' + handle)
|
||||||
if os.path.isdir(baseDir + '/accounts/' + handle):
|
if os.path.isdir(baseDir + '/accounts/' + handle):
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ def getPetName(baseDir: str, nickname: str, domain: str,
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
|
||||||
def getPetNameHandle(baseDir: str, nickname: str, domain: str,
|
def _getPetNameHandle(baseDir: str, nickname: str, domain: str,
|
||||||
petname: str) -> str:
|
petname: str) -> str:
|
||||||
"""Given a petname returns the handle
|
"""Given a petname returns the handle
|
||||||
"""
|
"""
|
||||||
|
|
@ -113,7 +113,7 @@ def resolvePetnames(baseDir: str, nickname: str, domain: str,
|
||||||
if not wrd.startswith('@'):
|
if not wrd.startswith('@'):
|
||||||
break
|
break
|
||||||
# does a petname handle exist for this?
|
# does a petname handle exist for this?
|
||||||
handle = getPetNameHandle(baseDir, nickname, domain, wrd)
|
handle = _getPetNameHandle(baseDir, nickname, domain, wrd)
|
||||||
if not handle:
|
if not handle:
|
||||||
continue
|
continue
|
||||||
# replace the petname with the handle
|
# replace the petname with the handle
|
||||||
|
|
|
||||||
147
posts.py
147
posts.py
|
|
@ -116,7 +116,7 @@ def noOfFollowersOnDomain(baseDir: str, handle: str,
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
||||||
def getPersonKey(nickname: str, domain: str, baseDir: str, keyType='public',
|
def _getPersonKey(nickname: str, domain: str, baseDir: str, keyType='public',
|
||||||
debug=False):
|
debug=False):
|
||||||
"""Returns the public or private key of a person
|
"""Returns the public or private key of a person
|
||||||
"""
|
"""
|
||||||
|
|
@ -136,7 +136,7 @@ def getPersonKey(nickname: str, domain: str, baseDir: str, keyType='public',
|
||||||
return keyPem
|
return keyPem
|
||||||
|
|
||||||
|
|
||||||
def cleanHtml(rawHtml: str) -> str:
|
def _cleanHtml(rawHtml: str) -> str:
|
||||||
# text=BeautifulSoup(rawHtml, 'html.parser').get_text()
|
# text=BeautifulSoup(rawHtml, 'html.parser').get_text()
|
||||||
text = rawHtml
|
text = rawHtml
|
||||||
return html.unescape(text)
|
return html.unescape(text)
|
||||||
|
|
@ -288,7 +288,7 @@ def getPersonBox(baseDir: str, session, wfRequest: {},
|
||||||
avatarUrl, displayName
|
avatarUrl, displayName
|
||||||
|
|
||||||
|
|
||||||
def getPosts(session, outboxUrl: str, maxPosts: int,
|
def _getPosts(session, outboxUrl: str, maxPosts: int,
|
||||||
maxMentions: int,
|
maxMentions: int,
|
||||||
maxEmoji: int, maxAttachments: int,
|
maxEmoji: int, maxAttachments: int,
|
||||||
federationList: [],
|
federationList: [],
|
||||||
|
|
@ -445,7 +445,7 @@ def getPosts(session, outboxUrl: str, maxPosts: int,
|
||||||
sensitive = item['object']['sensitive']
|
sensitive = item['object']['sensitive']
|
||||||
|
|
||||||
if simple:
|
if simple:
|
||||||
print(cleanHtml(content) + '\n')
|
print(_cleanHtml(content) + '\n')
|
||||||
else:
|
else:
|
||||||
pprint(item)
|
pprint(item)
|
||||||
personPosts[item['id']] = {
|
personPosts[item['id']] = {
|
||||||
|
|
@ -453,7 +453,7 @@ def getPosts(session, outboxUrl: str, maxPosts: int,
|
||||||
"inreplyto": inReplyTo,
|
"inreplyto": inReplyTo,
|
||||||
"summary": summary,
|
"summary": summary,
|
||||||
"html": content,
|
"html": content,
|
||||||
"plaintext": cleanHtml(content),
|
"plaintext": _cleanHtml(content),
|
||||||
"attachment": attachment,
|
"attachment": attachment,
|
||||||
"mentions": mentions,
|
"mentions": mentions,
|
||||||
"emoji": emoji,
|
"emoji": emoji,
|
||||||
|
|
@ -519,7 +519,7 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int,
|
||||||
return postDomains
|
return postDomains
|
||||||
|
|
||||||
|
|
||||||
def getPostsForBlockedDomains(baseDir: str,
|
def _getPostsForBlockedDomains(baseDir: str,
|
||||||
session, outboxUrl: str, maxPosts: int,
|
session, outboxUrl: str, maxPosts: int,
|
||||||
maxMentions: int,
|
maxMentions: int,
|
||||||
maxEmoji: int, maxAttachments: int,
|
maxEmoji: int, maxAttachments: int,
|
||||||
|
|
@ -643,7 +643,7 @@ def savePostToBox(baseDir: str, httpPrefix: str, postId: str,
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
|
|
||||||
def updateHashtagsIndex(baseDir: str, tag: {}, newPostId: str) -> None:
|
def _updateHashtagsIndex(baseDir: str, tag: {}, newPostId: str) -> None:
|
||||||
"""Writes the post url for hashtags to a file
|
"""Writes the post url for hashtags to a file
|
||||||
This allows posts for a hashtag to be quickly looked up
|
This allows posts for a hashtag to be quickly looked up
|
||||||
"""
|
"""
|
||||||
|
|
@ -677,7 +677,7 @@ def updateHashtagsIndex(baseDir: str, tag: {}, newPostId: str) -> None:
|
||||||
tagsFilename + ' ' + str(e))
|
tagsFilename + ' ' + str(e))
|
||||||
|
|
||||||
|
|
||||||
def addSchedulePost(baseDir: str, nickname: str, domain: str,
|
def _addSchedulePost(baseDir: str, nickname: str, domain: str,
|
||||||
eventDateStr: str, postId: str) -> None:
|
eventDateStr: str, postId: str) -> None:
|
||||||
"""Adds a scheduled post to the index
|
"""Adds a scheduled post to the index
|
||||||
"""
|
"""
|
||||||
|
|
@ -703,7 +703,7 @@ def addSchedulePost(baseDir: str, nickname: str, domain: str,
|
||||||
scheduleFile.close()
|
scheduleFile.close()
|
||||||
|
|
||||||
|
|
||||||
def appendEventFields(newPost: {},
|
def _appendEventFields(newPost: {},
|
||||||
eventUUID: str, eventStatus: str,
|
eventUUID: str, eventStatus: str,
|
||||||
anonymousParticipationEnabled: bool,
|
anonymousParticipationEnabled: bool,
|
||||||
repliesModerationOption: str,
|
repliesModerationOption: str,
|
||||||
|
|
@ -758,7 +758,7 @@ def validContentWarning(cw: str) -> str:
|
||||||
return cw
|
return cw
|
||||||
|
|
||||||
|
|
||||||
def loadAutoCW(baseDir: str, nickname: str, domain: str) -> []:
|
def _loadAutoCW(baseDir: str, nickname: str, domain: str) -> []:
|
||||||
"""Loads automatic CWs file and returns a list containing
|
"""Loads automatic CWs file and returns a list containing
|
||||||
the lines of the file
|
the lines of the file
|
||||||
"""
|
"""
|
||||||
|
|
@ -771,13 +771,13 @@ def loadAutoCW(baseDir: str, nickname: str, domain: str) -> []:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def addAutoCW(baseDir: str, nickname: str, domain: str,
|
def _addAutoCW(baseDir: str, nickname: str, domain: str,
|
||||||
subject: str, content: str) -> str:
|
subject: str, content: str) -> str:
|
||||||
"""Appends any automatic CW to the subject line
|
"""Appends any automatic CW to the subject line
|
||||||
and returns the new subject line
|
and returns the new subject line
|
||||||
"""
|
"""
|
||||||
newSubject = subject
|
newSubject = subject
|
||||||
autoCWList = loadAutoCW(baseDir, nickname, domain)
|
autoCWList = _loadAutoCW(baseDir, nickname, domain)
|
||||||
for cwRule in autoCWList:
|
for cwRule in autoCWList:
|
||||||
if '->' not in cwRule:
|
if '->' not in cwRule:
|
||||||
continue
|
continue
|
||||||
|
|
@ -793,10 +793,10 @@ def addAutoCW(baseDir: str, nickname: str, domain: str,
|
||||||
return newSubject
|
return newSubject
|
||||||
|
|
||||||
|
|
||||||
def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
def _createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str, content: str,
|
toUrl: str, ccUrl: str, httpPrefix: str, content: str,
|
||||||
followersOnly: bool, saveToFile: bool, clientToServer: bool,
|
followersOnly: bool, saveToFile: bool,
|
||||||
commentsEnabled: bool,
|
clientToServer: bool, commentsEnabled: bool,
|
||||||
attachImageFilename: str,
|
attachImageFilename: str,
|
||||||
mediaType: str, imageDescription: str,
|
mediaType: str, imageDescription: str,
|
||||||
useBlurhash: bool, isModerationReport: bool,
|
useBlurhash: bool, isModerationReport: bool,
|
||||||
|
|
@ -812,7 +812,7 @@ def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
eventStatus=None, ticketUrl=None) -> {}:
|
eventStatus=None, ticketUrl=None) -> {}:
|
||||||
"""Creates a message
|
"""Creates a message
|
||||||
"""
|
"""
|
||||||
subject = addAutoCW(baseDir, nickname, domain, subject, content)
|
subject = _addAutoCW(baseDir, nickname, domain, subject, content)
|
||||||
|
|
||||||
if nickname != 'news':
|
if nickname != 'news':
|
||||||
mentionedRecipients = \
|
mentionedRecipients = \
|
||||||
|
|
@ -885,7 +885,7 @@ def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
if not tagExists(tag['type'], tag['name'], tags):
|
if not tagExists(tag['type'], tag['name'], tags):
|
||||||
tags.append(tag)
|
tags.append(tag)
|
||||||
if isPublic:
|
if isPublic:
|
||||||
updateHashtagsIndex(baseDir, tag, newPostId)
|
_updateHashtagsIndex(baseDir, tag, newPostId)
|
||||||
print('Content tags: ' + str(tags))
|
print('Content tags: ' + str(tags))
|
||||||
|
|
||||||
if inReplyTo and not sensitive:
|
if inReplyTo and not sensitive:
|
||||||
|
|
@ -1031,7 +1031,7 @@ def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
attachMedia(baseDir, httpPrefix, domain, port,
|
attachMedia(baseDir, httpPrefix, domain, port,
|
||||||
newPost['object'], attachImageFilename,
|
newPost['object'], attachImageFilename,
|
||||||
mediaType, imageDescription, useBlurhash)
|
mediaType, imageDescription, useBlurhash)
|
||||||
appendEventFields(newPost['object'], eventUUID, eventStatus,
|
_appendEventFields(newPost['object'], eventUUID, eventStatus,
|
||||||
anonymousParticipationEnabled,
|
anonymousParticipationEnabled,
|
||||||
repliesModerationOption,
|
repliesModerationOption,
|
||||||
category, joinMode,
|
category, joinMode,
|
||||||
|
|
@ -1079,7 +1079,7 @@ def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
attachMedia(baseDir, httpPrefix, domain, port,
|
attachMedia(baseDir, httpPrefix, domain, port,
|
||||||
newPost, attachImageFilename,
|
newPost, attachImageFilename,
|
||||||
mediaType, imageDescription, useBlurhash)
|
mediaType, imageDescription, useBlurhash)
|
||||||
appendEventFields(newPost, eventUUID, eventStatus,
|
_appendEventFields(newPost, eventUUID, eventStatus,
|
||||||
anonymousParticipationEnabled,
|
anonymousParticipationEnabled,
|
||||||
repliesModerationOption,
|
repliesModerationOption,
|
||||||
category, joinMode,
|
category, joinMode,
|
||||||
|
|
@ -1123,7 +1123,8 @@ def createPostBase(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
if schedulePost:
|
if schedulePost:
|
||||||
if eventDate and eventTime:
|
if eventDate and eventTime:
|
||||||
# add an item to the scheduled post index file
|
# add an item to the scheduled post index file
|
||||||
addSchedulePost(baseDir, nickname, domain, eventDateStr, newPostId)
|
_addSchedulePost(baseDir, nickname, domain,
|
||||||
|
eventDateStr, newPostId)
|
||||||
savePostToBox(baseDir, httpPrefix, newPostId,
|
savePostToBox(baseDir, httpPrefix, newPostId,
|
||||||
nickname, domain, newPost, 'scheduled')
|
nickname, domain, newPost, 'scheduled')
|
||||||
else:
|
else:
|
||||||
|
|
@ -1179,7 +1180,7 @@ def outboxMessageCreateWrap(httpPrefix: str,
|
||||||
return newPost
|
return newPost
|
||||||
|
|
||||||
|
|
||||||
def postIsAddressedToFollowers(baseDir: str,
|
def _postIsAddressedToFollowers(baseDir: str,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
postJsonObject: {}) -> bool:
|
postJsonObject: {}) -> bool:
|
||||||
|
|
@ -1227,7 +1228,7 @@ def createPublicPost(baseDir: str,
|
||||||
"""Public post
|
"""Public post
|
||||||
"""
|
"""
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
return createPostBase(baseDir, nickname, domain, port,
|
return _createPostBase(baseDir, nickname, domain, port,
|
||||||
'https://www.w3.org/ns/activitystreams#Public',
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
httpPrefix + '://' + domainFull + '/users/' +
|
httpPrefix + '://' + domainFull + '/users/' +
|
||||||
nickname + '/followers',
|
nickname + '/followers',
|
||||||
|
|
@ -1328,7 +1329,7 @@ def createQuestionPost(baseDir: str,
|
||||||
"""
|
"""
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
messageJson = \
|
messageJson = \
|
||||||
createPostBase(baseDir, nickname, domain, port,
|
_createPostBase(baseDir, nickname, domain, port,
|
||||||
'https://www.w3.org/ns/activitystreams#Public',
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
httpPrefix + '://' + domainFull + '/users/' +
|
httpPrefix + '://' + domainFull + '/users/' +
|
||||||
nickname + '/followers',
|
nickname + '/followers',
|
||||||
|
|
@ -1373,7 +1374,7 @@ def createUnlistedPost(baseDir: str,
|
||||||
"""Unlisted post. This has the #Public and followers links inverted.
|
"""Unlisted post. This has the #Public and followers links inverted.
|
||||||
"""
|
"""
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
return createPostBase(baseDir, nickname, domain, port,
|
return _createPostBase(baseDir, nickname, domain, port,
|
||||||
httpPrefix + '://' + domainFull + '/users/' +
|
httpPrefix + '://' + domainFull + '/users/' +
|
||||||
nickname + '/followers',
|
nickname + '/followers',
|
||||||
'https://www.w3.org/ns/activitystreams#Public',
|
'https://www.w3.org/ns/activitystreams#Public',
|
||||||
|
|
@ -1402,7 +1403,7 @@ def createFollowersOnlyPost(baseDir: str,
|
||||||
"""Followers only post
|
"""Followers only post
|
||||||
"""
|
"""
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
return createPostBase(baseDir, nickname, domain, port,
|
return _createPostBase(baseDir, nickname, domain, port,
|
||||||
httpPrefix + '://' + domainFull + '/users/' +
|
httpPrefix + '://' + domainFull + '/users/' +
|
||||||
nickname + '/followers',
|
nickname + '/followers',
|
||||||
None,
|
None,
|
||||||
|
|
@ -1451,7 +1452,7 @@ def createEventPost(baseDir: str,
|
||||||
if followersOnly:
|
if followersOnly:
|
||||||
toStr1 = toStr2
|
toStr1 = toStr2
|
||||||
toStr2 = None
|
toStr2 = None
|
||||||
return createPostBase(baseDir, nickname, domain, port,
|
return _createPostBase(baseDir, nickname, domain, port,
|
||||||
toStr1, toStr2,
|
toStr1, toStr2,
|
||||||
httpPrefix, content, followersOnly, saveToFile,
|
httpPrefix, content, followersOnly, saveToFile,
|
||||||
clientToServer, commentsEnabled,
|
clientToServer, commentsEnabled,
|
||||||
|
|
@ -1526,7 +1527,7 @@ def createDirectMessagePost(baseDir: str,
|
||||||
postTo = None
|
postTo = None
|
||||||
postCc = None
|
postCc = None
|
||||||
messageJson = \
|
messageJson = \
|
||||||
createPostBase(baseDir, nickname, domain, port,
|
_createPostBase(baseDir, nickname, domain, port,
|
||||||
postTo, postCc,
|
postTo, postCc,
|
||||||
httpPrefix, content, followersOnly, saveToFile,
|
httpPrefix, content, followersOnly, saveToFile,
|
||||||
clientToServer, commentsEnabled,
|
clientToServer, commentsEnabled,
|
||||||
|
|
@ -1616,7 +1617,7 @@ def createReportPost(baseDir: str,
|
||||||
handle = toNickname + '@' + domain
|
handle = toNickname + '@' + domain
|
||||||
|
|
||||||
postJsonObject = \
|
postJsonObject = \
|
||||||
createPostBase(baseDir, nickname, domain, port,
|
_createPostBase(baseDir, nickname, domain, port,
|
||||||
toUrl, postCc,
|
toUrl, postCc,
|
||||||
httpPrefix, content, followersOnly, saveToFile,
|
httpPrefix, content, followersOnly, saveToFile,
|
||||||
clientToServer, commentsEnabled,
|
clientToServer, commentsEnabled,
|
||||||
|
|
@ -1766,7 +1767,7 @@ def sendPost(projectVersion: str,
|
||||||
# sharedInbox is optional
|
# sharedInbox is optional
|
||||||
|
|
||||||
postJsonObject = \
|
postJsonObject = \
|
||||||
createPostBase(baseDir, nickname, domain, port,
|
_createPostBase(baseDir, nickname, domain, port,
|
||||||
toPersonId, cc, httpPrefix, content,
|
toPersonId, cc, httpPrefix, content,
|
||||||
followersOnly, saveToFile, clientToServer,
|
followersOnly, saveToFile, clientToServer,
|
||||||
commentsEnabled,
|
commentsEnabled,
|
||||||
|
|
@ -1779,7 +1780,7 @@ def sendPost(projectVersion: str,
|
||||||
None, None, None, None, None)
|
None, None, None, None, None)
|
||||||
|
|
||||||
# get the senders private key
|
# get the senders private key
|
||||||
privateKeyPem = getPersonKey(nickname, domain, baseDir, 'private')
|
privateKeyPem = _getPersonKey(nickname, domain, baseDir, 'private')
|
||||||
if len(privateKeyPem) == 0:
|
if len(privateKeyPem) == 0:
|
||||||
return 6
|
return 6
|
||||||
|
|
||||||
|
|
@ -1902,7 +1903,7 @@ def sendPostViaServer(projectVersion: str,
|
||||||
'/users/' + toNickname
|
'/users/' + toNickname
|
||||||
|
|
||||||
postJsonObject = \
|
postJsonObject = \
|
||||||
createPostBase(baseDir,
|
_createPostBase(baseDir,
|
||||||
fromNickname, fromDomain, fromPort,
|
fromNickname, fromDomain, fromPort,
|
||||||
toPersonId, cc, httpPrefix, content,
|
toPersonId, cc, httpPrefix, content,
|
||||||
followersOnly, saveToFile, clientToServer,
|
followersOnly, saveToFile, clientToServer,
|
||||||
|
|
@ -1969,7 +1970,7 @@ def groupFollowersByDomain(baseDir: str, nickname: str, domain: str) -> {}:
|
||||||
return grouped
|
return grouped
|
||||||
|
|
||||||
|
|
||||||
def addFollowersToPublicPost(postJsonObject: {}) -> None:
|
def _addFollowersToPublicPost(postJsonObject: {}) -> None:
|
||||||
"""Adds followers entry to cc if it doesn't exist
|
"""Adds followers entry to cc if it doesn't exist
|
||||||
"""
|
"""
|
||||||
if not postJsonObject.get('actor'):
|
if not postJsonObject.get('actor'):
|
||||||
|
|
@ -2099,7 +2100,7 @@ def sendSignedJson(postJsonObject: {}, session, baseDir: str,
|
||||||
# sharedInbox is optional
|
# sharedInbox is optional
|
||||||
|
|
||||||
# get the senders private key
|
# get the senders private key
|
||||||
privateKeyPem = getPersonKey(nickname, domain, baseDir, 'private', debug)
|
privateKeyPem = _getPersonKey(nickname, domain, baseDir, 'private', debug)
|
||||||
if len(privateKeyPem) == 0:
|
if len(privateKeyPem) == 0:
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Private key not found for ' +
|
print('DEBUG: Private key not found for ' +
|
||||||
|
|
@ -2112,7 +2113,7 @@ def sendSignedJson(postJsonObject: {}, session, baseDir: str,
|
||||||
return 7
|
return 7
|
||||||
postPath = inboxUrl.split(toDomain, 1)[1]
|
postPath = inboxUrl.split(toDomain, 1)[1]
|
||||||
|
|
||||||
addFollowersToPublicPost(postJsonObject)
|
_addFollowersToPublicPost(postJsonObject)
|
||||||
|
|
||||||
if not postJsonObject.get('signature'):
|
if not postJsonObject.get('signature'):
|
||||||
try:
|
try:
|
||||||
|
|
@ -2332,7 +2333,7 @@ def sendToNamedAddresses(session, baseDir: str,
|
||||||
personCache, debug, projectVersion)
|
personCache, debug, projectVersion)
|
||||||
|
|
||||||
|
|
||||||
def hasSharedInbox(session, httpPrefix: str, domain: str) -> bool:
|
def _hasSharedInbox(session, httpPrefix: str, domain: str) -> bool:
|
||||||
"""Returns true if the given domain has a shared inbox
|
"""Returns true if the given domain has a shared inbox
|
||||||
This tries the new and the old way of webfingering the shared inbox
|
This tries the new and the old way of webfingering the shared inbox
|
||||||
"""
|
"""
|
||||||
|
|
@ -2351,7 +2352,7 @@ def hasSharedInbox(session, httpPrefix: str, domain: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def sendingProfileUpdate(postJsonObject: {}) -> bool:
|
def _sendingProfileUpdate(postJsonObject: {}) -> bool:
|
||||||
"""Returns true if the given json is a profile update
|
"""Returns true if the given json is a profile update
|
||||||
"""
|
"""
|
||||||
if postJsonObject['type'] != 'Update':
|
if postJsonObject['type'] != 'Update':
|
||||||
|
|
@ -2386,7 +2387,7 @@ def sendToFollowers(session, baseDir: str,
|
||||||
if not session:
|
if not session:
|
||||||
print('WARN: No session for sendToFollowers')
|
print('WARN: No session for sendToFollowers')
|
||||||
return
|
return
|
||||||
if not postIsAddressedToFollowers(baseDir, nickname, domain,
|
if not _postIsAddressedToFollowers(baseDir, nickname, domain,
|
||||||
port, httpPrefix,
|
port, httpPrefix,
|
||||||
postJsonObject):
|
postJsonObject):
|
||||||
if debug:
|
if debug:
|
||||||
|
|
@ -2428,7 +2429,7 @@ def sendToFollowers(session, baseDir: str,
|
||||||
print('Sending post to followers domain is active: ' +
|
print('Sending post to followers domain is active: ' +
|
||||||
followerDomainUrl)
|
followerDomainUrl)
|
||||||
|
|
||||||
withSharedInbox = hasSharedInbox(session, httpPrefix, followerDomain)
|
withSharedInbox = _hasSharedInbox(session, httpPrefix, followerDomain)
|
||||||
if debug:
|
if debug:
|
||||||
if withSharedInbox:
|
if withSharedInbox:
|
||||||
print(followerDomain + ' has shared inbox')
|
print(followerDomain + ' has shared inbox')
|
||||||
|
|
@ -2467,7 +2468,7 @@ def sendToFollowers(session, baseDir: str,
|
||||||
toNickname = 'inbox'
|
toNickname = 'inbox'
|
||||||
|
|
||||||
if toNickname != 'inbox' and postJsonObject.get('type'):
|
if toNickname != 'inbox' and postJsonObject.get('type'):
|
||||||
if sendingProfileUpdate(postJsonObject):
|
if _sendingProfileUpdate(postJsonObject):
|
||||||
print('Sending post to followers ' +
|
print('Sending post to followers ' +
|
||||||
'shared inbox of ' + toDomain)
|
'shared inbox of ' + toDomain)
|
||||||
toNickname = 'inbox'
|
toNickname = 'inbox'
|
||||||
|
|
@ -2554,7 +2555,7 @@ def createInbox(recentPostsCache: {},
|
||||||
session, baseDir: str, nickname: str, domain: str, port: int,
|
session, baseDir: str, nickname: str, domain: str, port: int,
|
||||||
httpPrefix: str, itemsPerPage: int, headerOnly: bool,
|
httpPrefix: str, itemsPerPage: int, headerOnly: bool,
|
||||||
pageNumber=None) -> {}:
|
pageNumber=None) -> {}:
|
||||||
return createBoxIndexed(recentPostsCache,
|
return _createBoxIndexed(recentPostsCache,
|
||||||
session, baseDir, 'inbox',
|
session, baseDir, 'inbox',
|
||||||
nickname, domain, port, httpPrefix,
|
nickname, domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
|
|
@ -2564,7 +2565,7 @@ def createInbox(recentPostsCache: {},
|
||||||
def createBookmarksTimeline(session, baseDir: str, nickname: str, domain: str,
|
def createBookmarksTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'tlbookmarks',
|
return _createBoxIndexed({}, session, baseDir, 'tlbookmarks',
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
port, httpPrefix, itemsPerPage, headerOnly,
|
port, httpPrefix, itemsPerPage, headerOnly,
|
||||||
True, 0, False, 0, pageNumber)
|
True, 0, False, 0, pageNumber)
|
||||||
|
|
@ -2574,7 +2575,7 @@ def createEventsTimeline(recentPostsCache: {},
|
||||||
session, baseDir: str, nickname: str, domain: str,
|
session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed(recentPostsCache, session, baseDir, 'tlevents',
|
return _createBoxIndexed(recentPostsCache, session, baseDir, 'tlevents',
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
port, httpPrefix, itemsPerPage, headerOnly,
|
port, httpPrefix, itemsPerPage, headerOnly,
|
||||||
True, 0, False, 0, pageNumber)
|
True, 0, False, 0, pageNumber)
|
||||||
|
|
@ -2584,7 +2585,7 @@ def createDMTimeline(recentPostsCache: {},
|
||||||
session, baseDir: str, nickname: str, domain: str,
|
session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed(recentPostsCache,
|
return _createBoxIndexed(recentPostsCache,
|
||||||
session, baseDir, 'dm', nickname,
|
session, baseDir, 'dm', nickname,
|
||||||
domain, port, httpPrefix, itemsPerPage,
|
domain, port, httpPrefix, itemsPerPage,
|
||||||
headerOnly, True, 0, False, 0, pageNumber)
|
headerOnly, True, 0, False, 0, pageNumber)
|
||||||
|
|
@ -2594,7 +2595,7 @@ def createRepliesTimeline(recentPostsCache: {},
|
||||||
session, baseDir: str, nickname: str, domain: str,
|
session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed(recentPostsCache, session, baseDir, 'tlreplies',
|
return _createBoxIndexed(recentPostsCache, session, baseDir, 'tlreplies',
|
||||||
nickname, domain, port, httpPrefix,
|
nickname, domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
0, False, 0, pageNumber)
|
0, False, 0, pageNumber)
|
||||||
|
|
@ -2603,7 +2604,7 @@ def createRepliesTimeline(recentPostsCache: {},
|
||||||
def createBlogsTimeline(session, baseDir: str, nickname: str, domain: str,
|
def createBlogsTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'tlblogs', nickname,
|
return _createBoxIndexed({}, session, baseDir, 'tlblogs', nickname,
|
||||||
domain, port, httpPrefix,
|
domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
0, False, 0, pageNumber)
|
0, False, 0, pageNumber)
|
||||||
|
|
@ -2612,7 +2613,7 @@ def createBlogsTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
def createFeaturesTimeline(session, baseDir: str, nickname: str, domain: str,
|
def createFeaturesTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'tlfeatures', nickname,
|
return _createBoxIndexed({}, session, baseDir, 'tlfeatures', nickname,
|
||||||
domain, port, httpPrefix,
|
domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
0, False, 0, pageNumber)
|
0, False, 0, pageNumber)
|
||||||
|
|
@ -2621,7 +2622,7 @@ def createFeaturesTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
def createMediaTimeline(session, baseDir: str, nickname: str, domain: str,
|
def createMediaTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str, itemsPerPage: int,
|
port: int, httpPrefix: str, itemsPerPage: int,
|
||||||
headerOnly: bool, pageNumber=None) -> {}:
|
headerOnly: bool, pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'tlmedia', nickname,
|
return _createBoxIndexed({}, session, baseDir, 'tlmedia', nickname,
|
||||||
domain, port, httpPrefix,
|
domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
0, False, 0, pageNumber)
|
0, False, 0, pageNumber)
|
||||||
|
|
@ -2632,7 +2633,7 @@ def createNewsTimeline(session, baseDir: str, nickname: str, domain: str,
|
||||||
headerOnly: bool, newswireVotesThreshold: int,
|
headerOnly: bool, newswireVotesThreshold: int,
|
||||||
positiveVoting: bool, votingTimeMins: int,
|
positiveVoting: bool, votingTimeMins: int,
|
||||||
pageNumber=None) -> {}:
|
pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'outbox', 'news',
|
return _createBoxIndexed({}, session, baseDir, 'outbox', 'news',
|
||||||
domain, port, httpPrefix,
|
domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, True,
|
itemsPerPage, headerOnly, True,
|
||||||
newswireVotesThreshold, positiveVoting,
|
newswireVotesThreshold, positiveVoting,
|
||||||
|
|
@ -2643,7 +2644,7 @@ def createOutbox(session, baseDir: str, nickname: str, domain: str,
|
||||||
port: int, httpPrefix: str,
|
port: int, httpPrefix: str,
|
||||||
itemsPerPage: int, headerOnly: bool, authorized: bool,
|
itemsPerPage: int, headerOnly: bool, authorized: bool,
|
||||||
pageNumber=None) -> {}:
|
pageNumber=None) -> {}:
|
||||||
return createBoxIndexed({}, session, baseDir, 'outbox',
|
return _createBoxIndexed({}, session, baseDir, 'outbox',
|
||||||
nickname, domain, port, httpPrefix,
|
nickname, domain, port, httpPrefix,
|
||||||
itemsPerPage, headerOnly, authorized,
|
itemsPerPage, headerOnly, authorized,
|
||||||
0, False, 0, pageNumber)
|
0, False, 0, pageNumber)
|
||||||
|
|
@ -2816,7 +2817,7 @@ def isReply(postJsonObject: {}, actor: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def addPostStringToTimeline(postStr: str, boxname: str,
|
def _addPostStringToTimeline(postStr: str, boxname: str,
|
||||||
postsInBox: [], boxActor: str) -> bool:
|
postsInBox: [], boxActor: str) -> bool:
|
||||||
""" is this a valid timeline post?
|
""" is this a valid timeline post?
|
||||||
"""
|
"""
|
||||||
|
|
@ -2853,7 +2854,7 @@ def addPostStringToTimeline(postStr: str, boxname: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def addPostToTimeline(filePath: str, boxname: str,
|
def _addPostToTimeline(filePath: str, boxname: str,
|
||||||
postsInBox: [], boxActor: str) -> bool:
|
postsInBox: [], boxActor: str) -> bool:
|
||||||
""" Reads a post from file and decides whether it is valid
|
""" Reads a post from file and decides whether it is valid
|
||||||
"""
|
"""
|
||||||
|
|
@ -2866,11 +2867,11 @@ def addPostToTimeline(filePath: str, boxname: str,
|
||||||
# append a replies identifier, which will later be removed
|
# append a replies identifier, which will later be removed
|
||||||
postStr += '<hasReplies>'
|
postStr += '<hasReplies>'
|
||||||
|
|
||||||
return addPostStringToTimeline(postStr, boxname, postsInBox, boxActor)
|
return _addPostStringToTimeline(postStr, boxname, postsInBox, boxActor)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def createBoxIndexed(recentPostsCache: {},
|
def _createBoxIndexed(recentPostsCache: {},
|
||||||
session, baseDir: str, boxname: str,
|
session, baseDir: str, boxname: str,
|
||||||
nickname: str, domain: str, port: int, httpPrefix: str,
|
nickname: str, domain: str, port: int, httpPrefix: str,
|
||||||
itemsPerPage: int, headerOnly: bool, authorized: bool,
|
itemsPerPage: int, headerOnly: bool, authorized: bool,
|
||||||
|
|
@ -3006,7 +3007,7 @@ def createBoxIndexed(recentPostsCache: {},
|
||||||
if postUrl in recentPostsCache['index']:
|
if postUrl in recentPostsCache['index']:
|
||||||
if recentPostsCache['json'].get(postUrl):
|
if recentPostsCache['json'].get(postUrl):
|
||||||
url = recentPostsCache['json'][postUrl]
|
url = recentPostsCache['json'][postUrl]
|
||||||
addPostStringToTimeline(url,
|
_addPostStringToTimeline(url,
|
||||||
boxname, postsInBox,
|
boxname, postsInBox,
|
||||||
boxActor)
|
boxActor)
|
||||||
postsCtr += 1
|
postsCtr += 1
|
||||||
|
|
@ -3017,7 +3018,7 @@ def createBoxIndexed(recentPostsCache: {},
|
||||||
locatePost(baseDir, nickname,
|
locatePost(baseDir, nickname,
|
||||||
domain, postUrl, False)
|
domain, postUrl, False)
|
||||||
if fullPostFilename:
|
if fullPostFilename:
|
||||||
addPostToTimeline(fullPostFilename, boxname,
|
_addPostToTimeline(fullPostFilename, boxname,
|
||||||
postsInBox, boxActor)
|
postsInBox, boxActor)
|
||||||
else:
|
else:
|
||||||
# if this is the features timeline
|
# if this is the features timeline
|
||||||
|
|
@ -3026,7 +3027,7 @@ def createBoxIndexed(recentPostsCache: {},
|
||||||
locatePost(baseDir, timelineNickname,
|
locatePost(baseDir, timelineNickname,
|
||||||
domain, postUrl, False)
|
domain, postUrl, False)
|
||||||
if fullPostFilename:
|
if fullPostFilename:
|
||||||
addPostToTimeline(fullPostFilename, boxname,
|
_addPostToTimeline(fullPostFilename, boxname,
|
||||||
postsInBox, boxActor)
|
postsInBox, boxActor)
|
||||||
else:
|
else:
|
||||||
print('WARN: unable to locate post ' + postUrl)
|
print('WARN: unable to locate post ' + postUrl)
|
||||||
|
|
@ -3314,7 +3315,7 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str,
|
||||||
maxMentions = 10
|
maxMentions = 10
|
||||||
maxEmoji = 10
|
maxEmoji = 10
|
||||||
maxAttachments = 5
|
maxAttachments = 5
|
||||||
getPosts(session, personUrl, 30, maxMentions, maxEmoji,
|
_getPosts(session, personUrl, 30, maxMentions, maxEmoji,
|
||||||
maxAttachments, federationList,
|
maxAttachments, federationList,
|
||||||
personCache, raw, simple, debug,
|
personCache, raw, simple, debug,
|
||||||
projectVersion, httpPrefix, domain)
|
projectVersion, httpPrefix, domain)
|
||||||
|
|
@ -3413,7 +3414,7 @@ def getPublicPostInfo(session, baseDir: str, nickname: str, domain: str,
|
||||||
domainsInfo[d] = []
|
domainsInfo[d] = []
|
||||||
|
|
||||||
blockedPosts = \
|
blockedPosts = \
|
||||||
getPostsForBlockedDomains(baseDir, session, personUrl, maxPosts,
|
_getPostsForBlockedDomains(baseDir, session, personUrl, maxPosts,
|
||||||
maxMentions,
|
maxMentions,
|
||||||
maxEmoji, maxAttachments,
|
maxEmoji, maxAttachments,
|
||||||
federationList,
|
federationList,
|
||||||
|
|
@ -3467,7 +3468,7 @@ def getPublicPostDomainsBlocked(session, baseDir: str,
|
||||||
return blockedDomains
|
return blockedDomains
|
||||||
|
|
||||||
|
|
||||||
def getNonMutualsOfPerson(baseDir: str,
|
def _getNonMutualsOfPerson(baseDir: str,
|
||||||
nickname: str, domain: str) -> []:
|
nickname: str, domain: str) -> []:
|
||||||
"""Returns the followers who are not mutuals of a person
|
"""Returns the followers who are not mutuals of a person
|
||||||
i.e. accounts which follow you but you don't follow them
|
i.e. accounts which follow you but you don't follow them
|
||||||
|
|
@ -3490,7 +3491,7 @@ def checkDomains(session, baseDir: str,
|
||||||
maxBlockedDomains: int, singleCheck: bool):
|
maxBlockedDomains: int, singleCheck: bool):
|
||||||
"""Checks follower accounts for references to globally blocked domains
|
"""Checks follower accounts for references to globally blocked domains
|
||||||
"""
|
"""
|
||||||
nonMutuals = getNonMutualsOfPerson(baseDir, nickname, domain)
|
nonMutuals = _getNonMutualsOfPerson(baseDir, nickname, domain)
|
||||||
if not nonMutuals:
|
if not nonMutuals:
|
||||||
print('No non-mutual followers were found')
|
print('No non-mutual followers were found')
|
||||||
return
|
return
|
||||||
|
|
@ -3614,7 +3615,7 @@ def populateRepliesJson(baseDir: str, nickname: str, domain: str,
|
||||||
repliesJson['orderedItems'].append(pjo)
|
repliesJson['orderedItems'].append(pjo)
|
||||||
|
|
||||||
|
|
||||||
def rejectAnnounce(announceFilename: str):
|
def _rejectAnnounce(announceFilename: str):
|
||||||
"""Marks an announce as rejected
|
"""Marks an announce as rejected
|
||||||
"""
|
"""
|
||||||
if not os.path.isfile(announceFilename + '.reject'):
|
if not os.path.isfile(announceFilename + '.reject'):
|
||||||
|
|
@ -3699,40 +3700,40 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
|
||||||
if not isinstance(announcedJson, dict):
|
if not isinstance(announcedJson, dict):
|
||||||
print('WARN: announce json is not a dict - ' +
|
print('WARN: announce json is not a dict - ' +
|
||||||
postJsonObject['object'])
|
postJsonObject['object'])
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if not announcedJson.get('id'):
|
if not announcedJson.get('id'):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if '/statuses/' not in announcedJson['id']:
|
if '/statuses/' not in announcedJson['id']:
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if '/users/' not in announcedJson['id'] and \
|
if '/users/' not in announcedJson['id'] and \
|
||||||
'/accounts/' not in announcedJson['id'] and \
|
'/accounts/' not in announcedJson['id'] and \
|
||||||
'/channel/' not in announcedJson['id'] and \
|
'/channel/' not in announcedJson['id'] and \
|
||||||
'/profile/' not in announcedJson['id']:
|
'/profile/' not in announcedJson['id']:
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if not announcedJson.get('type'):
|
if not announcedJson.get('type'):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
# pprint(announcedJson)
|
# pprint(announcedJson)
|
||||||
return None
|
return None
|
||||||
if announcedJson['type'] != 'Note' and \
|
if announcedJson['type'] != 'Note' and \
|
||||||
announcedJson['type'] != 'Article':
|
announcedJson['type'] != 'Article':
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
# pprint(announcedJson)
|
# pprint(announcedJson)
|
||||||
return None
|
return None
|
||||||
if not announcedJson.get('content'):
|
if not announcedJson.get('content'):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if not announcedJson.get('published'):
|
if not announcedJson.get('published'):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if not validPostDate(announcedJson['published']):
|
if not validPostDate(announcedJson['published']):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
if isFiltered(baseDir, nickname, domain, announcedJson['content']):
|
if isFiltered(baseDir, nickname, domain, announcedJson['content']):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
# remove any long words
|
# remove any long words
|
||||||
announcedJson['content'] = \
|
announcedJson['content'] = \
|
||||||
|
|
@ -3748,7 +3749,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
|
||||||
actorNickname, actorDomain, actorPort,
|
actorNickname, actorDomain, actorPort,
|
||||||
announcedJson)
|
announcedJson)
|
||||||
if announcedJson['type'] != 'Create':
|
if announcedJson['type'] != 'Create':
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
# pprint(announcedJson)
|
# pprint(announcedJson)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -3765,7 +3766,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
|
||||||
attributedDomain = getFullDomain(attributedDomain, attributedPort)
|
attributedDomain = getFullDomain(attributedDomain, attributedPort)
|
||||||
if isBlocked(baseDir, nickname, domain,
|
if isBlocked(baseDir, nickname, domain,
|
||||||
attributedNickname, attributedDomain):
|
attributedNickname, attributedDomain):
|
||||||
rejectAnnounce(announceFilename)
|
_rejectAnnounce(announceFilename)
|
||||||
return None
|
return None
|
||||||
postJsonObject = announcedJson
|
postJsonObject = announcedJson
|
||||||
replaceYouTube(postJsonObject, YTReplacementDomain)
|
replaceYouTube(postJsonObject, YTReplacementDomain)
|
||||||
|
|
|
||||||
16
roles.py
16
roles.py
|
|
@ -63,7 +63,7 @@ def clearEditorStatus(baseDir: str) -> None:
|
||||||
saveJson(actorJson, filename)
|
saveJson(actorJson, filename)
|
||||||
|
|
||||||
|
|
||||||
def addModerator(baseDir: str, nickname: str, domain: str) -> None:
|
def _addModerator(baseDir: str, nickname: str, domain: str) -> None:
|
||||||
"""Adds a moderator nickname to the file
|
"""Adds a moderator nickname to the file
|
||||||
"""
|
"""
|
||||||
if ':' in domain:
|
if ':' in domain:
|
||||||
|
|
@ -92,7 +92,7 @@ def addModerator(baseDir: str, nickname: str, domain: str) -> None:
|
||||||
f.write(nickname + '\n')
|
f.write(nickname + '\n')
|
||||||
|
|
||||||
|
|
||||||
def removeModerator(baseDir: str, nickname: str):
|
def _removeModerator(baseDir: str, nickname: str):
|
||||||
"""Removes a moderator nickname from the file
|
"""Removes a moderator nickname from the file
|
||||||
"""
|
"""
|
||||||
moderatorsFile = baseDir + '/accounts/moderators.txt'
|
moderatorsFile = baseDir + '/accounts/moderators.txt'
|
||||||
|
|
@ -125,7 +125,7 @@ def setRole(baseDir: str, nickname: str, domain: str,
|
||||||
if role:
|
if role:
|
||||||
# add the role
|
# add the role
|
||||||
if project == 'instance' and 'role' == 'moderator':
|
if project == 'instance' and 'role' == 'moderator':
|
||||||
addModerator(baseDir, nickname, domain)
|
_addModerator(baseDir, nickname, domain)
|
||||||
if actorJson['roles'].get(project):
|
if actorJson['roles'].get(project):
|
||||||
if role not in actorJson['roles'][project]:
|
if role not in actorJson['roles'][project]:
|
||||||
actorJson['roles'][project].append(role)
|
actorJson['roles'][project].append(role)
|
||||||
|
|
@ -134,7 +134,7 @@ def setRole(baseDir: str, nickname: str, domain: str,
|
||||||
else:
|
else:
|
||||||
# remove the role
|
# remove the role
|
||||||
if project == 'instance':
|
if project == 'instance':
|
||||||
removeModerator(baseDir, nickname)
|
_removeModerator(baseDir, nickname)
|
||||||
if actorJson['roles'].get(project):
|
if actorJson['roles'].get(project):
|
||||||
actorJson['roles'][project].remove(role)
|
actorJson['roles'][project].remove(role)
|
||||||
# if the project contains no roles then remove it
|
# if the project contains no roles then remove it
|
||||||
|
|
@ -144,7 +144,7 @@ def setRole(baseDir: str, nickname: str, domain: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def getRoles(baseDir: str, nickname: str, domain: str,
|
def _getRoles(baseDir: str, nickname: str, domain: str,
|
||||||
project: str) -> []:
|
project: str) -> []:
|
||||||
"""Returns the roles for a given person on a given project
|
"""Returns the roles for a given person on a given project
|
||||||
"""
|
"""
|
||||||
|
|
@ -198,7 +198,7 @@ def outboxDelegate(baseDir: str, authenticatedNickname: str,
|
||||||
# instance delegators can delagate to other projects
|
# instance delegators can delagate to other projects
|
||||||
# than their own
|
# than their own
|
||||||
canDelegate = False
|
canDelegate = False
|
||||||
delegatorRoles = getRoles(baseDir, delegatorNickname,
|
delegatorRoles = _getRoles(baseDir, delegatorNickname,
|
||||||
domain, 'instance')
|
domain, 'instance')
|
||||||
if delegatorRoles:
|
if delegatorRoles:
|
||||||
if 'delegator' in delegatorRoles:
|
if 'delegator' in delegatorRoles:
|
||||||
|
|
@ -207,7 +207,7 @@ def outboxDelegate(baseDir: str, authenticatedNickname: str,
|
||||||
if not canDelegate:
|
if not canDelegate:
|
||||||
canDelegate = True
|
canDelegate = True
|
||||||
# non-instance delegators can only delegate within their project
|
# non-instance delegators can only delegate within their project
|
||||||
delegatorRoles = getRoles(baseDir, delegatorNickname,
|
delegatorRoles = _getRoles(baseDir, delegatorNickname,
|
||||||
domain, project)
|
domain, project)
|
||||||
if delegatorRoles:
|
if delegatorRoles:
|
||||||
if 'delegator' not in delegatorRoles:
|
if 'delegator' not in delegatorRoles:
|
||||||
|
|
@ -230,7 +230,7 @@ def outboxDelegate(baseDir: str, authenticatedNickname: str,
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# what roles is this person already assigned to?
|
# what roles is this person already assigned to?
|
||||||
existingRoles = getRoles(baseDir, nickname, domain, project)
|
existingRoles = _getRoles(baseDir, nickname, domain, project)
|
||||||
if existingRoles:
|
if existingRoles:
|
||||||
if role in existingRoles:
|
if role in existingRoles:
|
||||||
if debug:
|
if debug:
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ from utils import loadJson
|
||||||
from outbox import postMessageToOutbox
|
from outbox import postMessageToOutbox
|
||||||
|
|
||||||
|
|
||||||
def updatePostSchedule(baseDir: str, handle: str, httpd,
|
def _updatePostSchedule(baseDir: str, handle: str, httpd,
|
||||||
maxScheduledPosts: int) -> None:
|
maxScheduledPosts: int) -> None:
|
||||||
"""Checks if posts are due to be delivered and if so moves them to the outbox
|
"""Checks if posts are due to be delivered and if so moves them to the outbox
|
||||||
"""
|
"""
|
||||||
|
|
@ -145,7 +145,7 @@ def runPostSchedule(baseDir: str, httpd, maxScheduledPosts: int):
|
||||||
baseDir + '/accounts/' + account + '/schedule.index'
|
baseDir + '/accounts/' + account + '/schedule.index'
|
||||||
if not os.path.isfile(scheduleIndexFilename):
|
if not os.path.isfile(scheduleIndexFilename):
|
||||||
continue
|
continue
|
||||||
updatePostSchedule(baseDir, account, httpd, maxScheduledPosts)
|
_updatePostSchedule(baseDir, account, httpd, maxScheduledPosts)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -176,11 +176,11 @@ def expireShares(baseDir: str) -> None:
|
||||||
continue
|
continue
|
||||||
nickname = account.split('@')[0]
|
nickname = account.split('@')[0]
|
||||||
domain = account.split('@')[1]
|
domain = account.split('@')[1]
|
||||||
expireSharesForAccount(baseDir, nickname, domain)
|
_expireSharesForAccount(baseDir, nickname, domain)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def expireSharesForAccount(baseDir: str, nickname: str, domain: str) -> None:
|
def _expireSharesForAccount(baseDir: str, nickname: str, domain: str) -> None:
|
||||||
"""Removes expired items from shares for a particular account
|
"""Removes expired items from shares for a particular account
|
||||||
"""
|
"""
|
||||||
handleDomain = domain
|
handleDomain = domain
|
||||||
|
|
|
||||||
23
tests.py
23
tests.py
|
|
@ -101,7 +101,7 @@ thrBob = None
|
||||||
thrEve = None
|
thrEve = None
|
||||||
|
|
||||||
|
|
||||||
def testHttpsigBase(withDigest):
|
def _testHttpsigBase(withDigest):
|
||||||
print('testHttpsig(' + str(withDigest) + ')')
|
print('testHttpsig(' + str(withDigest) + ')')
|
||||||
|
|
||||||
baseDir = os.getcwd()
|
baseDir = os.getcwd()
|
||||||
|
|
@ -206,8 +206,8 @@ def testHttpsigBase(withDigest):
|
||||||
|
|
||||||
|
|
||||||
def testHttpsig():
|
def testHttpsig():
|
||||||
testHttpsigBase(True)
|
_testHttpsigBase(True)
|
||||||
testHttpsigBase(False)
|
_testHttpsigBase(False)
|
||||||
|
|
||||||
|
|
||||||
def testCache():
|
def testCache():
|
||||||
|
|
@ -2617,6 +2617,11 @@ def testFunctions():
|
||||||
excludeImports = [
|
excludeImports = [
|
||||||
'link'
|
'link'
|
||||||
]
|
]
|
||||||
|
excludeLocal = [
|
||||||
|
'pyjsonld',
|
||||||
|
'daemon',
|
||||||
|
'tests'
|
||||||
|
]
|
||||||
# check that functions are called somewhere
|
# check that functions are called somewhere
|
||||||
for name, properties in functionProperties.items():
|
for name, properties in functionProperties.items():
|
||||||
if name in exclusions:
|
if name in exclusions:
|
||||||
|
|
@ -2626,6 +2631,16 @@ def testFunctions():
|
||||||
' in module ' + properties['module'] +
|
' in module ' + properties['module'] +
|
||||||
' is not called anywhere')
|
' is not called anywhere')
|
||||||
assert properties['calledInModule']
|
assert properties['calledInModule']
|
||||||
|
|
||||||
|
if len(properties['calledInModule']) == 1:
|
||||||
|
modName = properties['calledInModule'][0]
|
||||||
|
if modName not in excludeLocal and \
|
||||||
|
modName == properties['module']:
|
||||||
|
if not name.startswith('_'):
|
||||||
|
print('Local function ' + name +
|
||||||
|
' in ' + modName + ' does not begin with _')
|
||||||
|
assert False
|
||||||
|
|
||||||
if name not in excludeImports:
|
if name not in excludeImports:
|
||||||
for modName in properties['calledInModule']:
|
for modName in properties['calledInModule']:
|
||||||
if modName == properties['module']:
|
if modName == properties['module']:
|
||||||
|
|
@ -2635,8 +2650,6 @@ def testFunctions():
|
||||||
print(importStr + ' not found in ' + modName + '.py')
|
print(importStr + ' not found in ' + modName + '.py')
|
||||||
assert False
|
assert False
|
||||||
print('Function: ' + name + ' ✓')
|
print('Function: ' + name + ' ✓')
|
||||||
# print(str(function))
|
|
||||||
# print(str(functionProperties))
|
|
||||||
|
|
||||||
|
|
||||||
def runAllTests():
|
def runAllTests():
|
||||||
|
|
|
||||||
92
theme.py
92
theme.py
|
|
@ -14,7 +14,7 @@ from shutil import copyfile
|
||||||
from content import dangerousCSS
|
from content import dangerousCSS
|
||||||
|
|
||||||
|
|
||||||
def getThemeFiles() -> []:
|
def _getThemeFiles() -> []:
|
||||||
return ('epicyon.css', 'login.css', 'follow.css',
|
return ('epicyon.css', 'login.css', 'follow.css',
|
||||||
'suspended.css', 'calendar.css', 'blog.css',
|
'suspended.css', 'calendar.css', 'blog.css',
|
||||||
'options.css', 'search.css', 'links.css')
|
'options.css', 'search.css', 'links.css')
|
||||||
|
|
@ -38,7 +38,7 @@ def getThemesList(baseDir: str) -> []:
|
||||||
return themes
|
return themes
|
||||||
|
|
||||||
|
|
||||||
def setThemeInConfig(baseDir: str, name: str) -> bool:
|
def _setThemeInConfig(baseDir: str, name: str) -> bool:
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
if not os.path.isfile(configFilename):
|
if not os.path.isfile(configFilename):
|
||||||
return False
|
return False
|
||||||
|
|
@ -49,7 +49,7 @@ def setThemeInConfig(baseDir: str, name: str) -> bool:
|
||||||
return saveJson(configJson, configFilename)
|
return saveJson(configJson, configFilename)
|
||||||
|
|
||||||
|
|
||||||
def setNewswirePublishAsIcon(baseDir: str, useIcon: bool) -> bool:
|
def _setNewswirePublishAsIcon(baseDir: str, useIcon: bool) -> bool:
|
||||||
"""Shows the newswire publish action as an icon or a button
|
"""Shows the newswire publish action as an icon or a button
|
||||||
"""
|
"""
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
|
|
@ -62,7 +62,7 @@ def setNewswirePublishAsIcon(baseDir: str, useIcon: bool) -> bool:
|
||||||
return saveJson(configJson, configFilename)
|
return saveJson(configJson, configFilename)
|
||||||
|
|
||||||
|
|
||||||
def setIconsAsButtons(baseDir: str, useButtons: bool) -> bool:
|
def _setIconsAsButtons(baseDir: str, useButtons: bool) -> bool:
|
||||||
"""Whether to show icons in the header (inbox, outbox, etc)
|
"""Whether to show icons in the header (inbox, outbox, etc)
|
||||||
as buttons
|
as buttons
|
||||||
"""
|
"""
|
||||||
|
|
@ -76,7 +76,7 @@ def setIconsAsButtons(baseDir: str, useButtons: bool) -> bool:
|
||||||
return saveJson(configJson, configFilename)
|
return saveJson(configJson, configFilename)
|
||||||
|
|
||||||
|
|
||||||
def setRssIconAtTop(baseDir: str, atTop: bool) -> bool:
|
def _setRssIconAtTop(baseDir: str, atTop: bool) -> bool:
|
||||||
"""Whether to show RSS icon at the top of the timeline
|
"""Whether to show RSS icon at the top of the timeline
|
||||||
"""
|
"""
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
|
|
@ -89,7 +89,7 @@ def setRssIconAtTop(baseDir: str, atTop: bool) -> bool:
|
||||||
return saveJson(configJson, configFilename)
|
return saveJson(configJson, configFilename)
|
||||||
|
|
||||||
|
|
||||||
def setPublishButtonAtTop(baseDir: str, atTop: bool) -> bool:
|
def _setPublishButtonAtTop(baseDir: str, atTop: bool) -> bool:
|
||||||
"""Whether to show the publish button above the title image
|
"""Whether to show the publish button above the title image
|
||||||
in the newswire column
|
in the newswire column
|
||||||
"""
|
"""
|
||||||
|
|
@ -103,7 +103,7 @@ def setPublishButtonAtTop(baseDir: str, atTop: bool) -> bool:
|
||||||
return saveJson(configJson, configFilename)
|
return saveJson(configJson, configFilename)
|
||||||
|
|
||||||
|
|
||||||
def setFullWidthTimelineButtonHeader(baseDir: str, fullWidth: bool) -> bool:
|
def _setFullWidthTimelineButtonHeader(baseDir: str, fullWidth: bool) -> bool:
|
||||||
"""Shows the timeline button header containing inbox, outbox,
|
"""Shows the timeline button header containing inbox, outbox,
|
||||||
calendar, etc as full width
|
calendar, etc as full width
|
||||||
"""
|
"""
|
||||||
|
|
@ -127,8 +127,8 @@ def getTheme(baseDir: str) -> str:
|
||||||
return 'default'
|
return 'default'
|
||||||
|
|
||||||
|
|
||||||
def removeTheme(baseDir: str):
|
def _removeTheme(baseDir: str):
|
||||||
themeFiles = getThemeFiles()
|
themeFiles = _getThemeFiles()
|
||||||
for filename in themeFiles:
|
for filename in themeFiles:
|
||||||
if os.path.isfile(baseDir + '/' + filename):
|
if os.path.isfile(baseDir + '/' + filename):
|
||||||
os.remove(baseDir + '/' + filename)
|
os.remove(baseDir + '/' + filename)
|
||||||
|
|
@ -183,14 +183,14 @@ def setCSSparam(css: str, param: str, value: str) -> str:
|
||||||
return newcss.strip()
|
return newcss.strip()
|
||||||
|
|
||||||
|
|
||||||
def setThemeFromDict(baseDir: str, name: str,
|
def _setThemeFromDict(baseDir: str, name: str,
|
||||||
themeParams: {}, bgParams: {},
|
themeParams: {}, bgParams: {},
|
||||||
allowLocalNetworkAccess: bool) -> None:
|
allowLocalNetworkAccess: bool) -> None:
|
||||||
"""Uses a dictionary to set a theme
|
"""Uses a dictionary to set a theme
|
||||||
"""
|
"""
|
||||||
if name:
|
if name:
|
||||||
setThemeInConfig(baseDir, name)
|
_setThemeInConfig(baseDir, name)
|
||||||
themeFiles = getThemeFiles()
|
themeFiles = _getThemeFiles()
|
||||||
for filename in themeFiles:
|
for filename in themeFiles:
|
||||||
# check for custom css within the theme directory
|
# check for custom css within the theme directory
|
||||||
templateFilename = baseDir + '/theme/' + name + '/epicyon-' + filename
|
templateFilename = baseDir + '/theme/' + name + '/epicyon-' + filename
|
||||||
|
|
@ -215,33 +215,33 @@ def setThemeFromDict(baseDir: str, name: str,
|
||||||
for paramName, paramValue in themeParams.items():
|
for paramName, paramValue in themeParams.items():
|
||||||
if paramName == 'newswire-publish-icon':
|
if paramName == 'newswire-publish-icon':
|
||||||
if paramValue.lower() == 'true':
|
if paramValue.lower() == 'true':
|
||||||
setNewswirePublishAsIcon(baseDir, True)
|
_setNewswirePublishAsIcon(baseDir, True)
|
||||||
else:
|
else:
|
||||||
setNewswirePublishAsIcon(baseDir, False)
|
_setNewswirePublishAsIcon(baseDir, False)
|
||||||
continue
|
continue
|
||||||
elif paramName == 'full-width-timeline-buttons':
|
elif paramName == 'full-width-timeline-buttons':
|
||||||
if paramValue.lower() == 'true':
|
if paramValue.lower() == 'true':
|
||||||
setFullWidthTimelineButtonHeader(baseDir, True)
|
_setFullWidthTimelineButtonHeader(baseDir, True)
|
||||||
else:
|
else:
|
||||||
setFullWidthTimelineButtonHeader(baseDir, False)
|
_setFullWidthTimelineButtonHeader(baseDir, False)
|
||||||
continue
|
continue
|
||||||
elif paramName == 'icons-as-buttons':
|
elif paramName == 'icons-as-buttons':
|
||||||
if paramValue.lower() == 'true':
|
if paramValue.lower() == 'true':
|
||||||
setIconsAsButtons(baseDir, True)
|
_setIconsAsButtons(baseDir, True)
|
||||||
else:
|
else:
|
||||||
setIconsAsButtons(baseDir, False)
|
_setIconsAsButtons(baseDir, False)
|
||||||
continue
|
continue
|
||||||
elif paramName == 'rss-icon-at-top':
|
elif paramName == 'rss-icon-at-top':
|
||||||
if paramValue.lower() == 'true':
|
if paramValue.lower() == 'true':
|
||||||
setRssIconAtTop(baseDir, True)
|
_setRssIconAtTop(baseDir, True)
|
||||||
else:
|
else:
|
||||||
setRssIconAtTop(baseDir, False)
|
_setRssIconAtTop(baseDir, False)
|
||||||
continue
|
continue
|
||||||
elif paramName == 'publish-button-at-top':
|
elif paramName == 'publish-button-at-top':
|
||||||
if paramValue.lower() == 'true':
|
if paramValue.lower() == 'true':
|
||||||
setPublishButtonAtTop(baseDir, True)
|
_setPublishButtonAtTop(baseDir, True)
|
||||||
else:
|
else:
|
||||||
setPublishButtonAtTop(baseDir, False)
|
_setPublishButtonAtTop(baseDir, False)
|
||||||
continue
|
continue
|
||||||
css = setCSSparam(css, paramName, paramValue)
|
css = setCSSparam(css, paramName, paramValue)
|
||||||
filename = baseDir + '/' + filename
|
filename = baseDir + '/' + filename
|
||||||
|
|
@ -249,16 +249,16 @@ def setThemeFromDict(baseDir: str, name: str,
|
||||||
cssfile.write(css)
|
cssfile.write(css)
|
||||||
|
|
||||||
if bgParams.get('login'):
|
if bgParams.get('login'):
|
||||||
setBackgroundFormat(baseDir, name, 'login', bgParams['login'])
|
_setBackgroundFormat(baseDir, name, 'login', bgParams['login'])
|
||||||
if bgParams.get('follow'):
|
if bgParams.get('follow'):
|
||||||
setBackgroundFormat(baseDir, name, 'follow', bgParams['follow'])
|
_setBackgroundFormat(baseDir, name, 'follow', bgParams['follow'])
|
||||||
if bgParams.get('options'):
|
if bgParams.get('options'):
|
||||||
setBackgroundFormat(baseDir, name, 'options', bgParams['options'])
|
_setBackgroundFormat(baseDir, name, 'options', bgParams['options'])
|
||||||
if bgParams.get('search'):
|
if bgParams.get('search'):
|
||||||
setBackgroundFormat(baseDir, name, 'search', bgParams['search'])
|
_setBackgroundFormat(baseDir, name, 'search', bgParams['search'])
|
||||||
|
|
||||||
|
|
||||||
def setBackgroundFormat(baseDir: str, name: str,
|
def _setBackgroundFormat(baseDir: str, name: str,
|
||||||
backgroundType: str, extension: str) -> None:
|
backgroundType: str, extension: str) -> None:
|
||||||
"""Sets the background file extension
|
"""Sets the background file extension
|
||||||
"""
|
"""
|
||||||
|
|
@ -277,7 +277,7 @@ def setBackgroundFormat(baseDir: str, name: str,
|
||||||
def enableGrayscale(baseDir: str) -> None:
|
def enableGrayscale(baseDir: str) -> None:
|
||||||
"""Enables grayscale for the current theme
|
"""Enables grayscale for the current theme
|
||||||
"""
|
"""
|
||||||
themeFiles = getThemeFiles()
|
themeFiles = _getThemeFiles()
|
||||||
for filename in themeFiles:
|
for filename in themeFiles:
|
||||||
templateFilename = baseDir + '/' + filename
|
templateFilename = baseDir + '/' + filename
|
||||||
if not os.path.isfile(templateFilename):
|
if not os.path.isfile(templateFilename):
|
||||||
|
|
@ -300,7 +300,7 @@ def enableGrayscale(baseDir: str) -> None:
|
||||||
def disableGrayscale(baseDir: str) -> None:
|
def disableGrayscale(baseDir: str) -> None:
|
||||||
"""Disables grayscale for the current theme
|
"""Disables grayscale for the current theme
|
||||||
"""
|
"""
|
||||||
themeFiles = getThemeFiles()
|
themeFiles = _getThemeFiles()
|
||||||
for filename in themeFiles:
|
for filename in themeFiles:
|
||||||
templateFilename = baseDir + '/' + filename
|
templateFilename = baseDir + '/' + filename
|
||||||
if not os.path.isfile(templateFilename):
|
if not os.path.isfile(templateFilename):
|
||||||
|
|
@ -318,7 +318,7 @@ def disableGrayscale(baseDir: str) -> None:
|
||||||
os.remove(grayscaleFilename)
|
os.remove(grayscaleFilename)
|
||||||
|
|
||||||
|
|
||||||
def setCustomFont(baseDir: str):
|
def _setCustomFont(baseDir: str):
|
||||||
"""Uses a dictionary to set a theme
|
"""Uses a dictionary to set a theme
|
||||||
"""
|
"""
|
||||||
customFontExt = None
|
customFontExt = None
|
||||||
|
|
@ -337,7 +337,7 @@ def setCustomFont(baseDir: str):
|
||||||
if not customFontExt:
|
if not customFontExt:
|
||||||
return
|
return
|
||||||
|
|
||||||
themeFiles = getThemeFiles()
|
themeFiles = _getThemeFiles()
|
||||||
for filename in themeFiles:
|
for filename in themeFiles:
|
||||||
templateFilename = baseDir + '/' + filename
|
templateFilename = baseDir + '/' + filename
|
||||||
if not os.path.isfile(templateFilename):
|
if not os.path.isfile(templateFilename):
|
||||||
|
|
@ -356,7 +356,7 @@ def setCustomFont(baseDir: str):
|
||||||
cssfile.write(css)
|
cssfile.write(css)
|
||||||
|
|
||||||
|
|
||||||
def readVariablesFile(baseDir: str, themeName: str,
|
def _readVariablesFile(baseDir: str, themeName: str,
|
||||||
variablesFile: str,
|
variablesFile: str,
|
||||||
allowLocalNetworkAccess: bool) -> None:
|
allowLocalNetworkAccess: bool) -> None:
|
||||||
"""Reads variables from a file in the theme directory
|
"""Reads variables from a file in the theme directory
|
||||||
|
|
@ -370,14 +370,14 @@ def readVariablesFile(baseDir: str, themeName: str,
|
||||||
"options": "jpg",
|
"options": "jpg",
|
||||||
"search": "jpg"
|
"search": "jpg"
|
||||||
}
|
}
|
||||||
setThemeFromDict(baseDir, themeName, themeParams, bgParams,
|
_setThemeFromDict(baseDir, themeName, themeParams, bgParams,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess)
|
||||||
|
|
||||||
|
|
||||||
def setThemeDefault(baseDir: str, allowLocalNetworkAccess: bool):
|
def _setThemeDefault(baseDir: str, allowLocalNetworkAccess: bool):
|
||||||
name = 'default'
|
name = 'default'
|
||||||
removeTheme(baseDir)
|
_removeTheme(baseDir)
|
||||||
setThemeInConfig(baseDir, name)
|
_setThemeInConfig(baseDir, name)
|
||||||
bgParams = {
|
bgParams = {
|
||||||
"login": "jpg",
|
"login": "jpg",
|
||||||
"follow": "jpg",
|
"follow": "jpg",
|
||||||
|
|
@ -394,11 +394,11 @@ def setThemeDefault(baseDir: str, allowLocalNetworkAccess: bool):
|
||||||
"banner-height-mobile": "10vh",
|
"banner-height-mobile": "10vh",
|
||||||
"search-banner-height-mobile": "15vh"
|
"search-banner-height-mobile": "15vh"
|
||||||
}
|
}
|
||||||
setThemeFromDict(baseDir, name, themeParams, bgParams,
|
_setThemeFromDict(baseDir, name, themeParams, bgParams,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess)
|
||||||
|
|
||||||
|
|
||||||
def setThemeFonts(baseDir: str, themeName: str) -> None:
|
def _setThemeFonts(baseDir: str, themeName: str) -> None:
|
||||||
"""Adds custom theme fonts
|
"""Adds custom theme fonts
|
||||||
"""
|
"""
|
||||||
themeNameLower = themeName.lower()
|
themeNameLower = themeName.lower()
|
||||||
|
|
@ -422,7 +422,7 @@ def setThemeFonts(baseDir: str, themeName: str) -> None:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def setThemeImages(baseDir: str, name: str) -> None:
|
def _setThemeImages(baseDir: str, name: str) -> None:
|
||||||
"""Changes the profile background image
|
"""Changes the profile background image
|
||||||
and banner to the defaults
|
and banner to the defaults
|
||||||
"""
|
"""
|
||||||
|
|
@ -557,7 +557,7 @@ def setTheme(baseDir: str, name: str, domain: str,
|
||||||
result = False
|
result = False
|
||||||
|
|
||||||
prevThemeName = getTheme(baseDir)
|
prevThemeName = getTheme(baseDir)
|
||||||
removeTheme(baseDir)
|
_removeTheme(baseDir)
|
||||||
|
|
||||||
themes = getThemesList(baseDir)
|
themes = getThemesList(baseDir)
|
||||||
for themeName in themes:
|
for themeName in themes:
|
||||||
|
|
@ -573,21 +573,21 @@ def setTheme(baseDir: str, name: str, domain: str,
|
||||||
if prevThemeName.lower() != themeNameLower:
|
if prevThemeName.lower() != themeNameLower:
|
||||||
# change the banner and profile image
|
# change the banner and profile image
|
||||||
# to the default for the theme
|
# to the default for the theme
|
||||||
setThemeImages(baseDir, name)
|
_setThemeImages(baseDir, name)
|
||||||
setThemeFonts(baseDir, name)
|
_setThemeFonts(baseDir, name)
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
if not result:
|
if not result:
|
||||||
# default
|
# default
|
||||||
setThemeDefault(baseDir)
|
_setThemeDefault(baseDir)
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
variablesFile = baseDir + '/theme/' + name + '/theme.json'
|
variablesFile = baseDir + '/theme/' + name + '/theme.json'
|
||||||
if os.path.isfile(variablesFile):
|
if os.path.isfile(variablesFile):
|
||||||
readVariablesFile(baseDir, name, variablesFile,
|
_readVariablesFile(baseDir, name, variablesFile,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess)
|
||||||
|
|
||||||
setCustomFont(baseDir)
|
_setCustomFont(baseDir)
|
||||||
|
|
||||||
# set the news avatar
|
# set the news avatar
|
||||||
newsAvatarThemeFilename = \
|
newsAvatarThemeFilename = \
|
||||||
|
|
@ -604,5 +604,5 @@ def setTheme(baseDir: str, name: str, domain: str,
|
||||||
else:
|
else:
|
||||||
disableGrayscale(baseDir)
|
disableGrayscale(baseDir)
|
||||||
|
|
||||||
setThemeInConfig(baseDir, name)
|
_setThemeInConfig(baseDir, name)
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
19
utils.py
19
utils.py
|
|
@ -197,7 +197,7 @@ def isSystemAccount(nickname: str) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def createConfig(baseDir: str) -> None:
|
def _createConfig(baseDir: str) -> None:
|
||||||
"""Creates a configuration file
|
"""Creates a configuration file
|
||||||
"""
|
"""
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
|
|
@ -211,7 +211,7 @@ def createConfig(baseDir: str) -> None:
|
||||||
def setConfigParam(baseDir: str, variableName: str, variableValue) -> None:
|
def setConfigParam(baseDir: str, variableName: str, variableValue) -> None:
|
||||||
"""Sets a configuration value
|
"""Sets a configuration value
|
||||||
"""
|
"""
|
||||||
createConfig(baseDir)
|
_createConfig(baseDir)
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
configJson = {}
|
configJson = {}
|
||||||
if os.path.isfile(configFilename):
|
if os.path.isfile(configFilename):
|
||||||
|
|
@ -223,7 +223,7 @@ def setConfigParam(baseDir: str, variableName: str, variableValue) -> None:
|
||||||
def getConfigParam(baseDir: str, variableName: str):
|
def getConfigParam(baseDir: str, variableName: str):
|
||||||
"""Gets a configuration value
|
"""Gets a configuration value
|
||||||
"""
|
"""
|
||||||
createConfig(baseDir)
|
_createConfig(baseDir)
|
||||||
configFilename = baseDir + '/config.json'
|
configFilename = baseDir + '/config.json'
|
||||||
configJson = loadJson(configFilename)
|
configJson = loadJson(configFilename)
|
||||||
if configJson:
|
if configJson:
|
||||||
|
|
@ -610,7 +610,7 @@ def getDomainFromActor(actor: str) -> (str, int):
|
||||||
return domain, port
|
return domain, port
|
||||||
|
|
||||||
|
|
||||||
def setDefaultPetName(baseDir: str, nickname: str, domain: str,
|
def _setDefaultPetName(baseDir: str, nickname: str, domain: str,
|
||||||
followNickname: str, followDomain: str) -> None:
|
followNickname: str, followDomain: str) -> None:
|
||||||
"""Sets a default petname
|
"""Sets a default petname
|
||||||
This helps especially when using onion or i2p address
|
This helps especially when using onion or i2p address
|
||||||
|
|
@ -723,7 +723,7 @@ def followPerson(baseDir: str, nickname: str, domain: str,
|
||||||
addPersonToCalendar(baseDir, nickname, domain,
|
addPersonToCalendar(baseDir, nickname, domain,
|
||||||
followNickname, followDomain)
|
followNickname, followDomain)
|
||||||
# add a default petname
|
# add a default petname
|
||||||
setDefaultPetName(baseDir, nickname, domain,
|
_setDefaultPetName(baseDir, nickname, domain,
|
||||||
followNickname, followDomain)
|
followNickname, followDomain)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
@ -864,7 +864,8 @@ def locatePost(baseDir: str, nickname: str, domain: str,
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def removeAttachment(baseDir: str, httpPrefix: str, domain: str, postJson: {}):
|
def _removeAttachment(baseDir: str, httpPrefix: str, domain: str,
|
||||||
|
postJson: {}):
|
||||||
if not postJson.get('attachment'):
|
if not postJson.get('attachment'):
|
||||||
return
|
return
|
||||||
if not postJson['attachment'][0].get('url'):
|
if not postJson['attachment'][0].get('url'):
|
||||||
|
|
@ -907,7 +908,7 @@ def removeModerationPostFromIndex(baseDir: str, postUrl: str,
|
||||||
' from moderation index')
|
' from moderation index')
|
||||||
|
|
||||||
|
|
||||||
def isReplyToBlogPost(baseDir: str, nickname: str, domain: str,
|
def _isReplyToBlogPost(baseDir: str, nickname: str, domain: str,
|
||||||
postJsonObject: str):
|
postJsonObject: str):
|
||||||
"""Is the given post a reply to a blog post?
|
"""Is the given post a reply to a blog post?
|
||||||
"""
|
"""
|
||||||
|
|
@ -947,7 +948,7 @@ def deletePost(baseDir: str, httpPrefix: str,
|
||||||
return
|
return
|
||||||
|
|
||||||
# don't remove replies to blog posts
|
# don't remove replies to blog posts
|
||||||
if isReplyToBlogPost(baseDir, nickname, domain,
|
if _isReplyToBlogPost(baseDir, nickname, domain,
|
||||||
postJsonObject):
|
postJsonObject):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -966,7 +967,7 @@ def deletePost(baseDir: str, httpPrefix: str,
|
||||||
del recentPostsCache['html'][postId]
|
del recentPostsCache['html'][postId]
|
||||||
|
|
||||||
# remove any attachment
|
# remove any attachment
|
||||||
removeAttachment(baseDir, httpPrefix, domain, postJsonObject)
|
_removeAttachment(baseDir, httpPrefix, domain, postJsonObject)
|
||||||
|
|
||||||
extensions = ('votes', 'arrived', 'muted')
|
extensions = ('votes', 'arrived', 'muted')
|
||||||
for ext in extensions:
|
for ext in extensions:
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ def htmlCalendarDeleteConfirm(cssCache: {}, translate: {}, baseDir: str,
|
||||||
return deletePostStr
|
return deletePostStr
|
||||||
|
|
||||||
|
|
||||||
def htmlCalendarDay(cssCache: {}, translate: {},
|
def _htmlCalendarDay(cssCache: {}, translate: {},
|
||||||
baseDir: str, path: str,
|
baseDir: str, path: str,
|
||||||
year: int, monthNumber: int, dayNumber: int,
|
year: int, monthNumber: int, dayNumber: int,
|
||||||
nickname: str, domain: str, dayEvents: [],
|
nickname: str, domain: str, dayEvents: [],
|
||||||
|
|
@ -251,7 +251,7 @@ def htmlCalendar(cssCache: {}, translate: {},
|
||||||
if events:
|
if events:
|
||||||
if events.get(str(dayNumber)):
|
if events.get(str(dayNumber)):
|
||||||
dayEvents = events[str(dayNumber)]
|
dayEvents = events[str(dayNumber)]
|
||||||
return htmlCalendarDay(cssCache, translate, baseDir, path,
|
return _htmlCalendarDay(cssCache, translate, baseDir, path,
|
||||||
year, monthNumber, dayNumber,
|
year, monthNumber, dayNumber,
|
||||||
nickname, domain, dayEvents,
|
nickname, domain, dayEvents,
|
||||||
monthName, actor)
|
monthName, actor)
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@ from webapp_utils import htmlFooter
|
||||||
from webapp_utils import getBannerFile
|
from webapp_utils import getBannerFile
|
||||||
|
|
||||||
|
|
||||||
def linksExist(baseDir: str) -> bool:
|
def _linksExist(baseDir: str) -> bool:
|
||||||
"""Returns true if links have been created
|
"""Returns true if links have been created
|
||||||
"""
|
"""
|
||||||
linksFilename = baseDir + '/accounts/links.txt'
|
linksFilename = baseDir + '/accounts/links.txt'
|
||||||
return os.path.isfile(linksFilename)
|
return os.path.isfile(linksFilename)
|
||||||
|
|
||||||
|
|
||||||
def getLeftColumnShares(baseDir: str,
|
def _getLeftColumnShares(baseDir: str,
|
||||||
httpPrefix: str, domainFull: str,
|
httpPrefix: str, domainFull: str,
|
||||||
nickname: str,
|
nickname: str,
|
||||||
maxSharesInLeftColumn: int,
|
maxSharesInLeftColumn: int,
|
||||||
|
|
@ -164,7 +164,7 @@ def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
|
||||||
# show a number of shares
|
# show a number of shares
|
||||||
maxSharesInLeftColumn = 3
|
maxSharesInLeftColumn = 3
|
||||||
sharesList = \
|
sharesList = \
|
||||||
getLeftColumnShares(baseDir,
|
_getLeftColumnShares(baseDir,
|
||||||
httpPrefix, domainFull, nickname,
|
httpPrefix, domainFull, nickname,
|
||||||
maxSharesInLeftColumn, translate)
|
maxSharesInLeftColumn, translate)
|
||||||
if linksList and sharesList:
|
if linksList and sharesList:
|
||||||
|
|
@ -271,7 +271,7 @@ def htmlLinksMobile(cssCache: {}, baseDir: str,
|
||||||
headerButtonsFrontScreen(translate, nickname,
|
headerButtonsFrontScreen(translate, nickname,
|
||||||
'links', authorized,
|
'links', authorized,
|
||||||
iconsAsButtons) + '</center>'
|
iconsAsButtons) + '</center>'
|
||||||
if linksExist(baseDir):
|
if _linksExist(baseDir):
|
||||||
htmlStr += \
|
htmlStr += \
|
||||||
getLeftColumnContent(baseDir, nickname, domainFull,
|
getLeftColumnContent(baseDir, nickname, domainFull,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ from webapp_utils import htmlPostSeparator
|
||||||
from webapp_utils import headerButtonsFrontScreen
|
from webapp_utils import headerButtonsFrontScreen
|
||||||
|
|
||||||
|
|
||||||
def votesIndicator(totalVotes: int, positiveVoting: bool) -> str:
|
def _votesIndicator(totalVotes: int, positiveVoting: bool) -> str:
|
||||||
"""Returns an indicator of the number of votes on a newswire item
|
"""Returns an indicator of the number of votes on a newswire item
|
||||||
"""
|
"""
|
||||||
if totalVotes <= 0:
|
if totalVotes <= 0:
|
||||||
|
|
@ -177,7 +177,7 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
|
||||||
|
|
||||||
# show the newswire lines
|
# show the newswire lines
|
||||||
newswireContentStr = \
|
newswireContentStr = \
|
||||||
htmlNewswire(baseDir, newswire, nickname, moderator, translate,
|
_htmlNewswire(baseDir, newswire, nickname, moderator, translate,
|
||||||
positiveVoting)
|
positiveVoting)
|
||||||
htmlStr += newswireContentStr
|
htmlStr += newswireContentStr
|
||||||
|
|
||||||
|
|
@ -187,7 +187,7 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
|
||||||
return htmlStr
|
return htmlStr
|
||||||
|
|
||||||
|
|
||||||
def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
||||||
translate: {}, positiveVoting: bool) -> str:
|
translate: {}, positiveVoting: bool) -> str:
|
||||||
"""Converts a newswire dict into html
|
"""Converts a newswire dict into html
|
||||||
"""
|
"""
|
||||||
|
|
@ -220,7 +220,7 @@ def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
||||||
if moderator:
|
if moderator:
|
||||||
totalVotes = votesOnNewswireItem(item[2])
|
totalVotes = votesOnNewswireItem(item[2])
|
||||||
totalVotesStr = \
|
totalVotesStr = \
|
||||||
votesIndicator(totalVotes, positiveVoting)
|
_votesIndicator(totalVotes, positiveVoting)
|
||||||
|
|
||||||
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
||||||
htmlStr += '<p class="newswireItemVotedOn">' + \
|
htmlStr += '<p class="newswireItemVotedOn">' + \
|
||||||
|
|
@ -247,7 +247,7 @@ def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
||||||
# show a number of ticks or crosses for how many
|
# show a number of ticks or crosses for how many
|
||||||
# votes for or against
|
# votes for or against
|
||||||
totalVotesStr = \
|
totalVotesStr = \
|
||||||
votesIndicator(totalVotes, positiveVoting)
|
_votesIndicator(totalVotes, positiveVoting)
|
||||||
|
|
||||||
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
||||||
if moderator and moderatedItem:
|
if moderator and moderatedItem:
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ from webapp_utils import htmlHeaderWithExternalStyle
|
||||||
from webapp_utils import htmlFooter
|
from webapp_utils import htmlFooter
|
||||||
|
|
||||||
|
|
||||||
def htmlFollowingDataList(baseDir: str, nickname: str,
|
def _htmlFollowingDataList(baseDir: str, nickname: str,
|
||||||
domain: str, domainFull: str) -> str:
|
domain: str, domainFull: str) -> str:
|
||||||
"""Returns a datalist of handles being followed
|
"""Returns a datalist of handles being followed
|
||||||
"""
|
"""
|
||||||
|
|
@ -57,7 +57,7 @@ def htmlFollowingDataList(baseDir: str, nickname: str,
|
||||||
return listStr
|
return listStr
|
||||||
|
|
||||||
|
|
||||||
def htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
|
def _htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
|
||||||
replyStr: str,
|
replyStr: str,
|
||||||
translate: {},
|
translate: {},
|
||||||
showPublicOnDropdown: bool,
|
showPublicOnDropdown: bool,
|
||||||
|
|
@ -617,7 +617,7 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
|
||||||
dropDownContent = ''
|
dropDownContent = ''
|
||||||
if not reportUrl and not shareDescription:
|
if not reportUrl and not shareDescription:
|
||||||
dropDownContent = \
|
dropDownContent = \
|
||||||
htmlNewPostDropDown(scopeIcon, scopeDescription,
|
_htmlNewPostDropDown(scopeIcon, scopeDescription,
|
||||||
replyStr,
|
replyStr,
|
||||||
translate,
|
translate,
|
||||||
showPublicOnDropdown,
|
showPublicOnDropdown,
|
||||||
|
|
@ -717,7 +717,7 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
|
||||||
' <input type="text" name="mentions" ' + \
|
' <input type="text" name="mentions" ' + \
|
||||||
'list="followingHandles" value="' + mentionsStr + '" selected>\n'
|
'list="followingHandles" value="' + mentionsStr + '" selected>\n'
|
||||||
newPostForm += \
|
newPostForm += \
|
||||||
htmlFollowingDataList(baseDir, nickname, domain, domainFull)
|
_htmlFollowingDataList(baseDir, nickname, domain, domainFull)
|
||||||
newPostForm += ''
|
newPostForm += ''
|
||||||
selectedStr = ''
|
selectedStr = ''
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ from webapp_column_right import getRightColumnContent
|
||||||
from webapp_post import individualPostAsHtml
|
from webapp_post import individualPostAsHtml
|
||||||
|
|
||||||
|
|
||||||
def htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
translate: {},
|
translate: {},
|
||||||
baseDir: str, httpPrefix: str,
|
baseDir: str, httpPrefix: str,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
|
|
@ -139,7 +139,7 @@ def htmlFrontScreen(rssIconAtTop: bool,
|
||||||
bannerFile, bannerFilename = \
|
bannerFile, bannerFilename = \
|
||||||
getBannerFile(baseDir, nickname, domain, theme)
|
getBannerFile(baseDir, nickname, domain, theme)
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlFrontScreenPosts(recentPostsCache, maxRecentPosts,
|
_htmlFrontScreenPosts(recentPostsCache, maxRecentPosts,
|
||||||
translate,
|
translate,
|
||||||
baseDir, httpPrefix,
|
baseDir, httpPrefix,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ def getHashtagCategoriesFeed(baseDir: str,
|
||||||
return rssStr
|
return rssStr
|
||||||
|
|
||||||
|
|
||||||
def getHashtagDomainMax(domainHistogram: {}) -> str:
|
def _getHashtagDomainMax(domainHistogram: {}) -> str:
|
||||||
"""Returns the domain with the maximum number of hashtags
|
"""Returns the domain with the maximum number of hashtags
|
||||||
"""
|
"""
|
||||||
maxCount = 1
|
maxCount = 1
|
||||||
|
|
@ -63,7 +63,7 @@ def getHashtagDomainMax(domainHistogram: {}) -> str:
|
||||||
return maxDomain
|
return maxDomain
|
||||||
|
|
||||||
|
|
||||||
def getHashtagDomainHistogram(domainHistogram: {}, translate: {}) -> str:
|
def _getHashtagDomainHistogram(domainHistogram: {}, translate: {}) -> str:
|
||||||
"""Returns the html for a histogram of domains
|
"""Returns the html for a histogram of domains
|
||||||
from which hashtags are coming
|
from which hashtags are coming
|
||||||
"""
|
"""
|
||||||
|
|
@ -88,7 +88,7 @@ def getHashtagDomainHistogram(domainHistogram: {}, translate: {}) -> str:
|
||||||
rightColStr = ''
|
rightColStr = ''
|
||||||
|
|
||||||
for i in range(len(domainHistogram)):
|
for i in range(len(domainHistogram)):
|
||||||
domain = getHashtagDomainMax(domainHistogram)
|
domain = _getHashtagDomainMax(domainHistogram)
|
||||||
if not domain:
|
if not domain:
|
||||||
break
|
break
|
||||||
percent = int(domainHistogram[domain] * 100 / totalCount)
|
percent = int(domainHistogram[domain] * 100 / totalCount)
|
||||||
|
|
@ -224,7 +224,7 @@ def htmlHashTagSwarm(baseDir: str, actor: str, translate: {}) -> str:
|
||||||
getContentWarningButton('alltags', translate, tagSwarmStr)
|
getContentWarningButton('alltags', translate, tagSwarmStr)
|
||||||
|
|
||||||
tagSwarmHtml = categorySwarmStr + tagSwarmStr.strip() + '\n'
|
tagSwarmHtml = categorySwarmStr + tagSwarmStr.strip() + '\n'
|
||||||
# tagSwarmHtml += getHashtagDomainHistogram(domainHistogram, translate)
|
# tagSwarmHtml += _getHashtagDomainHistogram(domainHistogram, translate)
|
||||||
return tagSwarmHtml
|
return tagSwarmHtml
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ __email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
|
|
||||||
def addEmbeddedVideoFromSites(translate: {}, content: str,
|
def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
||||||
width=400, height=300) -> str:
|
width=400, height=300) -> str:
|
||||||
"""Adds embedded videos
|
"""Adds embedded videos
|
||||||
"""
|
"""
|
||||||
|
|
@ -122,7 +122,7 @@ def addEmbeddedVideoFromSites(translate: {}, content: str,
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def addEmbeddedAudio(translate: {}, content: str) -> str:
|
def _addEmbeddedAudio(translate: {}, content: str) -> str:
|
||||||
"""Adds embedded audio for mp3/ogg
|
"""Adds embedded audio for mp3/ogg
|
||||||
"""
|
"""
|
||||||
if not ('.mp3' in content or '.ogg' in content):
|
if not ('.mp3' in content or '.ogg' in content):
|
||||||
|
|
@ -167,7 +167,7 @@ def addEmbeddedAudio(translate: {}, content: str) -> str:
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def addEmbeddedVideo(translate: {}, content: str,
|
def _addEmbeddedVideo(translate: {}, content: str,
|
||||||
width=400, height=300) -> str:
|
width=400, height=300) -> str:
|
||||||
"""Adds embedded video for mp4/webm/ogv
|
"""Adds embedded video for mp4/webm/ogv
|
||||||
"""
|
"""
|
||||||
|
|
@ -219,6 +219,6 @@ def addEmbeddedVideo(translate: {}, content: str,
|
||||||
def addEmbeddedElements(translate: {}, content: str) -> str:
|
def addEmbeddedElements(translate: {}, content: str) -> str:
|
||||||
"""Adds embedded elements for various media types
|
"""Adds embedded elements for various media types
|
||||||
"""
|
"""
|
||||||
content = addEmbeddedVideoFromSites(translate, content)
|
content = _addEmbeddedVideoFromSites(translate, content)
|
||||||
content = addEmbeddedAudio(translate, content)
|
content = _addEmbeddedAudio(translate, content)
|
||||||
return addEmbeddedVideo(translate, content)
|
return _addEmbeddedVideo(translate, content)
|
||||||
|
|
|
||||||
177
webapp_post.py
177
webapp_post.py
|
|
@ -63,7 +63,7 @@ from webapp_question import insertQuestion
|
||||||
from devices import E2EEdecryptMessageFromDevice
|
from devices import E2EEdecryptMessageFromDevice
|
||||||
|
|
||||||
|
|
||||||
def logPostTiming(enableTimingLog: bool, postStartTime, debugId: str) -> None:
|
def _logPostTiming(enableTimingLog: bool, postStartTime, debugId: str) -> None:
|
||||||
"""Create a log of timings for performance tuning
|
"""Create a log of timings for performance tuning
|
||||||
"""
|
"""
|
||||||
if not enableTimingLog:
|
if not enableTimingLog:
|
||||||
|
|
@ -92,7 +92,7 @@ def preparePostFromHtmlCache(postHtml: str, boxName: str,
|
||||||
return withPageNumber
|
return withPageNumber
|
||||||
|
|
||||||
|
|
||||||
def saveIndividualPostAsHtmlToCache(baseDir: str,
|
def _saveIndividualPostAsHtmlToCache(baseDir: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
postHtml: str) -> bool:
|
postHtml: str) -> bool:
|
||||||
|
|
@ -118,7 +118,7 @@ def saveIndividualPostAsHtmlToCache(baseDir: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def getPostFromRecentCache(session,
|
def _getPostFromRecentCache(session,
|
||||||
baseDir: str,
|
baseDir: str,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
|
|
@ -157,13 +157,13 @@ def getPostFromRecentCache(session,
|
||||||
getPersonAvatarUrl(baseDir, postActor, personCache,
|
getPersonAvatarUrl(baseDir, postActor, personCache,
|
||||||
allowDownloads)
|
allowDownloads)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '2.1')
|
_logPostTiming(enableTimingLog, postStartTime, '2.1')
|
||||||
|
|
||||||
updateAvatarImageCache(session, baseDir, httpPrefix,
|
updateAvatarImageCache(session, baseDir, httpPrefix,
|
||||||
postActor, avatarUrl, personCache,
|
postActor, avatarUrl, personCache,
|
||||||
allowDownloads)
|
allowDownloads)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '2.2')
|
_logPostTiming(enableTimingLog, postStartTime, '2.2')
|
||||||
|
|
||||||
postHtml = \
|
postHtml = \
|
||||||
loadIndividualPostAsHtmlFromCache(baseDir, nickname, domain,
|
loadIndividualPostAsHtmlFromCache(baseDir, nickname, domain,
|
||||||
|
|
@ -174,11 +174,11 @@ def getPostFromRecentCache(session,
|
||||||
postHtml = preparePostFromHtmlCache(postHtml, boxName, pageNumber)
|
postHtml = preparePostFromHtmlCache(postHtml, boxName, pageNumber)
|
||||||
updateRecentPostsCache(recentPostsCache, maxRecentPosts,
|
updateRecentPostsCache(recentPostsCache, maxRecentPosts,
|
||||||
postJsonObject, postHtml)
|
postJsonObject, postHtml)
|
||||||
logPostTiming(enableTimingLog, postStartTime, '3')
|
_logPostTiming(enableTimingLog, postStartTime, '3')
|
||||||
return postHtml
|
return postHtml
|
||||||
|
|
||||||
|
|
||||||
def getAvatarImageHtml(showAvatarOptions: bool,
|
def _getAvatarImageHtml(showAvatarOptions: bool,
|
||||||
nickname: str, domainFull: str,
|
nickname: str, domainFull: str,
|
||||||
avatarUrl: str, postActor: str,
|
avatarUrl: str, postActor: str,
|
||||||
translate: {}, avatarPosition: str,
|
translate: {}, avatarPosition: str,
|
||||||
|
|
@ -215,7 +215,7 @@ def getAvatarImageHtml(showAvatarOptions: bool,
|
||||||
return avatarLink.strip()
|
return avatarLink.strip()
|
||||||
|
|
||||||
|
|
||||||
def getReplyIconHtml(nickname: str, isPublicRepeat: bool,
|
def _getReplyIconHtml(nickname: str, isPublicRepeat: bool,
|
||||||
showIcons: bool, commentsEnabled: bool,
|
showIcons: bool, commentsEnabled: bool,
|
||||||
postJsonObject: {}, pageNumberParam: str,
|
postJsonObject: {}, pageNumberParam: str,
|
||||||
translate: {}) -> str:
|
translate: {}) -> str:
|
||||||
|
|
@ -274,7 +274,7 @@ def getReplyIconHtml(nickname: str, isPublicRepeat: bool,
|
||||||
return replyStr
|
return replyStr
|
||||||
|
|
||||||
|
|
||||||
def getEditIconHtml(baseDir: str, nickname: str, domainFull: str,
|
def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str,
|
||||||
postJsonObject: {}, actorNickname: str,
|
postJsonObject: {}, actorNickname: str,
|
||||||
translate: {}, isEvent: bool) -> str:
|
translate: {}, isEvent: bool) -> str:
|
||||||
"""Returns html for the edit icon/button
|
"""Returns html for the edit icon/button
|
||||||
|
|
@ -330,7 +330,7 @@ def getEditIconHtml(baseDir: str, nickname: str, domainFull: str,
|
||||||
return editStr
|
return editStr
|
||||||
|
|
||||||
|
|
||||||
def getAnnounceIconHtml(nickname: str, domainFull: str,
|
def _getAnnounceIconHtml(nickname: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
isPublicRepeat: bool,
|
isPublicRepeat: bool,
|
||||||
isModerationPost: bool,
|
isModerationPost: bool,
|
||||||
|
|
@ -372,7 +372,7 @@ def getAnnounceIconHtml(nickname: str, domainFull: str,
|
||||||
return announceStr
|
return announceStr
|
||||||
|
|
||||||
|
|
||||||
def getLikeIconHtml(nickname: str, domainFull: str,
|
def _getLikeIconHtml(nickname: str, domainFull: str,
|
||||||
isModerationPost: bool,
|
isModerationPost: bool,
|
||||||
showLikeButton: bool,
|
showLikeButton: bool,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
|
|
@ -390,7 +390,7 @@ def getLikeIconHtml(nickname: str, domainFull: str,
|
||||||
likeTitle = translate['Like this post']
|
likeTitle = translate['Like this post']
|
||||||
likeCount = noOfLikes(postJsonObject)
|
likeCount = noOfLikes(postJsonObject)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12.1')
|
_logPostTiming(enableTimingLog, postStartTime, '12.1')
|
||||||
|
|
||||||
likeCountStr = ''
|
likeCountStr = ''
|
||||||
if likeCount > 0:
|
if likeCount > 0:
|
||||||
|
|
@ -406,7 +406,7 @@ def getLikeIconHtml(nickname: str, domainFull: str,
|
||||||
likeLink = 'unlike'
|
likeLink = 'unlike'
|
||||||
likeTitle = translate['Undo the like']
|
likeTitle = translate['Undo the like']
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12.2')
|
_logPostTiming(enableTimingLog, postStartTime, '12.2')
|
||||||
|
|
||||||
likeStr = ''
|
likeStr = ''
|
||||||
if likeCountStr:
|
if likeCountStr:
|
||||||
|
|
@ -430,7 +430,7 @@ def getLikeIconHtml(nickname: str, domainFull: str,
|
||||||
return likeStr
|
return likeStr
|
||||||
|
|
||||||
|
|
||||||
def getBookmarkIconHtml(nickname: str, domainFull: str,
|
def _getBookmarkIconHtml(nickname: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
isModerationPost: bool,
|
isModerationPost: bool,
|
||||||
translate: {},
|
translate: {},
|
||||||
|
|
@ -452,7 +452,7 @@ def getBookmarkIconHtml(nickname: str, domainFull: str,
|
||||||
bookmarkIcon = 'bookmark.png'
|
bookmarkIcon = 'bookmark.png'
|
||||||
bookmarkLink = 'unbookmark'
|
bookmarkLink = 'unbookmark'
|
||||||
bookmarkTitle = translate['Undo the bookmark']
|
bookmarkTitle = translate['Undo the bookmark']
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12.6')
|
_logPostTiming(enableTimingLog, postStartTime, '12.6')
|
||||||
bookmarkStr = \
|
bookmarkStr = \
|
||||||
' <a class="imageAnchor" href="/users/' + nickname + '?' + \
|
' <a class="imageAnchor" href="/users/' + nickname + '?' + \
|
||||||
bookmarkLink + '=' + postJsonObject['object']['id'] + \
|
bookmarkLink + '=' + postJsonObject['object']['id'] + \
|
||||||
|
|
@ -468,7 +468,7 @@ def getBookmarkIconHtml(nickname: str, domainFull: str,
|
||||||
return bookmarkStr
|
return bookmarkStr
|
||||||
|
|
||||||
|
|
||||||
def getMuteIconHtml(isMuted: bool,
|
def _getMuteIconHtml(isMuted: bool,
|
||||||
postActor: str,
|
postActor: str,
|
||||||
messageId: str,
|
messageId: str,
|
||||||
nickname: str, domainFull: str,
|
nickname: str, domainFull: str,
|
||||||
|
|
@ -512,7 +512,7 @@ def getMuteIconHtml(isMuted: bool,
|
||||||
return muteStr
|
return muteStr
|
||||||
|
|
||||||
|
|
||||||
def getDeleteIconHtml(nickname: str, domainFull: str,
|
def _getDeleteIconHtml(nickname: str, domainFull: str,
|
||||||
allowDeletion: bool,
|
allowDeletion: bool,
|
||||||
postActor: str,
|
postActor: str,
|
||||||
messageId: str,
|
messageId: str,
|
||||||
|
|
@ -541,7 +541,7 @@ def getDeleteIconHtml(nickname: str, domainFull: str,
|
||||||
return deleteStr
|
return deleteStr
|
||||||
|
|
||||||
|
|
||||||
def getPublishedDateStr(postJsonObject: {},
|
def _getPublishedDateStr(postJsonObject: {},
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool) -> str:
|
||||||
"""Return the html for the published date on a post
|
"""Return the html for the published date on a post
|
||||||
"""
|
"""
|
||||||
|
|
@ -575,7 +575,7 @@ def getPublishedDateStr(postJsonObject: {},
|
||||||
return publishedStr
|
return publishedStr
|
||||||
|
|
||||||
|
|
||||||
def getBlogCitationsHtml(boxName: str,
|
def _getBlogCitationsHtml(boxName: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
translate: {}) -> str:
|
translate: {}) -> str:
|
||||||
"""Returns blog citations as html
|
"""Returns blog citations as html
|
||||||
|
|
@ -609,7 +609,7 @@ def getBlogCitationsHtml(boxName: str,
|
||||||
return citationsStr
|
return citationsStr
|
||||||
|
|
||||||
|
|
||||||
def boostOwnTootHtml(translate: {}) -> str:
|
def _boostOwnTootHtml(translate: {}) -> str:
|
||||||
"""The html title for announcing your own post
|
"""The html title for announcing your own post
|
||||||
"""
|
"""
|
||||||
return ' <img loading="lazy" title="' + \
|
return ' <img loading="lazy" title="' + \
|
||||||
|
|
@ -619,7 +619,7 @@ def boostOwnTootHtml(translate: {}) -> str:
|
||||||
'/repeat_inactive.png" class="announceOrReply"/>\n'
|
'/repeat_inactive.png" class="announceOrReply"/>\n'
|
||||||
|
|
||||||
|
|
||||||
def announceUnattributedHtml(translate: {},
|
def _announceUnattributedHtml(translate: {},
|
||||||
postJsonObject: {}) -> str:
|
postJsonObject: {}) -> str:
|
||||||
"""Returns the html for an announce title where there
|
"""Returns the html for an announce title where there
|
||||||
is no attribution on the announced post
|
is no attribution on the announced post
|
||||||
|
|
@ -634,7 +634,7 @@ def announceUnattributedHtml(translate: {},
|
||||||
'" class="announceOrReply">@unattributed</a>\n'
|
'" class="announceOrReply">@unattributed</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def announceWithoutDisplayNameHtml(translate: {},
|
def _announceWithoutDisplayNameHtml(translate: {},
|
||||||
announceNickname: str,
|
announceNickname: str,
|
||||||
announceDomain: str,
|
announceDomain: str,
|
||||||
postJsonObject: {}) -> str:
|
postJsonObject: {}) -> str:
|
||||||
|
|
@ -650,7 +650,7 @@ def announceWithoutDisplayNameHtml(translate: {},
|
||||||
announceNickname + '@' + announceDomain + '</a>\n'
|
announceNickname + '@' + announceDomain + '</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def announceWithDisplayNameHtml(translate: {},
|
def _announceWithDisplayNameHtml(translate: {},
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
announceDisplayName: str) -> str:
|
announceDisplayName: str) -> str:
|
||||||
"""Returns html for an announce having a display name
|
"""Returns html for an announce having a display name
|
||||||
|
|
@ -665,7 +665,7 @@ def announceWithDisplayNameHtml(translate: {},
|
||||||
'class="announceOrReply">' + announceDisplayName + '</a>\n'
|
'class="announceOrReply">' + announceDisplayName + '</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def getPostTitleAnnounceHtml(baseDir: str,
|
def _getPostTitleAnnounceHtml(baseDir: str,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
showRepeatIcon: bool,
|
showRepeatIcon: bool,
|
||||||
|
|
@ -695,10 +695,10 @@ def getPostTitleAnnounceHtml(baseDir: str,
|
||||||
attributedTo = postJsonObject['object']['attributedTo']
|
attributedTo = postJsonObject['object']['attributedTo']
|
||||||
|
|
||||||
if attributedTo.startswith(postActor):
|
if attributedTo.startswith(postActor):
|
||||||
titleStr += boostOwnTootHtml(translate)
|
titleStr += _boostOwnTootHtml(translate)
|
||||||
else:
|
else:
|
||||||
# boosting another person's post
|
# boosting another person's post
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.2')
|
_logPostTiming(enableTimingLog, postStartTime, '13.2')
|
||||||
announceNickname = None
|
announceNickname = None
|
||||||
if attributedTo:
|
if attributedTo:
|
||||||
announceNickname = getNicknameFromActor(attributedTo)
|
announceNickname = getNicknameFromActor(attributedTo)
|
||||||
|
|
@ -710,7 +710,7 @@ def getPostTitleAnnounceHtml(baseDir: str,
|
||||||
announceDisplayName = \
|
announceDisplayName = \
|
||||||
getDisplayName(baseDir, attributedTo, personCache)
|
getDisplayName(baseDir, attributedTo, personCache)
|
||||||
if announceDisplayName:
|
if announceDisplayName:
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.3')
|
_logPostTiming(enableTimingLog, postStartTime, '13.3')
|
||||||
|
|
||||||
# add any emoji to the display name
|
# add any emoji to the display name
|
||||||
if ':' in announceDisplayName:
|
if ':' in announceDisplayName:
|
||||||
|
|
@ -719,9 +719,9 @@ def getPostTitleAnnounceHtml(baseDir: str,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
announceDisplayName,
|
announceDisplayName,
|
||||||
False)
|
False)
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.3.1')
|
_logPostTiming(enableTimingLog, postStartTime, '13.3.1')
|
||||||
titleStr += \
|
titleStr += \
|
||||||
announceWithDisplayNameHtml(translate,
|
_announceWithDisplayNameHtml(translate,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
announceDisplayName)
|
announceDisplayName)
|
||||||
# show avatar of person replied to
|
# show avatar of person replied to
|
||||||
|
|
@ -731,7 +731,7 @@ def getPostTitleAnnounceHtml(baseDir: str,
|
||||||
getPersonAvatarUrl(baseDir, announceActor,
|
getPersonAvatarUrl(baseDir, announceActor,
|
||||||
personCache, allowDownloads)
|
personCache, allowDownloads)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.4')
|
_logPostTiming(enableTimingLog, postStartTime, '13.4')
|
||||||
|
|
||||||
if announceAvatarUrl:
|
if announceAvatarUrl:
|
||||||
idx = 'Show options for this person'
|
idx = 'Show options for this person'
|
||||||
|
|
@ -756,23 +756,23 @@ def getPostTitleAnnounceHtml(baseDir: str,
|
||||||
'/></a>\n </div>\n'
|
'/></a>\n </div>\n'
|
||||||
else:
|
else:
|
||||||
titleStr += \
|
titleStr += \
|
||||||
announceWithoutDisplayNameHtml(translate,
|
_announceWithoutDisplayNameHtml(translate,
|
||||||
announceNickname,
|
announceNickname,
|
||||||
announceDomain,
|
announceDomain,
|
||||||
postJsonObject)
|
postJsonObject)
|
||||||
else:
|
else:
|
||||||
titleStr += \
|
titleStr += \
|
||||||
announceUnattributedHtml(translate,
|
_announceUnattributedHtml(translate,
|
||||||
postJsonObject)
|
postJsonObject)
|
||||||
else:
|
else:
|
||||||
titleStr += \
|
titleStr += \
|
||||||
announceUnattributedHtml(translate, postJsonObject)
|
_announceUnattributedHtml(translate, postJsonObject)
|
||||||
|
|
||||||
return (titleStr, replyAvatarImageInPost,
|
return (titleStr, replyAvatarImageInPost,
|
||||||
containerClassIcons, containerClass)
|
containerClassIcons, containerClass)
|
||||||
|
|
||||||
|
|
||||||
def replyToYourselfHtml(translate: {}, ) -> str:
|
def _replyToYourselfHtml(translate: {}, ) -> str:
|
||||||
"""Returns html for a title which is a reply to yourself
|
"""Returns html for a title which is a reply to yourself
|
||||||
"""
|
"""
|
||||||
return ' <img loading="lazy" title="' + \
|
return ' <img loading="lazy" title="' + \
|
||||||
|
|
@ -782,7 +782,7 @@ def replyToYourselfHtml(translate: {}, ) -> str:
|
||||||
'/reply.png" class="announceOrReply"/>\n'
|
'/reply.png" class="announceOrReply"/>\n'
|
||||||
|
|
||||||
|
|
||||||
def replyToUnknownHtml(translate: {},
|
def _replyToUnknownHtml(translate: {},
|
||||||
postJsonObject: {}) -> str:
|
postJsonObject: {}) -> str:
|
||||||
"""Returns the html title for a reply to an unknown handle
|
"""Returns the html title for a reply to an unknown handle
|
||||||
"""
|
"""
|
||||||
|
|
@ -795,7 +795,7 @@ def replyToUnknownHtml(translate: {},
|
||||||
'" class="announceOrReply">@unknown</a>\n'
|
'" class="announceOrReply">@unknown</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def replyWithUnknownPathHtml(translate: {},
|
def _replyWithUnknownPathHtml(translate: {},
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
postDomain: str) -> str:
|
postDomain: str) -> str:
|
||||||
"""Returns html title for a reply with an unknown path
|
"""Returns html title for a reply with an unknown path
|
||||||
|
|
@ -812,7 +812,7 @@ def replyWithUnknownPathHtml(translate: {},
|
||||||
postDomain + '</a>\n'
|
postDomain + '</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def getReplyHtml(translate: {},
|
def _getReplyHtml(translate: {},
|
||||||
inReplyTo: str, replyDisplayName: str) -> str:
|
inReplyTo: str, replyDisplayName: str) -> str:
|
||||||
"""Returns html title for a reply
|
"""Returns html title for a reply
|
||||||
"""
|
"""
|
||||||
|
|
@ -827,7 +827,7 @@ def getReplyHtml(translate: {},
|
||||||
replyDisplayName + '</a>\n'
|
replyDisplayName + '</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def getReplyWithoutDisplayName(translate: {},
|
def _getReplyWithoutDisplayName(translate: {},
|
||||||
inReplyTo: str,
|
inReplyTo: str,
|
||||||
replyNickname: str, replyDomain: str) -> str:
|
replyNickname: str, replyDomain: str) -> str:
|
||||||
"""Returns html for a reply without a display name,
|
"""Returns html for a reply without a display name,
|
||||||
|
|
@ -842,7 +842,7 @@ def getReplyWithoutDisplayName(translate: {},
|
||||||
replyNickname + '@' + replyDomain + '</a>\n'
|
replyNickname + '@' + replyDomain + '</a>\n'
|
||||||
|
|
||||||
|
|
||||||
def getPostTitleReplyHtml(baseDir: str,
|
def _getPostTitleReplyHtml(baseDir: str,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
showRepeatIcon: bool,
|
showRepeatIcon: bool,
|
||||||
|
|
@ -873,7 +873,7 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
containerClassIcons = 'containericons darker'
|
containerClassIcons = 'containericons darker'
|
||||||
containerClass = 'container darker'
|
containerClass = 'container darker'
|
||||||
if postJsonObject['object']['inReplyTo'].startswith(postActor):
|
if postJsonObject['object']['inReplyTo'].startswith(postActor):
|
||||||
titleStr += replyToYourselfHtml(translate)
|
titleStr += _replyToYourselfHtml(translate)
|
||||||
return (titleStr, replyAvatarImageInPost,
|
return (titleStr, replyAvatarImageInPost,
|
||||||
containerClassIcons, containerClass)
|
containerClassIcons, containerClass)
|
||||||
|
|
||||||
|
|
@ -894,7 +894,7 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
if replyDisplayName:
|
if replyDisplayName:
|
||||||
# add emoji to the display name
|
# add emoji to the display name
|
||||||
if ':' in replyDisplayName:
|
if ':' in replyDisplayName:
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.5')
|
_logPostTiming(enableTimingLog, postStartTime, '13.5')
|
||||||
|
|
||||||
replyDisplayName = \
|
replyDisplayName = \
|
||||||
addEmojiToDisplayName(baseDir,
|
addEmojiToDisplayName(baseDir,
|
||||||
|
|
@ -903,12 +903,12 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
domain,
|
domain,
|
||||||
replyDisplayName,
|
replyDisplayName,
|
||||||
False)
|
False)
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.6')
|
_logPostTiming(enableTimingLog, postStartTime, '13.6')
|
||||||
|
|
||||||
titleStr += \
|
titleStr += \
|
||||||
getReplyHtml(translate, inReplyTo, replyDisplayName)
|
_getReplyHtml(translate, inReplyTo, replyDisplayName)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.7')
|
_logPostTiming(enableTimingLog, postStartTime, '13.7')
|
||||||
|
|
||||||
# show avatar of person replied to
|
# show avatar of person replied to
|
||||||
replyAvatarUrl = \
|
replyAvatarUrl = \
|
||||||
|
|
@ -917,7 +917,7 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
personCache,
|
personCache,
|
||||||
allowDownloads)
|
allowDownloads)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.8')
|
_logPostTiming(enableTimingLog, postStartTime, '13.8')
|
||||||
|
|
||||||
if replyAvatarUrl:
|
if replyAvatarUrl:
|
||||||
replyAvatarImageInPost = \
|
replyAvatarImageInPost = \
|
||||||
|
|
@ -947,12 +947,13 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
inReplyTo = \
|
inReplyTo = \
|
||||||
postJsonObject['object']['inReplyTo']
|
postJsonObject['object']['inReplyTo']
|
||||||
titleStr += \
|
titleStr += \
|
||||||
getReplyWithoutDisplayName(translate,
|
_getReplyWithoutDisplayName(translate,
|
||||||
inReplyTo,
|
inReplyTo,
|
||||||
replyNickname, replyDomain)
|
replyNickname,
|
||||||
|
replyDomain)
|
||||||
else:
|
else:
|
||||||
titleStr += \
|
titleStr += \
|
||||||
replyToUnknownHtml(translate, postJsonObject)
|
_replyToUnknownHtml(translate, postJsonObject)
|
||||||
else:
|
else:
|
||||||
postDomain = \
|
postDomain = \
|
||||||
postJsonObject['object']['inReplyTo']
|
postJsonObject['object']['inReplyTo']
|
||||||
|
|
@ -963,14 +964,14 @@ def getPostTitleReplyHtml(baseDir: str,
|
||||||
postDomain = postDomain.split('/', 1)[0]
|
postDomain = postDomain.split('/', 1)[0]
|
||||||
if postDomain:
|
if postDomain:
|
||||||
titleStr += \
|
titleStr += \
|
||||||
replyWithUnknownPathHtml(translate,
|
_replyWithUnknownPathHtml(translate,
|
||||||
postJsonObject, postDomain)
|
postJsonObject, postDomain)
|
||||||
|
|
||||||
return (titleStr, replyAvatarImageInPost,
|
return (titleStr, replyAvatarImageInPost,
|
||||||
containerClassIcons, containerClass)
|
containerClassIcons, containerClass)
|
||||||
|
|
||||||
|
|
||||||
def getPostTitleHtml(baseDir: str,
|
def _getPostTitleHtml(baseDir: str,
|
||||||
httpPrefix: str,
|
httpPrefix: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
showRepeatIcon: bool,
|
showRepeatIcon: bool,
|
||||||
|
|
@ -998,7 +999,7 @@ def getPostTitleHtml(baseDir: str,
|
||||||
containerClassIcons, containerClass)
|
containerClassIcons, containerClass)
|
||||||
|
|
||||||
if isAnnounced:
|
if isAnnounced:
|
||||||
return getPostTitleAnnounceHtml(baseDir,
|
return _getPostTitleAnnounceHtml(baseDir,
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
showRepeatIcon,
|
showRepeatIcon,
|
||||||
|
|
@ -1017,7 +1018,7 @@ def getPostTitleHtml(baseDir: str,
|
||||||
containerClassIcons,
|
containerClassIcons,
|
||||||
containerClass)
|
containerClass)
|
||||||
|
|
||||||
return getPostTitleReplyHtml(baseDir,
|
return _getPostTitleReplyHtml(baseDir,
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
showRepeatIcon,
|
showRepeatIcon,
|
||||||
|
|
@ -1037,7 +1038,7 @@ def getPostTitleHtml(baseDir: str,
|
||||||
containerClass)
|
containerClass)
|
||||||
|
|
||||||
|
|
||||||
def getFooterWithIcons(showIcons: bool,
|
def _getFooterWithIcons(showIcons: bool,
|
||||||
containerClassIcons: str,
|
containerClassIcons: str,
|
||||||
replyStr: str, announceStr: str,
|
replyStr: str, announceStr: str,
|
||||||
likeStr: str, bookmarkStr: str,
|
likeStr: str, bookmarkStr: str,
|
||||||
|
|
@ -1098,14 +1099,14 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
# accurate timing of different parts of the code
|
# accurate timing of different parts of the code
|
||||||
enableTimingLog = not allowDownloads
|
enableTimingLog = not allowDownloads
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '1')
|
_logPostTiming(enableTimingLog, postStartTime, '1')
|
||||||
|
|
||||||
avatarPosition = ''
|
avatarPosition = ''
|
||||||
messageId = ''
|
messageId = ''
|
||||||
if postJsonObject.get('id'):
|
if postJsonObject.get('id'):
|
||||||
messageId = removeIdEnding(postJsonObject['id'])
|
messageId = removeIdEnding(postJsonObject['id'])
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '2')
|
_logPostTiming(enableTimingLog, postStartTime, '2')
|
||||||
|
|
||||||
messageIdStr = ''
|
messageIdStr = ''
|
||||||
if messageId:
|
if messageId:
|
||||||
|
|
@ -1119,7 +1120,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
|
|
||||||
# get the html post from the recent posts cache if it exists there
|
# get the html post from the recent posts cache if it exists there
|
||||||
postHtml = \
|
postHtml = \
|
||||||
getPostFromRecentCache(session, baseDir,
|
_getPostFromRecentCache(session, baseDir,
|
||||||
httpPrefix, nickname, domain,
|
httpPrefix, nickname, domain,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
postActor,
|
postActor,
|
||||||
|
|
@ -1137,7 +1138,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
if postHtml:
|
if postHtml:
|
||||||
return postHtml
|
return postHtml
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '4')
|
_logPostTiming(enableTimingLog, postStartTime, '4')
|
||||||
|
|
||||||
avatarUrl = \
|
avatarUrl = \
|
||||||
getAvatarImageUrl(session,
|
getAvatarImageUrl(session,
|
||||||
|
|
@ -1145,7 +1146,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
postActor, personCache,
|
postActor, personCache,
|
||||||
avatarUrl, allowDownloads)
|
avatarUrl, allowDownloads)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '5')
|
_logPostTiming(enableTimingLog, postStartTime, '5')
|
||||||
|
|
||||||
# get the display name
|
# get the display name
|
||||||
if domainFull not in postActor:
|
if domainFull not in postActor:
|
||||||
|
|
@ -1156,7 +1157,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
projectVersion, httpPrefix,
|
projectVersion, httpPrefix,
|
||||||
nickname, domain, 'outbox',
|
nickname, domain, 'outbox',
|
||||||
72367)
|
72367)
|
||||||
logPostTiming(enableTimingLog, postStartTime, '6')
|
_logPostTiming(enableTimingLog, postStartTime, '6')
|
||||||
|
|
||||||
if avatarUrl2:
|
if avatarUrl2:
|
||||||
avatarUrl = avatarUrl2
|
avatarUrl = avatarUrl2
|
||||||
|
|
@ -1168,10 +1169,10 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
displayName, False)
|
displayName, False)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '7')
|
_logPostTiming(enableTimingLog, postStartTime, '7')
|
||||||
|
|
||||||
avatarLink = \
|
avatarLink = \
|
||||||
getAvatarImageHtml(showAvatarOptions,
|
_getAvatarImageHtml(showAvatarOptions,
|
||||||
nickname, domainFull,
|
nickname, domainFull,
|
||||||
avatarUrl, postActor,
|
avatarUrl, postActor,
|
||||||
translate, avatarPosition,
|
translate, avatarPosition,
|
||||||
|
|
@ -1215,7 +1216,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
postJsonObject = postJsonAnnounce
|
postJsonObject = postJsonAnnounce
|
||||||
isAnnounced = True
|
isAnnounced = True
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '8')
|
_logPostTiming(enableTimingLog, postStartTime, '8')
|
||||||
|
|
||||||
if not isinstance(postJsonObject['object'], dict):
|
if not isinstance(postJsonObject['object'], dict):
|
||||||
return ''
|
return ''
|
||||||
|
|
@ -1266,7 +1267,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
'">@' + actorNickname + '@' + actorDomain + '</a>\n'
|
'">@' + actorNickname + '@' + actorDomain + '</a>\n'
|
||||||
|
|
||||||
# benchmark 9
|
# benchmark 9
|
||||||
logPostTiming(enableTimingLog, postStartTime, '9')
|
_logPostTiming(enableTimingLog, postStartTime, '9')
|
||||||
|
|
||||||
# Show a DM icon for DMs in the inbox timeline
|
# Show a DM icon for DMs in the inbox timeline
|
||||||
if showDMicon:
|
if showDMicon:
|
||||||
|
|
@ -1280,23 +1281,23 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
if postJsonObject['object']['commentsEnabled'] is False:
|
if postJsonObject['object']['commentsEnabled'] is False:
|
||||||
commentsEnabled = False
|
commentsEnabled = False
|
||||||
|
|
||||||
replyStr = getReplyIconHtml(nickname, isPublicRepeat,
|
replyStr = _getReplyIconHtml(nickname, isPublicRepeat,
|
||||||
showIcons, commentsEnabled,
|
showIcons, commentsEnabled,
|
||||||
postJsonObject, pageNumberParam,
|
postJsonObject, pageNumberParam,
|
||||||
translate)
|
translate)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '10')
|
_logPostTiming(enableTimingLog, postStartTime, '10')
|
||||||
|
|
||||||
isEvent = isEventPost(postJsonObject)
|
isEvent = isEventPost(postJsonObject)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '11')
|
_logPostTiming(enableTimingLog, postStartTime, '11')
|
||||||
|
|
||||||
editStr = getEditIconHtml(baseDir, nickname, domainFull,
|
editStr = _getEditIconHtml(baseDir, nickname, domainFull,
|
||||||
postJsonObject, actorNickname,
|
postJsonObject, actorNickname,
|
||||||
translate, isEvent)
|
translate, isEvent)
|
||||||
|
|
||||||
announceStr = \
|
announceStr = \
|
||||||
getAnnounceIconHtml(nickname, domainFull,
|
_getAnnounceIconHtml(nickname, domainFull,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
isPublicRepeat,
|
isPublicRepeat,
|
||||||
isModerationPost,
|
isModerationPost,
|
||||||
|
|
@ -1306,7 +1307,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
timelinePostBookmark,
|
timelinePostBookmark,
|
||||||
boxName)
|
boxName)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12')
|
_logPostTiming(enableTimingLog, postStartTime, '12')
|
||||||
|
|
||||||
# whether to show a like button
|
# whether to show a like button
|
||||||
hideLikeButtonFile = \
|
hideLikeButtonFile = \
|
||||||
|
|
@ -1315,7 +1316,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
if os.path.isfile(hideLikeButtonFile):
|
if os.path.isfile(hideLikeButtonFile):
|
||||||
showLikeButton = False
|
showLikeButton = False
|
||||||
|
|
||||||
likeStr = getLikeIconHtml(nickname, domainFull,
|
likeStr = _getLikeIconHtml(nickname, domainFull,
|
||||||
isModerationPost,
|
isModerationPost,
|
||||||
showLikeButton,
|
showLikeButton,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
|
|
@ -1325,10 +1326,10 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
timelinePostBookmark,
|
timelinePostBookmark,
|
||||||
boxName)
|
boxName)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12.5')
|
_logPostTiming(enableTimingLog, postStartTime, '12.5')
|
||||||
|
|
||||||
bookmarkStr = \
|
bookmarkStr = \
|
||||||
getBookmarkIconHtml(nickname, domainFull,
|
_getBookmarkIconHtml(nickname, domainFull,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
isModerationPost,
|
isModerationPost,
|
||||||
translate,
|
translate,
|
||||||
|
|
@ -1337,14 +1338,14 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
pageNumberParam,
|
pageNumberParam,
|
||||||
timelinePostBookmark)
|
timelinePostBookmark)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '12.9')
|
_logPostTiming(enableTimingLog, postStartTime, '12.9')
|
||||||
|
|
||||||
isMuted = postIsMuted(baseDir, nickname, domain, postJsonObject, messageId)
|
isMuted = postIsMuted(baseDir, nickname, domain, postJsonObject, messageId)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13')
|
_logPostTiming(enableTimingLog, postStartTime, '13')
|
||||||
|
|
||||||
muteStr = \
|
muteStr = \
|
||||||
getMuteIconHtml(isMuted,
|
_getMuteIconHtml(isMuted,
|
||||||
postActor,
|
postActor,
|
||||||
messageId,
|
messageId,
|
||||||
nickname, domainFull,
|
nickname, domainFull,
|
||||||
|
|
@ -1355,7 +1356,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
translate)
|
translate)
|
||||||
|
|
||||||
deleteStr = \
|
deleteStr = \
|
||||||
getDeleteIconHtml(nickname, domainFull,
|
_getDeleteIconHtml(nickname, domainFull,
|
||||||
allowDeletion,
|
allowDeletion,
|
||||||
postActor,
|
postActor,
|
||||||
messageId,
|
messageId,
|
||||||
|
|
@ -1363,13 +1364,13 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
pageNumberParam,
|
pageNumberParam,
|
||||||
translate)
|
translate)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '13.1')
|
_logPostTiming(enableTimingLog, postStartTime, '13.1')
|
||||||
|
|
||||||
# get the title: x replies to y, x announces y, etc
|
# get the title: x replies to y, x announces y, etc
|
||||||
(titleStr2,
|
(titleStr2,
|
||||||
replyAvatarImageInPost,
|
replyAvatarImageInPost,
|
||||||
containerClassIcons,
|
containerClassIcons,
|
||||||
containerClass) = getPostTitleHtml(baseDir,
|
containerClass) = _getPostTitleHtml(baseDir,
|
||||||
httpPrefix,
|
httpPrefix,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
showRepeatIcon,
|
showRepeatIcon,
|
||||||
|
|
@ -1389,7 +1390,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
containerClass)
|
containerClass)
|
||||||
titleStr += titleStr2
|
titleStr += titleStr2
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '14')
|
_logPostTiming(enableTimingLog, postStartTime, '14')
|
||||||
|
|
||||||
attachmentStr, galleryStr = \
|
attachmentStr, galleryStr = \
|
||||||
getPostAttachmentsAsHtml(postJsonObject, boxName, translate,
|
getPostAttachmentsAsHtml(postJsonObject, boxName, translate,
|
||||||
|
|
@ -1398,9 +1399,9 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
bookmarkStr, deleteStr, muteStr)
|
bookmarkStr, deleteStr, muteStr)
|
||||||
|
|
||||||
publishedStr = \
|
publishedStr = \
|
||||||
getPublishedDateStr(postJsonObject, showPublishedDateOnly)
|
_getPublishedDateStr(postJsonObject, showPublishedDateOnly)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '15')
|
_logPostTiming(enableTimingLog, postStartTime, '15')
|
||||||
|
|
||||||
publishedLink = messageId
|
publishedLink = messageId
|
||||||
# blog posts should have no /statuses/ in their link
|
# blog posts should have no /statuses/ in their link
|
||||||
|
|
@ -1427,7 +1428,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
containerClassIcons = 'containericons dm'
|
containerClassIcons = 'containericons dm'
|
||||||
containerClass = 'container dm'
|
containerClass = 'container dm'
|
||||||
|
|
||||||
newFooterStr = getFooterWithIcons(showIcons,
|
newFooterStr = _getFooterWithIcons(showIcons,
|
||||||
containerClassIcons,
|
containerClassIcons,
|
||||||
replyStr, announceStr,
|
replyStr, announceStr,
|
||||||
likeStr, bookmarkStr,
|
likeStr, bookmarkStr,
|
||||||
|
|
@ -1466,7 +1467,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
postJsonObject['object']['summary'],
|
postJsonObject['object']['summary'],
|
||||||
postJsonObject['object']['content'])
|
postJsonObject['object']['content'])
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '16')
|
_logPostTiming(enableTimingLog, postStartTime, '16')
|
||||||
|
|
||||||
if not isPatch:
|
if not isPatch:
|
||||||
objectContent = \
|
objectContent = \
|
||||||
|
|
@ -1509,7 +1510,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
else:
|
else:
|
||||||
contentStr += cwContentStr
|
contentStr += cwContentStr
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '17')
|
_logPostTiming(enableTimingLog, postStartTime, '17')
|
||||||
|
|
||||||
if postJsonObject['object'].get('tag') and not isPatch:
|
if postJsonObject['object'].get('tag') and not isPatch:
|
||||||
contentStr = \
|
contentStr = \
|
||||||
|
|
@ -1531,7 +1532,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
|
|
||||||
# show blog citations
|
# show blog citations
|
||||||
citationsStr = \
|
citationsStr = \
|
||||||
getBlogCitationsHtml(boxName, postJsonObject, translate)
|
_getBlogCitationsHtml(boxName, postJsonObject, translate)
|
||||||
|
|
||||||
postHtml = ''
|
postHtml = ''
|
||||||
if boxName != 'tlmedia':
|
if boxName != 'tlmedia':
|
||||||
|
|
@ -1546,18 +1547,18 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
else:
|
else:
|
||||||
postHtml = galleryStr
|
postHtml = galleryStr
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '18')
|
_logPostTiming(enableTimingLog, postStartTime, '18')
|
||||||
|
|
||||||
# save the created html to the recent posts cache
|
# save the created html to the recent posts cache
|
||||||
if not showPublicOnly and storeToCache and \
|
if not showPublicOnly and storeToCache and \
|
||||||
boxName != 'tlmedia' and boxName != 'tlbookmarks' and \
|
boxName != 'tlmedia' and boxName != 'tlbookmarks' and \
|
||||||
boxName != 'bookmarks':
|
boxName != 'bookmarks':
|
||||||
saveIndividualPostAsHtmlToCache(baseDir, nickname, domain,
|
_saveIndividualPostAsHtmlToCache(baseDir, nickname, domain,
|
||||||
postJsonObject, postHtml)
|
postJsonObject, postHtml)
|
||||||
updateRecentPostsCache(recentPostsCache, maxRecentPosts,
|
updateRecentPostsCache(recentPostsCache, maxRecentPosts,
|
||||||
postJsonObject, postHtml)
|
postJsonObject, postHtml)
|
||||||
|
|
||||||
logPostTiming(enableTimingLog, postStartTime, '19')
|
_logPostTiming(enableTimingLog, postStartTime, '19')
|
||||||
|
|
||||||
return postHtml
|
return postHtml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
imageUrl = profileJson['image']['url']
|
imageUrl = profileJson['image']['url']
|
||||||
|
|
||||||
profileStr = \
|
profileStr = \
|
||||||
getProfileHeaderAfterSearch(baseDir,
|
_getProfileHeaderAfterSearch(baseDir,
|
||||||
nickname, defaultTimeline,
|
nickname, defaultTimeline,
|
||||||
searchNickname,
|
searchNickname,
|
||||||
searchDomainFull,
|
searchDomainFull,
|
||||||
|
|
@ -287,7 +287,7 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
return htmlHeaderWithExternalStyle(cssFilename) + profileStr + htmlFooter()
|
return htmlHeaderWithExternalStyle(cssFilename) + profileStr + htmlFooter()
|
||||||
|
|
||||||
|
|
||||||
def getProfileHeader(baseDir: str, nickname: str, domain: str,
|
def _getProfileHeader(baseDir: str, nickname: str, domain: str,
|
||||||
domainFull: str, translate: {},
|
domainFull: str, translate: {},
|
||||||
defaultTimeline: str,
|
defaultTimeline: str,
|
||||||
displayName: str,
|
displayName: str,
|
||||||
|
|
@ -327,7 +327,7 @@ def getProfileHeader(baseDir: str, nickname: str, domain: str,
|
||||||
return htmlStr
|
return htmlStr
|
||||||
|
|
||||||
|
|
||||||
def getProfileHeaderAfterSearch(baseDir: str,
|
def _getProfileHeaderAfterSearch(baseDir: str,
|
||||||
nickname: str, defaultTimeline: str,
|
nickname: str, defaultTimeline: str,
|
||||||
searchNickname: str,
|
searchNickname: str,
|
||||||
searchDomainFull: str,
|
searchDomainFull: str,
|
||||||
|
|
@ -568,7 +568,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
|
|
||||||
avatarUrl = profileJson['icon']['url']
|
avatarUrl = profileJson['icon']['url']
|
||||||
profileHeaderStr = \
|
profileHeaderStr = \
|
||||||
getProfileHeader(baseDir, nickname, domain,
|
_getProfileHeader(baseDir, nickname, domain,
|
||||||
domainFull, translate,
|
domainFull, translate,
|
||||||
defaultTimeline, displayName,
|
defaultTimeline, displayName,
|
||||||
avatarDescription,
|
avatarDescription,
|
||||||
|
|
@ -621,7 +621,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
|
|
||||||
if selected == 'posts':
|
if selected == 'posts':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfilePosts(recentPostsCache, maxRecentPosts,
|
_htmlProfilePosts(recentPostsCache, maxRecentPosts,
|
||||||
translate,
|
translate,
|
||||||
baseDir, httpPrefix, authorized,
|
baseDir, httpPrefix, authorized,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
|
|
@ -631,7 +631,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
showPublishedDateOnly) + licenseStr
|
showPublishedDateOnly) + licenseStr
|
||||||
elif selected == 'following':
|
elif selected == 'following':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfileFollowing(translate, baseDir, httpPrefix,
|
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
||||||
authorized, nickname,
|
authorized, nickname,
|
||||||
domain, port, session,
|
domain, port, session,
|
||||||
wfRequest, personCache, extraJson,
|
wfRequest, personCache, extraJson,
|
||||||
|
|
@ -640,7 +640,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
dormantMonths)
|
dormantMonths)
|
||||||
elif selected == 'followers':
|
elif selected == 'followers':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfileFollowing(translate, baseDir, httpPrefix,
|
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
||||||
authorized, nickname,
|
authorized, nickname,
|
||||||
domain, port, session,
|
domain, port, session,
|
||||||
wfRequest, personCache, extraJson,
|
wfRequest, personCache, extraJson,
|
||||||
|
|
@ -649,14 +649,14 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
maxItemsPerPage, dormantMonths)
|
maxItemsPerPage, dormantMonths)
|
||||||
elif selected == 'roles':
|
elif selected == 'roles':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfileRoles(translate, nickname, domainFull,
|
_htmlProfileRoles(translate, nickname, domainFull,
|
||||||
extraJson)
|
extraJson)
|
||||||
elif selected == 'skills':
|
elif selected == 'skills':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfileSkills(translate, nickname, domainFull, extraJson)
|
_htmlProfileSkills(translate, nickname, domainFull, extraJson)
|
||||||
elif selected == 'shares':
|
elif selected == 'shares':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
htmlProfileShares(actor, translate,
|
_htmlProfileShares(actor, translate,
|
||||||
nickname, domainFull,
|
nickname, domainFull,
|
||||||
extraJson) + licenseStr
|
extraJson) + licenseStr
|
||||||
|
|
||||||
|
|
@ -666,7 +666,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
def _htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
translate: {},
|
translate: {},
|
||||||
baseDir: str, httpPrefix: str,
|
baseDir: str, httpPrefix: str,
|
||||||
authorized: bool,
|
authorized: bool,
|
||||||
|
|
@ -720,7 +720,7 @@ def htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
|
def _htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
|
||||||
authorized: bool,
|
authorized: bool,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
session, wfRequest: {}, personCache: {},
|
session, wfRequest: {}, personCache: {},
|
||||||
|
|
@ -756,7 +756,7 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
|
||||||
dormantMonths)
|
dormantMonths)
|
||||||
|
|
||||||
profileStr += \
|
profileStr += \
|
||||||
individualFollowAsHtml(translate, baseDir, session,
|
_individualFollowAsHtml(translate, baseDir, session,
|
||||||
wfRequest, personCache,
|
wfRequest, personCache,
|
||||||
domain, followingActor,
|
domain, followingActor,
|
||||||
authorized, nickname,
|
authorized, nickname,
|
||||||
|
|
@ -778,7 +778,7 @@ def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlProfileRoles(translate: {}, nickname: str, domain: str,
|
def _htmlProfileRoles(translate: {}, nickname: str, domain: str,
|
||||||
rolesJson: {}) -> str:
|
rolesJson: {}) -> str:
|
||||||
"""Shows roles on the profile screen
|
"""Shows roles on the profile screen
|
||||||
"""
|
"""
|
||||||
|
|
@ -801,7 +801,7 @@ def htmlProfileRoles(translate: {}, nickname: str, domain: str,
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlProfileSkills(translate: {}, nickname: str, domain: str,
|
def _htmlProfileSkills(translate: {}, nickname: str, domain: str,
|
||||||
skillsJson: {}) -> str:
|
skillsJson: {}) -> str:
|
||||||
"""Shows skills on the profile screen
|
"""Shows skills on the profile screen
|
||||||
"""
|
"""
|
||||||
|
|
@ -817,7 +817,7 @@ def htmlProfileSkills(translate: {}, nickname: str, domain: str,
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlProfileShares(actor: str, translate: {},
|
def _htmlProfileShares(actor: str, translate: {},
|
||||||
nickname: str, domain: str, sharesJson: {}) -> str:
|
nickname: str, domain: str, sharesJson: {}) -> str:
|
||||||
"""Shows shares on the profile screen
|
"""Shows shares on the profile screen
|
||||||
"""
|
"""
|
||||||
|
|
@ -1450,7 +1450,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
return editProfileForm
|
return editProfileForm
|
||||||
|
|
||||||
|
|
||||||
def individualFollowAsHtml(translate: {},
|
def _individualFollowAsHtml(translate: {},
|
||||||
baseDir: str, session, wfRequest: {},
|
baseDir: str, session, wfRequest: {},
|
||||||
personCache: {}, domain: str,
|
personCache: {}, domain: str,
|
||||||
followUrl: str,
|
followUrl: str,
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ from webapp_headerbuttons import headerButtonsTimeline
|
||||||
from posts import isModerator
|
from posts import isModerator
|
||||||
|
|
||||||
|
|
||||||
def logTimelineTiming(enableTimingLog: bool, timelineStartTime,
|
def _logTimelineTiming(enableTimingLog: bool, timelineStartTime,
|
||||||
boxName: str, debugId: str) -> None:
|
boxName: str, debugId: str) -> None:
|
||||||
"""Create a log of timings for performance tuning
|
"""Create a log of timings for performance tuning
|
||||||
"""
|
"""
|
||||||
|
|
@ -127,7 +127,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
bannerFile, bannerFilename = \
|
bannerFile, bannerFilename = \
|
||||||
getBannerFile(baseDir, nickname, domain, theme)
|
getBannerFile(baseDir, nickname, domain, theme)
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '1')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '1')
|
||||||
|
|
||||||
# is the user a moderator?
|
# is the user a moderator?
|
||||||
if not moderator:
|
if not moderator:
|
||||||
|
|
@ -137,7 +137,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
if not editor:
|
if not editor:
|
||||||
editor = isEditor(baseDir, nickname)
|
editor = isEditor(baseDir, nickname)
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '2')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '2')
|
||||||
|
|
||||||
# the appearance of buttons - highlighted or not
|
# the appearance of buttons - highlighted or not
|
||||||
inboxButton = 'button'
|
inboxButton = 'button'
|
||||||
|
|
@ -221,7 +221,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
'" src="/icons/person.png"/></a>\n'
|
'" src="/icons/person.png"/></a>\n'
|
||||||
break
|
break
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '3')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '3')
|
||||||
|
|
||||||
# moderation / reports button
|
# moderation / reports button
|
||||||
moderationButtonStr = ''
|
moderationButtonStr = ''
|
||||||
|
|
@ -256,7 +256,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
||||||
tlStr = htmlHeaderWithExternalStyle(cssFilename)
|
tlStr = htmlHeaderWithExternalStyle(cssFilename)
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '4')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '4')
|
||||||
|
|
||||||
# if this is a news instance and we are viewing the news timeline
|
# if this is a news instance and we are viewing the news timeline
|
||||||
newsHeader = False
|
newsHeader = False
|
||||||
|
|
@ -487,17 +487,17 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
||||||
tlStr += '</div>\n</form>\n'
|
tlStr += '</div>\n</form>\n'
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '6')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '6')
|
||||||
|
|
||||||
if boxName == 'tlshares':
|
if boxName == 'tlshares':
|
||||||
maxSharesPerAccount = itemsPerPage
|
maxSharesPerAccount = itemsPerPage
|
||||||
return (tlStr +
|
return (tlStr +
|
||||||
htmlSharesTimeline(translate, pageNumber, itemsPerPage,
|
_htmlSharesTimeline(translate, pageNumber, itemsPerPage,
|
||||||
baseDir, actor, nickname, domain, port,
|
baseDir, actor, nickname, domain, port,
|
||||||
maxSharesPerAccount, httpPrefix) +
|
maxSharesPerAccount, httpPrefix) +
|
||||||
htmlFooter())
|
htmlFooter())
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '7')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '7')
|
||||||
|
|
||||||
# page up arrow
|
# page up arrow
|
||||||
if pageNumber > 1:
|
if pageNumber > 1:
|
||||||
|
|
@ -543,12 +543,12 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
preparePostFromHtmlCache(currTlStr,
|
preparePostFromHtmlCache(currTlStr,
|
||||||
boxName,
|
boxName,
|
||||||
pageNumber)
|
pageNumber)
|
||||||
logTimelineTiming(enableTimingLog,
|
_logTimelineTiming(enableTimingLog,
|
||||||
timelineStartTime,
|
timelineStartTime,
|
||||||
boxName, '10')
|
boxName, '10')
|
||||||
|
|
||||||
if not currTlStr:
|
if not currTlStr:
|
||||||
logTimelineTiming(enableTimingLog,
|
_logTimelineTiming(enableTimingLog,
|
||||||
timelineStartTime,
|
timelineStartTime,
|
||||||
boxName, '11')
|
boxName, '11')
|
||||||
|
|
||||||
|
|
@ -570,7 +570,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
manuallyApproveFollowers,
|
manuallyApproveFollowers,
|
||||||
False, True)
|
False, True)
|
||||||
logTimelineTiming(enableTimingLog,
|
_logTimelineTiming(enableTimingLog,
|
||||||
timelineStartTime, boxName, '12')
|
timelineStartTime, boxName, '12')
|
||||||
|
|
||||||
if currTlStr:
|
if currTlStr:
|
||||||
|
|
@ -612,7 +612,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
rightColumnStr + ' </td>\n'
|
rightColumnStr + ' </td>\n'
|
||||||
tlStr += ' </tr>\n'
|
tlStr += ' </tr>\n'
|
||||||
|
|
||||||
logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '9')
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '9')
|
||||||
|
|
||||||
tlStr += ' </tbody>\n'
|
tlStr += ' </tbody>\n'
|
||||||
tlStr += '</table>\n'
|
tlStr += '</table>\n'
|
||||||
|
|
@ -656,7 +656,7 @@ def htmlIndividualShare(actor: str, item: {}, translate: {},
|
||||||
return profileStr
|
return profileStr
|
||||||
|
|
||||||
|
|
||||||
def htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
|
def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
|
||||||
baseDir: str, actor: str,
|
baseDir: str, actor: str,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
maxSharesPerAccount: int, httpPrefix: str) -> str:
|
maxSharesPerAccount: int, httpPrefix: str) -> str:
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ def getContentWarningButton(postID: str, translate: {},
|
||||||
'</div></details>\n'
|
'</div></details>\n'
|
||||||
|
|
||||||
|
|
||||||
def getActorPropertyUrl(actorJson: {}, propertyName: str) -> str:
|
def _getActorPropertyUrl(actorJson: {}, propertyName: str) -> str:
|
||||||
"""Returns a url property from an actor
|
"""Returns a url property from an actor
|
||||||
"""
|
"""
|
||||||
if not actorJson.get('attachment'):
|
if not actorJson.get('attachment'):
|
||||||
|
|
@ -206,10 +206,10 @@ def getActorPropertyUrl(actorJson: {}, propertyName: str) -> str:
|
||||||
def getBlogAddress(actorJson: {}) -> str:
|
def getBlogAddress(actorJson: {}) -> str:
|
||||||
"""Returns blog address for the given actor
|
"""Returns blog address for the given actor
|
||||||
"""
|
"""
|
||||||
return getActorPropertyUrl(actorJson, 'Blog')
|
return _getActorPropertyUrl(actorJson, 'Blog')
|
||||||
|
|
||||||
|
|
||||||
def setActorPropertyUrl(actorJson: {}, propertyName: str, url: str) -> None:
|
def _setActorPropertyUrl(actorJson: {}, propertyName: str, url: str) -> None:
|
||||||
"""Sets a url for the given actor property
|
"""Sets a url for the given actor property
|
||||||
"""
|
"""
|
||||||
if not actorJson.get('attachment'):
|
if not actorJson.get('attachment'):
|
||||||
|
|
@ -269,7 +269,7 @@ def setActorPropertyUrl(actorJson: {}, propertyName: str, url: str) -> None:
|
||||||
def setBlogAddress(actorJson: {}, blogAddress: str) -> None:
|
def setBlogAddress(actorJson: {}, blogAddress: str) -> None:
|
||||||
"""Sets an blog address for the given actor
|
"""Sets an blog address for the given actor
|
||||||
"""
|
"""
|
||||||
setActorPropertyUrl(actorJson, 'Blog', removeHtml(blogAddress))
|
_setActorPropertyUrl(actorJson, 'Blog', removeHtml(blogAddress))
|
||||||
|
|
||||||
|
|
||||||
def updateAvatarImageCache(session, baseDir: str, httpPrefix: str,
|
def updateAvatarImageCache(session, baseDir: str, httpPrefix: str,
|
||||||
|
|
@ -475,7 +475,7 @@ def postContainsPublic(postJsonObject: {}) -> bool:
|
||||||
return containsPublic
|
return containsPublic
|
||||||
|
|
||||||
|
|
||||||
def getImageFile(baseDir: str, name: str, directory: str,
|
def _getImageFile(baseDir: str, name: str, directory: str,
|
||||||
nickname: str, domain: str, theme: str) -> (str, str):
|
nickname: str, domain: str, theme: str) -> (str, str):
|
||||||
"""
|
"""
|
||||||
returns the filenames for an image with the given name
|
returns the filenames for an image with the given name
|
||||||
|
|
@ -495,28 +495,28 @@ def getImageFile(baseDir: str, name: str, directory: str,
|
||||||
|
|
||||||
def getBannerFile(baseDir: str,
|
def getBannerFile(baseDir: str,
|
||||||
nickname: str, domain: str, theme: str) -> (str, str):
|
nickname: str, domain: str, theme: str) -> (str, str):
|
||||||
return getImageFile(baseDir, 'banner',
|
return _getImageFile(baseDir, 'banner',
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain,
|
baseDir + '/accounts/' + nickname + '@' + domain,
|
||||||
nickname, domain, theme)
|
nickname, domain, theme)
|
||||||
|
|
||||||
|
|
||||||
def getSearchBannerFile(baseDir: str,
|
def getSearchBannerFile(baseDir: str,
|
||||||
nickname: str, domain: str, theme: str) -> (str, str):
|
nickname: str, domain: str, theme: str) -> (str, str):
|
||||||
return getImageFile(baseDir, 'search_banner',
|
return _getImageFile(baseDir, 'search_banner',
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain,
|
baseDir + '/accounts/' + nickname + '@' + domain,
|
||||||
nickname, domain, theme)
|
nickname, domain, theme)
|
||||||
|
|
||||||
|
|
||||||
def getLeftImageFile(baseDir: str,
|
def getLeftImageFile(baseDir: str,
|
||||||
nickname: str, domain: str, theme: str) -> (str, str):
|
nickname: str, domain: str, theme: str) -> (str, str):
|
||||||
return getImageFile(baseDir, 'left_col_image',
|
return _getImageFile(baseDir, 'left_col_image',
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain,
|
baseDir + '/accounts/' + nickname + '@' + domain,
|
||||||
nickname, domain, theme)
|
nickname, domain, theme)
|
||||||
|
|
||||||
|
|
||||||
def getRightImageFile(baseDir: str,
|
def getRightImageFile(baseDir: str,
|
||||||
nickname: str, domain: str, theme: str) -> (str, str):
|
nickname: str, domain: str, theme: str) -> (str, str):
|
||||||
return getImageFile(baseDir, 'right_col_image',
|
return _getImageFile(baseDir, 'right_col_image',
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain,
|
baseDir + '/accounts/' + nickname + '@' + domain,
|
||||||
nickname, domain, theme)
|
nickname, domain, theme)
|
||||||
|
|
||||||
|
|
|
||||||
12
webfinger.py
12
webfinger.py
|
|
@ -25,7 +25,7 @@ from utils import saveJson
|
||||||
from utils import getProtocolPrefixes
|
from utils import getProtocolPrefixes
|
||||||
|
|
||||||
|
|
||||||
def parseHandle(handle: str) -> (str, str):
|
def _parseHandle(handle: str) -> (str, str):
|
||||||
if '.' not in handle:
|
if '.' not in handle:
|
||||||
return None, None
|
return None, None
|
||||||
prefixes = getProtocolPrefixes()
|
prefixes = getProtocolPrefixes()
|
||||||
|
|
@ -54,7 +54,7 @@ def webfingerHandle(session, handle: str, httpPrefix: str,
|
||||||
print('WARN: No session specified for webfingerHandle')
|
print('WARN: No session specified for webfingerHandle')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
nickname, domain = parseHandle(handle)
|
nickname, domain = _parseHandle(handle)
|
||||||
if not nickname:
|
if not nickname:
|
||||||
return None
|
return None
|
||||||
wfDomain = domain
|
wfDomain = domain
|
||||||
|
|
@ -97,7 +97,7 @@ def webfingerHandle(session, handle: str, httpPrefix: str,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def generateMagicKey(publicKeyPem) -> str:
|
def _generateMagicKey(publicKeyPem) -> str:
|
||||||
"""See magic_key method in
|
"""See magic_key method in
|
||||||
https://github.com/tootsuite/mastodon/blob/
|
https://github.com/tootsuite/mastodon/blob/
|
||||||
707ddf7808f90e3ab042d7642d368c2ce8e95e6f/app/models/account.rb
|
707ddf7808f90e3ab042d7642d368c2ce8e95e6f/app/models/account.rb
|
||||||
|
|
@ -170,7 +170,7 @@ def createWebfingerEndpoint(nickname: str, domain: str, port: int,
|
||||||
"type": "application/activity+json"
|
"type": "application/activity+json"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"href": generateMagicKey(publicKeyPem),
|
"href": _generateMagicKey(publicKeyPem),
|
||||||
"rel": "magic-public-key"
|
"rel": "magic-public-key"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -271,7 +271,7 @@ def webfingerLookup(path: str, baseDir: str,
|
||||||
return wfJson
|
return wfJson
|
||||||
|
|
||||||
|
|
||||||
def webfingerUpdateFromProfile(wfJson: {}, actorJson: {}) -> bool:
|
def _webfingerUpdateFromProfile(wfJson: {}, actorJson: {}) -> bool:
|
||||||
"""Updates webfinger Email/blog/xmpp links from profile
|
"""Updates webfinger Email/blog/xmpp links from profile
|
||||||
Returns true if one or more tags has been changed
|
Returns true if one or more tags has been changed
|
||||||
"""
|
"""
|
||||||
|
|
@ -350,6 +350,6 @@ def webfingerUpdate(baseDir: str, nickname: str, domain: str,
|
||||||
if not actorJson:
|
if not actorJson:
|
||||||
return
|
return
|
||||||
|
|
||||||
if webfingerUpdateFromProfile(wfJson, actorJson):
|
if _webfingerUpdateFromProfile(wfJson, actorJson):
|
||||||
if saveJson(wfJson, filename):
|
if saveJson(wfJson, filename):
|
||||||
cachedWebfingers[handle] = wfJson
|
cachedWebfingers[handle] = wfJson
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue