mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main
commit
b754b13fd8
|
|
@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
from utils import getDomainFromActor
|
from utils import getDomainFromActor
|
||||||
|
|
@ -182,10 +183,7 @@ def receiveAcceptReject(session, baseDir: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' + messageJson['type'] + ' has no actor')
|
print('DEBUG: ' + messageJson['type'] + ' has no actor')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor in ' +
|
print('DEBUG: "users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'] + '. Assuming single user instance.')
|
messageJson['type'] + '. Assuming single user instance.')
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ __maintainer__ = "Bob Mottram"
|
||||||
__email__ = "bob@freedombone.net"
|
__email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import getStatusNumber
|
from utils import getStatusNumber
|
||||||
from utils import createOutboxDir
|
from utils import createOutboxDir
|
||||||
|
|
@ -143,10 +144,7 @@ def createAnnounce(session, baseDir: str, federationList: [],
|
||||||
announceNickname = None
|
announceNickname = None
|
||||||
announceDomain = None
|
announceDomain = None
|
||||||
announcePort = None
|
announcePort = None
|
||||||
if '/users/' in objectUrl or \
|
if hasUsersPath(objectUrl):
|
||||||
'/accounts/' in objectUrl or \
|
|
||||||
'/channel/' in objectUrl or \
|
|
||||||
'/profile/' in objectUrl:
|
|
||||||
announceNickname = getNicknameFromActor(objectUrl)
|
announceNickname = getNicknameFromActor(objectUrl)
|
||||||
announceDomain, announcePort = getDomainFromActor(objectUrl)
|
announceDomain, announcePort = getDomainFromActor(objectUrl)
|
||||||
|
|
||||||
|
|
|
||||||
6
auth.py
6
auth.py
|
|
@ -12,6 +12,7 @@ import binascii
|
||||||
import os
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
from utils import isSystemAccount
|
from utils import isSystemAccount
|
||||||
|
from utils import hasUsersPath
|
||||||
|
|
||||||
|
|
||||||
def _hashPassword(password: str) -> str:
|
def _hashPassword(password: str) -> str:
|
||||||
|
|
@ -89,10 +90,7 @@ def authorizeBasic(baseDir: str, path: str, authHeader: str,
|
||||||
print('DEBUG: basic auth - Authorixation header does not ' +
|
print('DEBUG: basic auth - Authorixation header does not ' +
|
||||||
'contain a space character')
|
'contain a space character')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in path and \
|
if not hasUsersPath(path):
|
||||||
'/accounts/' not in path and \
|
|
||||||
'/channel/' not in path and \
|
|
||||||
'/profile/' not in path:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: basic auth - ' +
|
print('DEBUG: basic auth - ' +
|
||||||
'path for Authorization does not contain a user')
|
'path for Authorization does not contain a user')
|
||||||
|
|
|
||||||
11
blocking.py
11
blocking.py
|
|
@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import removeIdEnding
|
from utils import removeIdEnding
|
||||||
from utils import isEvil
|
from utils import isEvil
|
||||||
|
|
@ -246,10 +247,7 @@ def outboxBlock(baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s block object is not a status')
|
print('DEBUG: c2s block object is not a status')
|
||||||
return
|
return
|
||||||
if '/users/' not in messageId and \
|
if not hasUsersPath(messageId):
|
||||||
'/accounts/' not in messageId and \
|
|
||||||
'/channel/' not in messageId and \
|
|
||||||
'/profile/' not in messageId:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s block object has no nickname')
|
print('DEBUG: c2s block object has no nickname')
|
||||||
return
|
return
|
||||||
|
|
@ -321,10 +319,7 @@ def outboxUndoBlock(baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s undo block object is not a status')
|
print('DEBUG: c2s undo block object is not a status')
|
||||||
return
|
return
|
||||||
if '/users/' not in messageId and \
|
if not hasUsersPath(messageId):
|
||||||
'/accounts/' not in messageId and \
|
|
||||||
'/channel/' not in messageId and \
|
|
||||||
'/profile/' not in messageId:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s undo block object has no nickname')
|
print('DEBUG: c2s undo block object has no nickname')
|
||||||
return
|
return
|
||||||
|
|
|
||||||
21
blog.py
21
blog.py
|
|
@ -158,6 +158,7 @@ def _htmlBlogPostContent(authorized: bool,
|
||||||
nickname: str, domain: str, domainFull: str,
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
handle: str, restrictToDomain: bool,
|
handle: str, restrictToDomain: bool,
|
||||||
|
peertubeInstances: [],
|
||||||
blogSeparator='<hr>') -> str:
|
blogSeparator='<hr>') -> str:
|
||||||
"""Returns the content for a single blog post
|
"""Returns the content for a single blog post
|
||||||
"""
|
"""
|
||||||
|
|
@ -231,7 +232,8 @@ def _htmlBlogPostContent(authorized: bool,
|
||||||
|
|
||||||
if postJsonObject['object'].get('content'):
|
if postJsonObject['object'].get('content'):
|
||||||
contentStr = addEmbeddedElements(translate,
|
contentStr = addEmbeddedElements(translate,
|
||||||
postJsonObject['object']['content'])
|
postJsonObject['object']['content'],
|
||||||
|
peertubeInstances)
|
||||||
if postJsonObject['object'].get('tag'):
|
if postJsonObject['object'].get('tag'):
|
||||||
contentStr = replaceEmojiFromTags(contentStr,
|
contentStr = replaceEmojiFromTags(contentStr,
|
||||||
postJsonObject['object']['tag'],
|
postJsonObject['object']['tag'],
|
||||||
|
|
@ -375,7 +377,8 @@ def _htmlBlogRemoveCwButton(blogStr: str, translate: {}) -> str:
|
||||||
def htmlBlogPost(authorized: bool,
|
def htmlBlogPost(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: {}) -> str:
|
postJsonObject: {},
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Returns a html blog post
|
"""Returns a html blog post
|
||||||
"""
|
"""
|
||||||
blogStr = ''
|
blogStr = ''
|
||||||
|
|
@ -390,7 +393,8 @@ def htmlBlogPost(authorized: bool,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, postJsonObject,
|
domainFull, postJsonObject,
|
||||||
None, False)
|
None, False,
|
||||||
|
peertubeInstances)
|
||||||
|
|
||||||
# show rss links
|
# show rss links
|
||||||
blogStr += '<p class="rssfeed">'
|
blogStr += '<p class="rssfeed">'
|
||||||
|
|
@ -417,7 +421,8 @@ def htmlBlogPost(authorized: bool,
|
||||||
def htmlBlogPage(authorized: bool, session,
|
def htmlBlogPage(authorized: bool, session,
|
||||||
baseDir: str, httpPrefix: str, translate: {},
|
baseDir: str, httpPrefix: str, translate: {},
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
noOfItems: int, pageNumber: int) -> str:
|
noOfItems: int, pageNumber: int,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Returns a html blog page containing posts
|
"""Returns a html blog page containing posts
|
||||||
"""
|
"""
|
||||||
if ' ' in nickname or '@' in nickname or \
|
if ' ' in nickname or '@' in nickname or \
|
||||||
|
|
@ -477,7 +482,8 @@ def htmlBlogPage(authorized: bool, session,
|
||||||
httpPrefix, translate,
|
httpPrefix, translate,
|
||||||
nickname, domain,
|
nickname, domain,
|
||||||
domainFull, item,
|
domainFull, item,
|
||||||
None, True)
|
None, True,
|
||||||
|
peertubeInstances)
|
||||||
|
|
||||||
if len(timelineJson['orderedItems']) >= noOfItems:
|
if len(timelineJson['orderedItems']) >= noOfItems:
|
||||||
blogStr += navigateStr
|
blogStr += navigateStr
|
||||||
|
|
@ -638,7 +644,8 @@ def _singleBlogAccountNickname(baseDir: str) -> str:
|
||||||
def htmlBlogView(authorized: bool,
|
def htmlBlogView(authorized: bool,
|
||||||
session, baseDir: str, httpPrefix: str,
|
session, baseDir: str, httpPrefix: str,
|
||||||
translate: {}, domain: str, port: int,
|
translate: {}, domain: str, port: int,
|
||||||
noOfItems: int) -> str:
|
noOfItems: int,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the blog main page
|
"""Show the blog main page
|
||||||
"""
|
"""
|
||||||
blogStr = ''
|
blogStr = ''
|
||||||
|
|
@ -654,7 +661,7 @@ def htmlBlogView(authorized: bool,
|
||||||
return htmlBlogPage(authorized, session,
|
return htmlBlogPage(authorized, session,
|
||||||
baseDir, httpPrefix, translate,
|
baseDir, httpPrefix, translate,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
noOfItems, 1)
|
noOfItems, 1, peertubeInstances)
|
||||||
|
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
|
|
||||||
|
|
|
||||||
11
bookmarks.py
11
bookmarks.py
|
|
@ -8,6 +8,7 @@ __status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import removeIdEnding
|
from utils import removeIdEnding
|
||||||
from utils import removePostFromCache
|
from utils import removePostFromCache
|
||||||
|
|
@ -255,10 +256,7 @@ def bookmark(recentPostsCache: {},
|
||||||
bookmarkedPostNickname = getNicknameFromActor(acBm)
|
bookmarkedPostNickname = getNicknameFromActor(acBm)
|
||||||
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm)
|
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm)
|
||||||
else:
|
else:
|
||||||
if '/users/' in objectUrl or \
|
if hasUsersPath(objectUrl):
|
||||||
'/accounts/' in objectUrl or \
|
|
||||||
'/channel/' in objectUrl or \
|
|
||||||
'/profile/' in objectUrl:
|
|
||||||
ou = objectUrl
|
ou = objectUrl
|
||||||
bookmarkedPostNickname = getNicknameFromActor(ou)
|
bookmarkedPostNickname = getNicknameFromActor(ou)
|
||||||
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou)
|
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou)
|
||||||
|
|
@ -322,10 +320,7 @@ def undoBookmark(recentPostsCache: {},
|
||||||
bookmarkedPostNickname = getNicknameFromActor(acBm)
|
bookmarkedPostNickname = getNicknameFromActor(acBm)
|
||||||
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm)
|
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(acBm)
|
||||||
else:
|
else:
|
||||||
if '/users/' in objectUrl or \
|
if hasUsersPath(objectUrl):
|
||||||
'/accounts/' in objectUrl or \
|
|
||||||
'/channel/' in objectUrl or \
|
|
||||||
'/profile/' in objectUrl:
|
|
||||||
ou = objectUrl
|
ou = objectUrl
|
||||||
bookmarkedPostNickname = getNicknameFromActor(ou)
|
bookmarkedPostNickname = getNicknameFromActor(ou)
|
||||||
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou)
|
bookmarkedPostDomain, bookmarkedPostPort = getDomainFromActor(ou)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
__filename__ = "briar.py"
|
||||||
|
__author__ = "Bob Mottram"
|
||||||
|
__license__ = "AGPL3+"
|
||||||
|
__version__ = "1.1.0"
|
||||||
|
__maintainer__ = "Bob Mottram"
|
||||||
|
__email__ = "bob@freedombone.net"
|
||||||
|
__status__ = "Production"
|
||||||
|
|
||||||
|
|
||||||
|
def getBriarAddress(actorJson: {}) -> str:
|
||||||
|
"""Returns briar address for the given actor
|
||||||
|
"""
|
||||||
|
if not actorJson.get('attachment'):
|
||||||
|
return ''
|
||||||
|
for propertyValue in actorJson['attachment']:
|
||||||
|
if not propertyValue.get('name'):
|
||||||
|
continue
|
||||||
|
if not propertyValue['name'].lower().startswith('briar'):
|
||||||
|
continue
|
||||||
|
if not propertyValue.get('type'):
|
||||||
|
continue
|
||||||
|
if not propertyValue.get('value'):
|
||||||
|
continue
|
||||||
|
if propertyValue['type'] != 'PropertyValue':
|
||||||
|
continue
|
||||||
|
propertyValue['value'] = propertyValue['value'].strip()
|
||||||
|
if len(propertyValue['value']) < 50:
|
||||||
|
continue
|
||||||
|
if not propertyValue['value'].startswith('briar://'):
|
||||||
|
continue
|
||||||
|
if propertyValue['value'].lower() != propertyValue['value']:
|
||||||
|
continue
|
||||||
|
if '"' in propertyValue['value']:
|
||||||
|
continue
|
||||||
|
if ' ' in propertyValue['value']:
|
||||||
|
continue
|
||||||
|
if ',' in propertyValue['value']:
|
||||||
|
continue
|
||||||
|
if '.' in propertyValue['value']:
|
||||||
|
continue
|
||||||
|
return propertyValue['value']
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def setBriarAddress(actorJson: {}, briarAddress: str) -> None:
|
||||||
|
"""Sets an briar address for the given actor
|
||||||
|
"""
|
||||||
|
notBriarAddress = False
|
||||||
|
|
||||||
|
if len(briarAddress) < 50:
|
||||||
|
notBriarAddress = True
|
||||||
|
if not briarAddress.startswith('briar://'):
|
||||||
|
notBriarAddress = True
|
||||||
|
if briarAddress.lower() != briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
if '"' in briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
if ' ' in briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
if '.' in briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
if ',' in briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
if '<' in briarAddress:
|
||||||
|
notBriarAddress = True
|
||||||
|
|
||||||
|
if not actorJson.get('attachment'):
|
||||||
|
actorJson['attachment'] = []
|
||||||
|
|
||||||
|
# remove any existing value
|
||||||
|
propertyFound = None
|
||||||
|
for propertyValue in actorJson['attachment']:
|
||||||
|
if not propertyValue.get('name'):
|
||||||
|
continue
|
||||||
|
if not propertyValue.get('type'):
|
||||||
|
continue
|
||||||
|
if not propertyValue['name'].lower().startswith('briar'):
|
||||||
|
continue
|
||||||
|
propertyFound = propertyValue
|
||||||
|
break
|
||||||
|
if propertyFound:
|
||||||
|
actorJson['attachment'].remove(propertyFound)
|
||||||
|
if notBriarAddress:
|
||||||
|
return
|
||||||
|
|
||||||
|
for propertyValue in actorJson['attachment']:
|
||||||
|
if not propertyValue.get('name'):
|
||||||
|
continue
|
||||||
|
if not propertyValue.get('type'):
|
||||||
|
continue
|
||||||
|
if not propertyValue['name'].lower().startswith('briar'):
|
||||||
|
continue
|
||||||
|
if propertyValue['type'] != 'PropertyValue':
|
||||||
|
continue
|
||||||
|
propertyValue['value'] = briarAddress
|
||||||
|
return
|
||||||
|
|
||||||
|
newBriarAddress = {
|
||||||
|
"name": "Briar",
|
||||||
|
"type": "PropertyValue",
|
||||||
|
"value": briarAddress
|
||||||
|
}
|
||||||
|
actorJson['attachment'].append(newBriarAddress)
|
||||||
|
|
@ -8,6 +8,7 @@ __status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import removeIdEnding
|
from utils import removeIdEnding
|
||||||
from utils import getNicknameFromActor
|
from utils import getNicknameFromActor
|
||||||
|
|
@ -139,10 +140,7 @@ def outboxDelete(baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s delete object is not a status')
|
print('DEBUG: c2s delete object is not a status')
|
||||||
return
|
return
|
||||||
if '/users/' not in messageId and \
|
if not hasUsersPath(messageId):
|
||||||
'/accounts/' not in messageId and \
|
|
||||||
'/channel/' not in messageId and \
|
|
||||||
'/profile/' not in messageId:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: c2s delete object has no nickname')
|
print('DEBUG: c2s delete object has no nickname')
|
||||||
return
|
return
|
||||||
|
|
|
||||||
11
epicyon.py
11
epicyon.py
|
|
@ -47,6 +47,7 @@ from tests import testClientToServer
|
||||||
from tests import runAllTests
|
from tests import runAllTests
|
||||||
from auth import storeBasicCredentials
|
from auth import storeBasicCredentials
|
||||||
from auth import createPassword
|
from auth import createPassword
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import setConfigParam
|
from utils import setConfigParam
|
||||||
from utils import getConfigParam
|
from utils import getConfigParam
|
||||||
|
|
@ -1318,10 +1319,7 @@ if args.actor:
|
||||||
for prefix in prefixes:
|
for prefix in prefixes:
|
||||||
args.actor = args.actor.replace(prefix, '')
|
args.actor = args.actor.replace(prefix, '')
|
||||||
args.actor = args.actor.replace('/@', '/users/')
|
args.actor = args.actor.replace('/@', '/users/')
|
||||||
if '/users/' not in args.actor and \
|
if not hasUsersPath(args.actor):
|
||||||
'/accounts/' not in args.actor and \
|
|
||||||
'/channel/' not in args.actor and \
|
|
||||||
'/profile/' not in args.actor:
|
|
||||||
print('Expected actor format: ' +
|
print('Expected actor format: ' +
|
||||||
'https://domain/@nick or https://domain/users/nick')
|
'https://domain/@nick or https://domain/users/nick')
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
@ -1391,10 +1389,7 @@ if args.actor:
|
||||||
personUrl = None
|
personUrl = None
|
||||||
if wfRequest.get('errors'):
|
if wfRequest.get('errors'):
|
||||||
print('wfRequest error: ' + str(wfRequest['errors']))
|
print('wfRequest error: ' + str(wfRequest['errors']))
|
||||||
if '/users/' in args.actor or \
|
if hasUsersPath(args.actor):
|
||||||
'/accounts/' in args.actor or \
|
|
||||||
'/profile/' in args.actor or \
|
|
||||||
'/channel/' in args.actor:
|
|
||||||
personUrl = originalActor
|
personUrl = originalActor
|
||||||
else:
|
else:
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
|
||||||
21
follow.py
21
follow.py
|
|
@ -8,6 +8,7 @@ __status__ = "Production"
|
||||||
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import os
|
import os
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import isSystemAccount
|
from utils import isSystemAccount
|
||||||
from utils import getFollowersList
|
from utils import getFollowersList
|
||||||
|
|
@ -316,10 +317,7 @@ def _getNoOfFollows(baseDir: str, nickname: str, domain: str,
|
||||||
ctr += 1
|
ctr += 1
|
||||||
elif ((line.startswith('http') or
|
elif ((line.startswith('http') or
|
||||||
line.startswith('dat')) and
|
line.startswith('dat')) and
|
||||||
('/users/' in line or
|
hasUsersPath(line)):
|
||||||
'/profile/' in line or
|
|
||||||
'/accounts/' in line or
|
|
||||||
'/channel/' in line)):
|
|
||||||
ctr += 1
|
ctr += 1
|
||||||
return ctr
|
return ctr
|
||||||
|
|
||||||
|
|
@ -438,10 +436,7 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str,
|
||||||
following['orderedItems'].append(url)
|
following['orderedItems'].append(url)
|
||||||
elif ((line.startswith('http') or
|
elif ((line.startswith('http') or
|
||||||
line.startswith('dat')) and
|
line.startswith('dat')) and
|
||||||
('/users/' in line or
|
hasUsersPath(line)):
|
||||||
'/profile/' in line or
|
|
||||||
'/accounts/' in line or
|
|
||||||
'/channel/' in line)):
|
|
||||||
# https://domain/users/nickname
|
# https://domain/users/nickname
|
||||||
pageCtr += 1
|
pageCtr += 1
|
||||||
totalCtr += 1
|
totalCtr += 1
|
||||||
|
|
@ -616,10 +611,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: follow request has no actor')
|
print('DEBUG: follow request has no actor')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: users/profile/accounts/channel missing from actor')
|
print('DEBUG: users/profile/accounts/channel missing from actor')
|
||||||
return False
|
return False
|
||||||
|
|
@ -641,10 +633,7 @@ def receiveFollowRequest(session, baseDir: str, httpPrefix: str,
|
||||||
'nickname. Assuming single user instance.')
|
'nickname. Assuming single user instance.')
|
||||||
if not messageJson.get('to'):
|
if not messageJson.get('to'):
|
||||||
messageJson['to'] = messageJson['object']
|
messageJson['to'] = messageJson['object']
|
||||||
if '/users/' not in messageJson['object'] and \
|
if not hasUsersPath(messageJson['object']):
|
||||||
'/accounts/' not in messageJson['object'] and \
|
|
||||||
'/channel/' not in messageJson['object'] and \
|
|
||||||
'/profile/' not in messageJson['object']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: users/profile/channel/accounts ' +
|
print('DEBUG: users/profile/channel/accounts ' +
|
||||||
'not found within object')
|
'not found within object')
|
||||||
|
|
|
||||||
98
inbox.py
98
inbox.py
|
|
@ -10,6 +10,7 @@ import json
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import validPostDate
|
from utils import validPostDate
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import isEventPost
|
from utils import isEventPost
|
||||||
|
|
@ -145,7 +146,8 @@ def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
postJsonObject: {},
|
postJsonObject: {},
|
||||||
allowDeletion: bool, boxname: str,
|
allowDeletion: bool, boxname: str,
|
||||||
showPublishedDateOnly: bool) -> None:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> None:
|
||||||
"""Converts the json post into html and stores it in a cache
|
"""Converts the json post into html and stores it in a cache
|
||||||
This enables the post to be quickly displayed later
|
This enables the post to be quickly displayed later
|
||||||
"""
|
"""
|
||||||
|
|
@ -170,6 +172,7 @@ def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
avatarUrl, True, allowDeletion,
|
avatarUrl, True, allowDeletion,
|
||||||
httpPrefix, __version__, boxname, None,
|
httpPrefix, __version__, boxname, None,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
not isDM(postJsonObject),
|
not isDM(postJsonObject),
|
||||||
True, True, False, True)
|
True, True, False, True)
|
||||||
|
|
||||||
|
|
@ -604,10 +607,7 @@ def _receiveUndoFollow(session, baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: follow request has no actor within object')
|
print('DEBUG: follow request has no actor within object')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['object']['actor'] and \
|
if not hasUsersPath(messageJson['object']['actor']):
|
||||||
'/accounts/' not in messageJson['object']['actor'] and \
|
|
||||||
'/channel/' not in messageJson['object']['actor'] and \
|
|
||||||
'/profile/' not in messageJson['object']['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing ' +
|
print('DEBUG: "users" or "profile" missing ' +
|
||||||
'from actor within object')
|
'from actor within object')
|
||||||
|
|
@ -668,10 +668,7 @@ def _receiveUndo(session, baseDir: str, httpPrefix: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: follow request has no actor')
|
print('DEBUG: follow request has no actor')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor')
|
print('DEBUG: "users" or "profile" missing from actor')
|
||||||
return False
|
return False
|
||||||
|
|
@ -735,19 +732,19 @@ def _personReceiveUpdate(baseDir: str,
|
||||||
' ' + str(personJson))
|
' ' + str(personJson))
|
||||||
domainFull = getFullDomain(domain, port)
|
domainFull = getFullDomain(domain, port)
|
||||||
updateDomainFull = getFullDomain(updateDomain, updatePort)
|
updateDomainFull = getFullDomain(updateDomain, updatePort)
|
||||||
actor = updateDomainFull + '/users/' + updateNickname
|
usersPaths = ('users', 'profile', 'channel', 'accounts')
|
||||||
if actor not in personJson['id']:
|
usersStrFound = False
|
||||||
actor = updateDomainFull + '/profile/' + updateNickname
|
for usersStr in usersPaths:
|
||||||
if actor not in personJson['id']:
|
actor = updateDomainFull + '/' + usersStr + '/' + updateNickname
|
||||||
actor = updateDomainFull + '/channel/' + updateNickname
|
if actor in personJson['id']:
|
||||||
if actor not in personJson['id']:
|
usersStrFound = True
|
||||||
actor = updateDomainFull + '/accounts/' + updateNickname
|
break
|
||||||
if actor not in personJson['id']:
|
if not usersStrFound:
|
||||||
if debug:
|
if debug:
|
||||||
print('actor: ' + actor)
|
print('actor: ' + actor)
|
||||||
print('id: ' + personJson['id'])
|
print('id: ' + personJson['id'])
|
||||||
print('DEBUG: Actor does not match id')
|
print('DEBUG: Actor does not match id')
|
||||||
return False
|
return False
|
||||||
if updateDomainFull == domainFull:
|
if updateDomainFull == domainFull:
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: You can only receive actor updates ' +
|
print('DEBUG: You can only receive actor updates ' +
|
||||||
|
|
@ -859,10 +856,7 @@ def _receiveUpdate(recentPostsCache: {}, session, baseDir: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' + messageJson['type'] + ' object has no type')
|
print('DEBUG: ' + messageJson['type'] + ' object has no type')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor in ' +
|
print('DEBUG: "users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'])
|
messageJson['type'])
|
||||||
|
|
@ -943,10 +937,7 @@ def _receiveLike(recentPostsCache: {},
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor in ' +
|
print('DEBUG: "users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'])
|
messageJson['type'])
|
||||||
|
|
@ -1014,10 +1005,7 @@ def _receiveUndoLike(recentPostsCache: {},
|
||||||
print('DEBUG: ' + messageJson['type'] +
|
print('DEBUG: ' + messageJson['type'] +
|
||||||
' like object is not a string')
|
' like object is not a string')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor in ' +
|
print('DEBUG: "users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'] + ' like')
|
messageJson['type'] + ' like')
|
||||||
|
|
@ -1219,10 +1207,7 @@ def _receiveDelete(session, handle: str, isGroup: bool, baseDir: str,
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' +
|
print('DEBUG: ' +
|
||||||
'"users" or "profile" missing from actor in ' +
|
'"users" or "profile" missing from actor in ' +
|
||||||
|
|
@ -1303,19 +1288,13 @@ def _receiveAnnounce(recentPostsCache: {},
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
print('DEBUG: ' + messageJson['type'] + ' has no "to" list')
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' +
|
print('DEBUG: ' +
|
||||||
'"users" or "profile" missing from actor in ' +
|
'"users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'])
|
messageJson['type'])
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['object'] and \
|
if not hasUsersPath(messageJson['object']):
|
||||||
'/accounts/' not in messageJson['object'] and \
|
|
||||||
'/channel/' not in messageJson['object'] and \
|
|
||||||
'/profile/' not in messageJson['object']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: ' +
|
print('DEBUG: ' +
|
||||||
'"users", "channel" or "profile" missing in ' +
|
'"users", "channel" or "profile" missing in ' +
|
||||||
|
|
@ -1387,10 +1366,7 @@ def _receiveAnnounce(recentPostsCache: {},
|
||||||
if isinstance(attrib, str):
|
if isinstance(attrib, str):
|
||||||
lookupActor = attrib
|
lookupActor = attrib
|
||||||
if lookupActor:
|
if lookupActor:
|
||||||
if '/users/' in lookupActor or \
|
if hasUsersPath(lookupActor):
|
||||||
'/accounts/' in lookupActor or \
|
|
||||||
'/channel/' in lookupActor or \
|
|
||||||
'/profile/' in lookupActor:
|
|
||||||
if '/statuses/' in lookupActor:
|
if '/statuses/' in lookupActor:
|
||||||
lookupActor = lookupActor.split('/statuses/')[0]
|
lookupActor = lookupActor.split('/statuses/')[0]
|
||||||
|
|
||||||
|
|
@ -1439,10 +1415,7 @@ def _receiveUndoAnnounce(recentPostsCache: {},
|
||||||
return False
|
return False
|
||||||
if messageJson['object']['type'] != 'Announce':
|
if messageJson['object']['type'] != 'Announce':
|
||||||
return False
|
return False
|
||||||
if '/users/' not in messageJson['actor'] and \
|
if not hasUsersPath(messageJson['actor']):
|
||||||
'/accounts/' not in messageJson['actor'] and \
|
|
||||||
'/channel/' not in messageJson['actor'] and \
|
|
||||||
'/profile/' not in messageJson['actor']:
|
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: "users" or "profile" missing from actor in ' +
|
print('DEBUG: "users" or "profile" missing from actor in ' +
|
||||||
messageJson['type'] + ' announce')
|
messageJson['type'] + ' announce')
|
||||||
|
|
@ -1688,10 +1661,7 @@ def _obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
|
||||||
if not isinstance(lookupActor, str):
|
if not isinstance(lookupActor, str):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not ('/users/' in lookupActor or
|
if not hasUsersPath(lookupActor):
|
||||||
'/accounts/' in lookupActor or
|
|
||||||
'/channel/' in lookupActor or
|
|
||||||
'/profile/' in lookupActor):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if '/statuses/' in lookupActor:
|
if '/statuses/' in lookupActor:
|
||||||
|
|
@ -2071,7 +2041,8 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
maxMentions: int, maxEmoji: int, translate: {},
|
maxMentions: int, maxEmoji: int, translate: {},
|
||||||
unitTest: bool, YTReplacementDomain: str,
|
unitTest: bool, YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
allowLocalNetworkAccess: bool) -> bool:
|
allowLocalNetworkAccess: bool,
|
||||||
|
peertubeInstances: []) -> bool:
|
||||||
""" Anything which needs to be done after initial checks have passed
|
""" Anything which needs to be done after initial checks have passed
|
||||||
"""
|
"""
|
||||||
actor = keyId
|
actor = keyId
|
||||||
|
|
@ -2378,7 +2349,8 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
postJsonObject,
|
postJsonObject,
|
||||||
allowDeletion,
|
allowDeletion,
|
||||||
boxname,
|
boxname,
|
||||||
showPublishedDateOnly)
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances)
|
||||||
if debug:
|
if debug:
|
||||||
timeDiff = \
|
timeDiff = \
|
||||||
str(int((time.time() - htmlCacheStartTime) *
|
str(int((time.time() - htmlCacheStartTime) *
|
||||||
|
|
@ -2478,7 +2450,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
allowNewsFollowers: bool,
|
allowNewsFollowers: bool,
|
||||||
maxFollowers: int, allowLocalNetworkAccess: bool) -> None:
|
maxFollowers: int, allowLocalNetworkAccess: bool,
|
||||||
|
peertubeInstances: []) -> None:
|
||||||
"""Processes received items and moves them to the appropriate
|
"""Processes received items and moves them to the appropriate
|
||||||
directories
|
directories
|
||||||
"""
|
"""
|
||||||
|
|
@ -2895,7 +2868,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
translate, unitTest,
|
translate, unitTest,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess,
|
||||||
|
peertubeInstances)
|
||||||
if debug:
|
if debug:
|
||||||
pprint(queueJson['post'])
|
pprint(queueJson['post'])
|
||||||
|
|
||||||
|
|
|
||||||
6
like.py
6
like.py
|
|
@ -6,6 +6,7 @@ __maintainer__ = "Bob Mottram"
|
||||||
__email__ = "bob@freedombone.net"
|
__email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import removeIdEnding
|
from utils import removeIdEnding
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
|
|
@ -87,10 +88,7 @@ def _like(recentPostsCache: {},
|
||||||
likedPostNickname = getNicknameFromActor(actorLiked)
|
likedPostNickname = getNicknameFromActor(actorLiked)
|
||||||
likedPostDomain, likedPostPort = getDomainFromActor(actorLiked)
|
likedPostDomain, likedPostPort = getDomainFromActor(actorLiked)
|
||||||
else:
|
else:
|
||||||
if '/users/' in objectUrl or \
|
if hasUsersPath(objectUrl):
|
||||||
'/accounts/' in objectUrl or \
|
|
||||||
'/channel/' in objectUrl or \
|
|
||||||
'/profile/' in objectUrl:
|
|
||||||
likedPostNickname = getNicknameFromActor(objectUrl)
|
likedPostNickname = getNicknameFromActor(objectUrl)
|
||||||
likedPostDomain, likedPostPort = getDomainFromActor(objectUrl)
|
likedPostDomain, likedPostPort = getDomainFromActor(objectUrl)
|
||||||
|
|
||||||
|
|
|
||||||
6
posts.py
6
posts.py
|
|
@ -30,6 +30,7 @@ from session import postJsonString
|
||||||
from session import postImage
|
from session import postImage
|
||||||
from webfinger import webfingerHandle
|
from webfinger import webfingerHandle
|
||||||
from httpsig import createSignedHeader
|
from httpsig import createSignedHeader
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import validPostDate
|
from utils import validPostDate
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import getFollowersList
|
from utils import getFollowersList
|
||||||
|
|
@ -155,10 +156,7 @@ def getUserUrl(wfRequest: {}, sourceId=0) -> str:
|
||||||
continue
|
continue
|
||||||
if link['type'] != 'application/activity+json':
|
if link['type'] != 'application/activity+json':
|
||||||
continue
|
continue
|
||||||
if not ('/users/' in link['href'] or
|
if not hasUsersPath(link['href']):
|
||||||
'/accounts/' in link['href'] or
|
|
||||||
'/profile/' in link['href'] or
|
|
||||||
'/channel/' in link['href']):
|
|
||||||
print('getUserUrl webfinger activity+json ' +
|
print('getUserUrl webfinger activity+json ' +
|
||||||
'contains single user instance actor ' +
|
'contains single user instance actor ' +
|
||||||
str(sourceId) + ' ' + str(link))
|
str(sourceId) + ' ' + str(link))
|
||||||
|
|
|
||||||
154
tests.py
154
tests.py
|
|
@ -854,7 +854,7 @@ def testFollowBetweenServers():
|
||||||
True, __version__, False)
|
True, __version__, False)
|
||||||
print('sendResult: ' + str(sendResult))
|
print('sendResult: ' + str(sendResult))
|
||||||
|
|
||||||
for t in range(10):
|
for t in range(16):
|
||||||
if os.path.isfile(bobDir + '/accounts/bob@' +
|
if os.path.isfile(bobDir + '/accounts/bob@' +
|
||||||
bobDomain + '/followers.txt'):
|
bobDomain + '/followers.txt'):
|
||||||
if os.path.isfile(aliceDir + '/accounts/alice@' +
|
if os.path.isfile(aliceDir + '/accounts/alice@' +
|
||||||
|
|
@ -2613,9 +2613,10 @@ def getFunctionCalls(name: str, lines: [], startLineCtr: int,
|
||||||
callsFunctions = []
|
callsFunctions = []
|
||||||
functionContentStr = ''
|
functionContentStr = ''
|
||||||
for lineCtr in range(startLineCtr + 1, len(lines)):
|
for lineCtr in range(startLineCtr + 1, len(lines)):
|
||||||
if lines[lineCtr].startswith('def '):
|
lineStr = lines[lineCtr].strip()
|
||||||
|
if lineStr.startswith('def '):
|
||||||
break
|
break
|
||||||
if lines[lineCtr].startswith('class '):
|
if lineStr.startswith('class '):
|
||||||
break
|
break
|
||||||
functionContentStr += lines[lineCtr]
|
functionContentStr += lines[lineCtr]
|
||||||
for funcName, properties in functionProperties.items():
|
for funcName, properties in functionProperties.items():
|
||||||
|
|
@ -2635,14 +2636,14 @@ def functionArgsMatch(callArgs: [], funcArgs: []):
|
||||||
for a in callArgs:
|
for a in callArgs:
|
||||||
if a == 'self':
|
if a == 'self':
|
||||||
continue
|
continue
|
||||||
if '=' not in a:
|
if '=' not in a or a.startswith("'"):
|
||||||
callArgsCtr += 1
|
callArgsCtr += 1
|
||||||
|
|
||||||
funcArgsCtr = 0
|
funcArgsCtr = 0
|
||||||
for a in funcArgs:
|
for a in funcArgs:
|
||||||
if a == 'self':
|
if a == 'self':
|
||||||
continue
|
continue
|
||||||
if '=' not in a:
|
if '=' not in a or a.startswith("'"):
|
||||||
funcArgsCtr += 1
|
funcArgsCtr += 1
|
||||||
|
|
||||||
return callArgsCtr >= funcArgsCtr
|
return callArgsCtr >= funcArgsCtr
|
||||||
|
|
@ -2670,7 +2671,7 @@ def testFunctions():
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
modules[modName]['lines'] = lines
|
modules[modName]['lines'] = lines
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if not line.startswith('def '):
|
if not line.strip().startswith('def '):
|
||||||
continue
|
continue
|
||||||
methodName = line.split('def ', 1)[1].split('(')[0]
|
methodName = line.split('def ', 1)[1].split('(')[0]
|
||||||
methodArgs = \
|
methodArgs = \
|
||||||
|
|
@ -2694,7 +2695,9 @@ def testFunctions():
|
||||||
'pyjsonld'
|
'pyjsonld'
|
||||||
]
|
]
|
||||||
excludeFuncs = [
|
excludeFuncs = [
|
||||||
'link'
|
'link',
|
||||||
|
'set',
|
||||||
|
'get'
|
||||||
]
|
]
|
||||||
# which modules is each function used within?
|
# which modules is each function used within?
|
||||||
for modName, modProperties in modules.items():
|
for modName, modProperties in modules.items():
|
||||||
|
|
@ -2702,7 +2705,11 @@ def testFunctions():
|
||||||
for name, properties in functionProperties.items():
|
for name, properties in functionProperties.items():
|
||||||
lineCtr = 0
|
lineCtr = 0
|
||||||
for line in modules[modName]['lines']:
|
for line in modules[modName]['lines']:
|
||||||
if line.startswith('def '):
|
lineStr = line.strip()
|
||||||
|
if lineStr.startswith('def '):
|
||||||
|
lineCtr += 1
|
||||||
|
continue
|
||||||
|
if lineStr.startswith('class '):
|
||||||
lineCtr += 1
|
lineCtr += 1
|
||||||
continue
|
continue
|
||||||
if name + '(' in line:
|
if name + '(' in line:
|
||||||
|
|
@ -2735,7 +2742,22 @@ def testFunctions():
|
||||||
|
|
||||||
# don't check these functions, because they are procedurally called
|
# don't check these functions, because they are procedurally called
|
||||||
exclusions = [
|
exclusions = [
|
||||||
|
'do_GET',
|
||||||
|
'do_POST',
|
||||||
|
'do_HEAD',
|
||||||
|
'__run',
|
||||||
|
'globaltrace',
|
||||||
|
'localtrace',
|
||||||
|
'kill',
|
||||||
|
'clone',
|
||||||
|
'unregister_rdf_parser',
|
||||||
'set_document_loader',
|
'set_document_loader',
|
||||||
|
'has_property',
|
||||||
|
'has_value',
|
||||||
|
'add_value',
|
||||||
|
'get_values',
|
||||||
|
'remove_property',
|
||||||
|
'remove_value',
|
||||||
'normalize',
|
'normalize',
|
||||||
'get_document_loader',
|
'get_document_loader',
|
||||||
'runInboxQueueWatchdog',
|
'runInboxQueueWatchdog',
|
||||||
|
|
@ -2764,17 +2786,26 @@ def testFunctions():
|
||||||
'setOrganizationScheme'
|
'setOrganizationScheme'
|
||||||
]
|
]
|
||||||
excludeImports = [
|
excludeImports = [
|
||||||
'link'
|
'link',
|
||||||
|
'start'
|
||||||
]
|
]
|
||||||
excludeLocal = [
|
excludeLocal = [
|
||||||
'pyjsonld',
|
'pyjsonld',
|
||||||
'daemon',
|
'daemon',
|
||||||
'tests'
|
'tests'
|
||||||
]
|
]
|
||||||
|
excludeMods = [
|
||||||
|
'pyjsonld'
|
||||||
|
]
|
||||||
# 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.startswith('__'):
|
||||||
|
if name.endswith('__'):
|
||||||
|
continue
|
||||||
if name in exclusions:
|
if name in exclusions:
|
||||||
continue
|
continue
|
||||||
|
if properties['module'] in excludeMods:
|
||||||
|
continue
|
||||||
isLocalFunction = False
|
isLocalFunction = False
|
||||||
if not properties['calledInModule']:
|
if not properties['calledInModule']:
|
||||||
print('function ' + name +
|
print('function ' + name +
|
||||||
|
|
@ -2815,18 +2846,80 @@ def testFunctions():
|
||||||
assert False
|
assert False
|
||||||
print('Function: ' + name + ' ✓')
|
print('Function: ' + name + ' ✓')
|
||||||
|
|
||||||
print('Constructing call graph')
|
print('Constructing function call graph')
|
||||||
|
moduleColors = ('red', 'green', 'yellow', 'orange', 'purple', 'cyan',
|
||||||
|
'darkgoldenrod3', 'darkolivegreen1', 'darkorange1',
|
||||||
|
'darkorchid1', 'darkseagreen', 'darkslategray4',
|
||||||
|
'deeppink1', 'deepskyblue1', 'dimgrey', 'gold1',
|
||||||
|
'goldenrod', 'burlywood2', 'bisque1', 'brown1',
|
||||||
|
'chartreuse2', 'cornsilk', 'darksalmon')
|
||||||
|
maxModuleCalls = 1
|
||||||
|
maxFunctionCalls = 1
|
||||||
|
colorCtr = 0
|
||||||
for modName, modProperties in modules.items():
|
for modName, modProperties in modules.items():
|
||||||
lineCtr = 0
|
lineCtr = 0
|
||||||
|
modules[modName]['color'] = moduleColors[colorCtr]
|
||||||
|
colorCtr += 1
|
||||||
|
if colorCtr >= len(moduleColors):
|
||||||
|
colorCtr = 0
|
||||||
for line in modules[modName]['lines']:
|
for line in modules[modName]['lines']:
|
||||||
if line.startswith('def '):
|
if line.strip().startswith('def '):
|
||||||
name = line.split('def ')[1].split('(')[0]
|
name = line.split('def ')[1].split('(')[0]
|
||||||
callsList = \
|
callsList = \
|
||||||
getFunctionCalls(name, modules[modName]['lines'],
|
getFunctionCalls(name, modules[modName]['lines'],
|
||||||
lineCtr, functionProperties)
|
lineCtr, functionProperties)
|
||||||
functionProperties[name]['calls'] = callsList.copy()
|
functionProperties[name]['calls'] = callsList.copy()
|
||||||
|
if len(callsList) > maxFunctionCalls:
|
||||||
|
maxFunctionCalls = len(callsList)
|
||||||
|
# keep track of which module calls which other module
|
||||||
|
for fn in callsList:
|
||||||
|
modCall = functionProperties[fn]['module']
|
||||||
|
if modCall != modName:
|
||||||
|
if modules[modName].get('calls'):
|
||||||
|
if modCall not in modules[modName]['calls']:
|
||||||
|
modules[modName]['calls'].append(modCall)
|
||||||
|
if len(modules[modName]['calls']) > \
|
||||||
|
maxModuleCalls:
|
||||||
|
maxModuleCalls = \
|
||||||
|
len(modules[modName]['calls'])
|
||||||
|
else:
|
||||||
|
modules[modName]['calls'] = [modCall]
|
||||||
lineCtr += 1
|
lineCtr += 1
|
||||||
|
callGraphStr = 'digraph EpicyonModules {\n\n'
|
||||||
|
callGraphStr += ' graph [fontsize=10 fontname="Verdana" compound=true];\n'
|
||||||
|
callGraphStr += ' node [shape=record fontsize=10 fontname="Verdana"];\n\n'
|
||||||
|
# colors of modules nodes
|
||||||
|
for modName, modProperties in modules.items():
|
||||||
|
if not modProperties.get('calls'):
|
||||||
|
callGraphStr += ' "' + modName + \
|
||||||
|
'" [fillcolor=yellow style=filled];\n'
|
||||||
|
continue
|
||||||
|
if len(modProperties['calls']) <= int(maxModuleCalls / 8):
|
||||||
|
callGraphStr += ' "' + modName + \
|
||||||
|
'" [fillcolor=green style=filled];\n'
|
||||||
|
elif len(modProperties['calls']) < int(maxModuleCalls / 4):
|
||||||
|
callGraphStr += ' "' + modName + \
|
||||||
|
'" [fillcolor=orange style=filled];\n'
|
||||||
|
else:
|
||||||
|
callGraphStr += ' "' + modName + \
|
||||||
|
'" [fillcolor=red style=filled];\n'
|
||||||
|
callGraphStr += '\n'
|
||||||
|
# connections between modules
|
||||||
|
for modName, modProperties in modules.items():
|
||||||
|
if not modProperties.get('calls'):
|
||||||
|
continue
|
||||||
|
for modCall in modProperties['calls']:
|
||||||
|
callGraphStr += ' "' + modName + '" -> "' + modCall + '";\n'
|
||||||
|
callGraphStr += '\n}\n'
|
||||||
|
with open('epicyon_modules.dot', 'w+') as fp:
|
||||||
|
fp.write(callGraphStr)
|
||||||
|
print('Modules call graph saved to epicyon_modules.dot')
|
||||||
|
print('Plot using: ' +
|
||||||
|
'sfdp -x -Goverlap=false -Goverlap_scaling=2 ' +
|
||||||
|
'-Gsep=+100 -Tx11 epicyon_modules.dot')
|
||||||
|
|
||||||
callGraphStr = 'digraph Epicyon {\n\n'
|
callGraphStr = 'digraph Epicyon {\n\n'
|
||||||
|
callGraphStr += ' size="8,6"; ratio=fill;\n'
|
||||||
callGraphStr += ' graph [fontsize=10 fontname="Verdana" compound=true];\n'
|
callGraphStr += ' graph [fontsize=10 fontname="Verdana" compound=true];\n'
|
||||||
callGraphStr += ' node [shape=record fontsize=10 fontname="Verdana"];\n\n'
|
callGraphStr += ' node [shape=record fontsize=10 fontname="Verdana"];\n\n'
|
||||||
|
|
||||||
|
|
@ -2834,25 +2927,52 @@ def testFunctions():
|
||||||
callGraphStr += ' subgraph cluster_' + modName + ' {\n'
|
callGraphStr += ' subgraph cluster_' + modName + ' {\n'
|
||||||
callGraphStr += ' label = "' + modName + '";\n'
|
callGraphStr += ' label = "' + modName + '";\n'
|
||||||
callGraphStr += ' node [style=filled];\n'
|
callGraphStr += ' node [style=filled];\n'
|
||||||
callGraphStr += ' '
|
moduleFunctionsStr = ''
|
||||||
for name in modProperties['functions']:
|
for name in modProperties['functions']:
|
||||||
callGraphStr += '"' + name + '" '
|
if name.startswith('test'):
|
||||||
callGraphStr += ';\n'
|
continue
|
||||||
|
if name not in excludeFuncs:
|
||||||
|
if not functionProperties[name]['calls']:
|
||||||
|
moduleFunctionsStr += \
|
||||||
|
' "' + name + '" [fillcolor=yellow style=filled];\n'
|
||||||
|
continue
|
||||||
|
noOfCalls = len(functionProperties[name]['calls'])
|
||||||
|
if noOfCalls < int(maxFunctionCalls / 4):
|
||||||
|
moduleFunctionsStr += ' "' + name + \
|
||||||
|
'" [fillcolor=orange style=filled];\n'
|
||||||
|
else:
|
||||||
|
moduleFunctionsStr += ' "' + name + \
|
||||||
|
'" [fillcolor=red style=filled];\n'
|
||||||
|
|
||||||
|
if moduleFunctionsStr:
|
||||||
|
callGraphStr += moduleFunctionsStr + '\n'
|
||||||
callGraphStr += ' color=blue;\n'
|
callGraphStr += ' color=blue;\n'
|
||||||
callGraphStr += ' }\n\n'
|
callGraphStr += ' }\n\n'
|
||||||
|
|
||||||
for name, properties in functionProperties.items():
|
for name, properties in functionProperties.items():
|
||||||
if not properties['calls']:
|
if not properties['calls']:
|
||||||
continue
|
continue
|
||||||
|
noOfCalls = len(properties['calls'])
|
||||||
|
if noOfCalls <= int(maxFunctionCalls / 8):
|
||||||
|
modColor = 'blue'
|
||||||
|
elif noOfCalls < int(maxFunctionCalls / 4):
|
||||||
|
modColor = 'green'
|
||||||
|
else:
|
||||||
|
modColor = 'red'
|
||||||
for calledFunc in properties['calls']:
|
for calledFunc in properties['calls']:
|
||||||
callGraphStr += ' "' + name + '" -> "' + calledFunc + '";\n'
|
if calledFunc.startswith('test'):
|
||||||
|
continue
|
||||||
|
if calledFunc not in excludeFuncs:
|
||||||
|
callGraphStr += ' "' + name + '" -> "' + calledFunc + \
|
||||||
|
'" [color=' + modColor + '];\n'
|
||||||
|
|
||||||
callGraphStr += '\n}\n'
|
callGraphStr += '\n}\n'
|
||||||
with open('epicyon.dot', 'w+') as fp:
|
with open('epicyon.dot', 'w+') as fp:
|
||||||
fp.write(callGraphStr)
|
fp.write(callGraphStr)
|
||||||
print('Call graph saved to epicyon.dot')
|
print('Call graph saved to epicyon.dot')
|
||||||
print('Convert to image with: ' +
|
print('Plot using: ' +
|
||||||
'dot -Tjpg epicyon.dot -o epicyon_diagram.jpg')
|
'sfdp -x -Goverlap=prism -Goverlap_scaling=8 ' +
|
||||||
|
'-Gsep=+120 -Tx11 epicyon.dot')
|
||||||
|
|
||||||
|
|
||||||
def runAllTests():
|
def runAllTests():
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"post-separator-margin-top": "10px",
|
||||||
|
"post-separator-margin-bottom": "10px",
|
||||||
"calendar-header-font-style": "normal",
|
"calendar-header-font-style": "normal",
|
||||||
"italic-font-style": "normal",
|
"italic-font-style": "normal",
|
||||||
"calendar-header-font": "'Orbitron'",
|
"calendar-header-font": "'Orbitron'",
|
||||||
|
|
@ -22,8 +24,6 @@
|
||||||
"publish-button-at-top": "False",
|
"publish-button-at-top": "False",
|
||||||
"main-visited-color": "#46eed5",
|
"main-visited-color": "#46eed5",
|
||||||
"options-main-visited-color": "#46eed5",
|
"options-main-visited-color": "#46eed5",
|
||||||
"post-separator-margin-top": "9%",
|
|
||||||
"post-separator-margin-bottom": "9%",
|
|
||||||
"post-separator-width": "80%",
|
"post-separator-width": "80%",
|
||||||
"post-separator-height": "10%",
|
"post-separator-height": "10%",
|
||||||
"column-left-header-background": "#6800e7",
|
"column-left-header-background": "#6800e7",
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "تصفية الكلمات",
|
"Filter out words": "تصفية الكلمات",
|
||||||
"Unfilter": "غير مرشح",
|
"Unfilter": "غير مرشح",
|
||||||
"Unfilter words": "الكلمات غير المصفاة",
|
"Unfilter words": "الكلمات غير المصفاة",
|
||||||
"Show Accounts": "إظهار الحسابات"
|
"Show Accounts": "إظهار الحسابات",
|
||||||
|
"Peertube Instances": "مثيلات Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "إظهار معاينات الفيديو لمواقع Peertube التالية."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filtra les paraules",
|
"Filter out words": "Filtra les paraules",
|
||||||
"Unfilter": "Sense filtre",
|
"Unfilter": "Sense filtre",
|
||||||
"Unfilter words": "Paraules sense filtre",
|
"Unfilter words": "Paraules sense filtre",
|
||||||
"Show Accounts": "Mostra comptes"
|
"Show Accounts": "Mostra comptes",
|
||||||
|
"Peertube Instances": "Instàncies de Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Mostra les previsualitzacions de vídeo dels següents llocs de Peertube."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Hidlo geiriau",
|
"Filter out words": "Hidlo geiriau",
|
||||||
"Unfilter": "Di-hid",
|
"Unfilter": "Di-hid",
|
||||||
"Unfilter words": "Geiriau di-hid",
|
"Unfilter words": "Geiriau di-hid",
|
||||||
"Show Accounts": "Dangos Cyfrifon"
|
"Show Accounts": "Dangos Cyfrifon",
|
||||||
|
"Peertube Instances": "Camau Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Dangos rhagolygon fideo ar gyfer y safleoedd Peertube canlynol."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Wörter herausfiltern",
|
"Filter out words": "Wörter herausfiltern",
|
||||||
"Unfilter": "Filter entfernen",
|
"Unfilter": "Filter entfernen",
|
||||||
"Unfilter words": "Wörter herausfiltern",
|
"Unfilter words": "Wörter herausfiltern",
|
||||||
"Show Accounts": "Konten anzeigen"
|
"Show Accounts": "Konten anzeigen",
|
||||||
|
"Peertube Instances": "Peertube-Instanzen",
|
||||||
|
"Show video previews for the following Peertube sites.": "Zeigen Sie eine Videovorschau für die folgenden Peertube-Websites an."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filter out words",
|
"Filter out words": "Filter out words",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "Unfilter words",
|
"Unfilter words": "Unfilter words",
|
||||||
"Show Accounts": "Show Accounts"
|
"Show Accounts": "Show Accounts",
|
||||||
|
"Peertube Instances": "Peertube Instances",
|
||||||
|
"Show video previews for the following Peertube sites.": "Show video previews for the following Peertube sites."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filtrar palabras",
|
"Filter out words": "Filtrar palabras",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "Palabras sin filtrar",
|
"Unfilter words": "Palabras sin filtrar",
|
||||||
"Show Accounts": "Mostrar cuentas"
|
"Show Accounts": "Mostrar cuentas",
|
||||||
|
"Peertube Instances": "Instancias de Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Muestre vistas previas de video para los siguientes sitios de Peertube."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filtrer les mots",
|
"Filter out words": "Filtrer les mots",
|
||||||
"Unfilter": "Non filtrer",
|
"Unfilter": "Non filtrer",
|
||||||
"Unfilter words": "Mots non filtrés",
|
"Unfilter words": "Mots non filtrés",
|
||||||
"Show Accounts": "Afficher les comptes"
|
"Show Accounts": "Afficher les comptes",
|
||||||
|
"Peertube Instances": "Instances Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Afficher des aperçus vidéo pour les sites Peertube suivants."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Scag focail amach",
|
"Filter out words": "Scag focail amach",
|
||||||
"Unfilter": "Neamhleithleach",
|
"Unfilter": "Neamhleithleach",
|
||||||
"Unfilter words": "Focail neamhleithleacha",
|
"Unfilter words": "Focail neamhleithleacha",
|
||||||
"Show Accounts": "Taispeáin Cuntais"
|
"Show Accounts": "Taispeáin Cuntais",
|
||||||
|
"Peertube Instances": "Imeachtaí Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Taispeáin réamhamharcanna físe do na suíomhanna Peertube seo a leanas."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "शब्दों को फ़िल्टर करें",
|
"Filter out words": "शब्दों को फ़िल्टर करें",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "अनफ़िल्टर शब्द",
|
"Unfilter words": "अनफ़िल्टर शब्द",
|
||||||
"Show Accounts": "खाते दिखाएं"
|
"Show Accounts": "खाते दिखाएं",
|
||||||
|
"Peertube Instances": "Peertube उदाहरण",
|
||||||
|
"Show video previews for the following Peertube sites.": "निम्नलिखित Peertube साइटों के लिए वीडियो पूर्वावलोकन दिखाएं।"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filtra le parole",
|
"Filter out words": "Filtra le parole",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "Parole non filtrate",
|
"Unfilter words": "Parole non filtrate",
|
||||||
"Show Accounts": "Mostra account"
|
"Show Accounts": "Mostra account",
|
||||||
|
"Peertube Instances": "Istanze di Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Mostra le anteprime dei video per i seguenti siti Peertube."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "単語を除外する",
|
"Filter out words": "単語を除外する",
|
||||||
"Unfilter": "フィルタリング解除",
|
"Unfilter": "フィルタリング解除",
|
||||||
"Unfilter words": "単語のフィルタリングを解除する",
|
"Unfilter words": "単語のフィルタリングを解除する",
|
||||||
"Show Accounts": "アカウントを表示する"
|
"Show Accounts": "アカウントを表示する",
|
||||||
|
"Peertube Instances": "Peertubeインスタンス",
|
||||||
|
"Show video previews for the following Peertube sites.": "次のPeertubeサイトのビデオプレビューを表示します。"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -343,5 +343,7 @@
|
||||||
"Filter out words": "Filter out words",
|
"Filter out words": "Filter out words",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "Unfilter words",
|
"Unfilter words": "Unfilter words",
|
||||||
"Show Accounts": "Show Accounts"
|
"Show Accounts": "Show Accounts",
|
||||||
|
"Peertube Instances": "Peertube Instances",
|
||||||
|
"Show video previews for the following Peertube sites.": "Show video previews for the following Peertube sites."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Filtrar palavras",
|
"Filter out words": "Filtrar palavras",
|
||||||
"Unfilter": "Unfilter",
|
"Unfilter": "Unfilter",
|
||||||
"Unfilter words": "Palavras sem filtro",
|
"Unfilter words": "Palavras sem filtro",
|
||||||
"Show Accounts": "Mostrar contas"
|
"Show Accounts": "Mostrar contas",
|
||||||
|
"Peertube Instances": "Instâncias Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Mostrar visualizações de vídeo para os seguintes sites Peertube."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "Отфильтровать слова",
|
"Filter out words": "Отфильтровать слова",
|
||||||
"Unfilter": "Нефильтровать",
|
"Unfilter": "Нефильтровать",
|
||||||
"Unfilter words": "Не фильтровать слова",
|
"Unfilter words": "Не фильтровать слова",
|
||||||
"Show Accounts": "Показать счета"
|
"Show Accounts": "Показать счета",
|
||||||
|
"Peertube Instances": "Экземпляры Peertube",
|
||||||
|
"Show video previews for the following Peertube sites.": "Показать превью видео для следующих сайтов Peertube."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -347,5 +347,7 @@
|
||||||
"Filter out words": "过滤掉单词",
|
"Filter out words": "过滤掉单词",
|
||||||
"Unfilter": "取消过滤",
|
"Unfilter": "取消过滤",
|
||||||
"Unfilter words": "未过滤字词",
|
"Unfilter words": "未过滤字词",
|
||||||
"Show Accounts": "显示帐户"
|
"Show Accounts": "显示帐户",
|
||||||
|
"Peertube Instances": "Peertube实例",
|
||||||
|
"Show video previews for the following Peertube sites.": "显示以下Peertube网站的视频预览。"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
utils.py
10
utils.py
|
|
@ -19,6 +19,16 @@ from calendar import monthrange
|
||||||
from followingCalendar import addPersonToCalendar
|
from followingCalendar import addPersonToCalendar
|
||||||
|
|
||||||
|
|
||||||
|
def hasUsersPath(pathStr: str) -> bool:
|
||||||
|
"""Whether there is a /users/ path (or equivalent) in the given string
|
||||||
|
"""
|
||||||
|
usersList = ('users', 'accounts', 'channel', 'profile')
|
||||||
|
for usersStr in usersList:
|
||||||
|
if '/' + usersStr + '/' in pathStr:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def validPostDate(published: str, maxAgeDays=7) -> bool:
|
def validPostDate(published: str, maxAgeDays=7) -> bool:
|
||||||
"""Returns true if the published date is recent and is not in the future
|
"""Returns true if the published date is recent and is not in the future
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ def htmlConfirmDelete(cssCache: {},
|
||||||
wfRequest: {}, personCache: {},
|
wfRequest: {}, personCache: {},
|
||||||
callingDomain: str,
|
callingDomain: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Shows a screen asking to confirm the deletion of a post
|
"""Shows a screen asking to confirm the deletion of a post
|
||||||
"""
|
"""
|
||||||
if '/statuses/' not in messageId:
|
if '/statuses/' not in messageId:
|
||||||
|
|
@ -66,6 +67,7 @@ def htmlConfirmDelete(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'outbox',
|
httpPrefix, projectVersion, 'outbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
deletePostStr += '<center>'
|
deletePostStr += '<center>'
|
||||||
deletePostStr += \
|
deletePostStr += \
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
session, wfRequest: {}, personCache: {},
|
session, wfRequest: {}, personCache: {},
|
||||||
projectVersion: str,
|
projectVersion: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Shows posts on the front screen of a news instance
|
"""Shows posts on the front screen of a news instance
|
||||||
These should only be public blog posts from the features timeline
|
These should only be public blog posts from the features timeline
|
||||||
which is the blog timeline of the news actor
|
which is the blog timeline of the news actor
|
||||||
|
|
@ -65,6 +66,7 @@ def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, False, False, True, False)
|
False, False, False, True, False)
|
||||||
if postStr:
|
if postStr:
|
||||||
profileStr += postStr + separatorStr
|
profileStr += postStr + separatorStr
|
||||||
|
|
@ -85,7 +87,9 @@ def htmlFrontScreen(rssIconAtTop: bool,
|
||||||
session, wfRequest: {}, personCache: {},
|
session, wfRequest: {}, personCache: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
newswire: {}, theme: str, extraJson=None,
|
newswire: {}, theme: str,
|
||||||
|
peertubeInstances: [],
|
||||||
|
extraJson=None,
|
||||||
pageNumber=None, maxItemsPerPage=None) -> str:
|
pageNumber=None, maxItemsPerPage=None) -> str:
|
||||||
"""Show the news instance front screen
|
"""Show the news instance front screen
|
||||||
"""
|
"""
|
||||||
|
|
@ -148,7 +152,8 @@ def htmlFrontScreen(rssIconAtTop: bool,
|
||||||
session, wfRequest, personCache,
|
session, wfRequest, personCache,
|
||||||
projectVersion,
|
projectVersion,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly) + licenseStr
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances) + licenseStr
|
||||||
|
|
||||||
# Footer which is only used for system accounts
|
# Footer which is only used for system accounts
|
||||||
profileFooterStr = ' </td>\n'
|
profileFooterStr = ' </td>\n'
|
||||||
|
|
|
||||||
121
webapp_media.py
121
webapp_media.py
|
|
@ -6,8 +6,30 @@ __maintainer__ = "Bob Mottram"
|
||||||
__email__ = "bob@freedombone.net"
|
__email__ = "bob@freedombone.net"
|
||||||
__status__ = "Production"
|
__status__ = "Production"
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def loadPeertubeInstances(baseDir: str, peertubeInstances: []) -> None:
|
||||||
|
"""Loads peertube instances from file into the given list
|
||||||
|
"""
|
||||||
|
peertubeList = None
|
||||||
|
peertubeInstancesFilename = baseDir + '/accounts/peertube.txt'
|
||||||
|
if os.path.isfile(peertubeInstancesFilename):
|
||||||
|
with open(peertubeInstancesFilename, 'r') as fp:
|
||||||
|
peertubeStr = fp.read()
|
||||||
|
if peertubeStr:
|
||||||
|
peertubeStr = peertubeStr.replace('\r', '')
|
||||||
|
peertubeList = peertubeStr.split('\n')
|
||||||
|
if not peertubeList:
|
||||||
|
return
|
||||||
|
for url in peertubeList:
|
||||||
|
if url in peertubeInstances:
|
||||||
|
continue
|
||||||
|
peertubeInstances.append(url)
|
||||||
|
|
||||||
|
|
||||||
def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
||||||
|
peertubeInstances: [],
|
||||||
width=400, height=300) -> str:
|
width=400, height=300) -> str:
|
||||||
"""Adds embedded videos
|
"""Adds embedded videos
|
||||||
"""
|
"""
|
||||||
|
|
@ -39,8 +61,14 @@ def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
||||||
"allowfullscreen></iframe>\n</center>\n"
|
"allowfullscreen></iframe>\n</center>\n"
|
||||||
return content
|
return content
|
||||||
|
|
||||||
invidiousSites = ('https://invidio.us',
|
invidiousSites = ('https://invidious.snopyta.org',
|
||||||
'https://invidious.snopyta.org',
|
'https://yewtu.be',
|
||||||
|
'https://tube.connect.cafe',
|
||||||
|
'https://invidious.kavin.rocks',
|
||||||
|
'https://invidiou.site',
|
||||||
|
'https://invidious.tube',
|
||||||
|
'https://invidious.xyz',
|
||||||
|
'https://invidious.zapashcanon.fr',
|
||||||
'http://c7hqkpkpemu6e7emz5b4vy' +
|
'http://c7hqkpkpemu6e7emz5b4vy' +
|
||||||
'z7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion',
|
'z7idjgdvgaaa3dyimmeojqbgpea3xqjoid.onion',
|
||||||
'http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4' +
|
'http://axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4' +
|
||||||
|
|
@ -76,38 +104,59 @@ def _addEmbeddedVideoFromSites(translate: {}, content: str,
|
||||||
return content
|
return content
|
||||||
|
|
||||||
if '"https://' in content:
|
if '"https://' in content:
|
||||||
# A selection of the current larger peertube sites, mostly
|
if peertubeInstances:
|
||||||
# French and German language
|
peerTubeSites = peertubeInstances
|
||||||
# These have been chosen based on reported numbers of users
|
else:
|
||||||
# and the content of each has not been reviewed, so mileage could vary
|
# A default selection of the current larger peertube sites,
|
||||||
peerTubeSites = ('peertube.mastodon.host', 'open.tube', 'share.tube',
|
# mostly French and German language.
|
||||||
'tube.tr4sk.me', 'videos.elbinario.net',
|
# These have only been semi-vetted, and so should be under
|
||||||
'hkvideo.live',
|
# continuous review.
|
||||||
'peertube.snargol.com', 'tube.22decembre.eu',
|
# Also see https://peertube_isolation.frama.io/list/ for
|
||||||
'tube.fabrigli.fr', 'libretube.net', 'libre.video',
|
# adversarial instances. Nothing in that list should be
|
||||||
'peertube.linuxrocks.online', 'spacepub.space',
|
# in the defaults below.
|
||||||
'video.ploud.jp', 'video.omniatv.com',
|
peerTubeSites = ('share.tube',
|
||||||
'peertube.servebeer.com',
|
'tube.22decembre.eu',
|
||||||
'tube.tchncs.de', 'tubee.fr', 'video.alternanet.fr',
|
'libre.video',
|
||||||
'devtube.dev-wiki.de', 'video.samedi.pm',
|
'peertube.linuxrocks.online',
|
||||||
'video.irem.univ-paris-diderot.fr',
|
'spacepub.space',
|
||||||
'peertube.openstreetmap.fr', 'video.antopie.org',
|
'tube.tchncs.de',
|
||||||
'scitech.video', 'tube.4aem.com', 'video.ploud.fr',
|
'video.irem.univ-paris-diderot.fr',
|
||||||
'peervideo.net', 'video.valme.io',
|
'peertube.openstreetmap.fr',
|
||||||
'videos.pair2jeux.tube',
|
'video.antopie.org',
|
||||||
'vault.mle.party', 'hostyour.tv',
|
'scitech.video',
|
||||||
'diode.zone', 'visionon.tv',
|
'video.ploud.fr',
|
||||||
'artitube.artifaille.fr', 'peertube.fr',
|
'diode.zone',
|
||||||
'peertube.live', 'kolektiva.media',
|
'visionon.tv',
|
||||||
'tube.ac-lyon.fr', 'www.yiny.org', 'betamax.video',
|
'peertube.fr',
|
||||||
'tube.piweb.be', 'pe.ertu.be', 'peertube.social',
|
'peertube.live',
|
||||||
'videos.lescommuns.org', 'peertube.nogafa.org',
|
'kolektiva.media',
|
||||||
'skeptikon.fr', 'video.tedomum.net',
|
'betamax.video',
|
||||||
'tube.p2p.legal', 'tilvids.com',
|
'peertube.social',
|
||||||
'sikke.fi', 'exode.me', 'peertube.video')
|
'videos.lescommuns.org',
|
||||||
|
'video.tedomum.net',
|
||||||
|
'tilvids.com',
|
||||||
|
'exode.me',
|
||||||
|
'peertube.video')
|
||||||
for site in peerTubeSites:
|
for site in peerTubeSites:
|
||||||
if '"https://' + site in content:
|
site = site.strip()
|
||||||
url = content.split('"https://' + site)[1]
|
if not site:
|
||||||
|
continue
|
||||||
|
if len(site) < 5:
|
||||||
|
continue
|
||||||
|
if '.' not in site:
|
||||||
|
continue
|
||||||
|
siteStr = site
|
||||||
|
if site.startswith('http://'):
|
||||||
|
site = site.replace('http://', '')
|
||||||
|
elif site.startswith('https://'):
|
||||||
|
site = site.replace('https://', '')
|
||||||
|
if site.endswith('.onion') or site.endswith('.i2p'):
|
||||||
|
siteStr = 'http://' + site
|
||||||
|
else:
|
||||||
|
siteStr = 'https://' + site
|
||||||
|
siteStr = '"' + siteStr
|
||||||
|
if siteStr in content:
|
||||||
|
url = content.split(siteStr)[1]
|
||||||
if '"' in url:
|
if '"' in url:
|
||||||
url = url.split('"')[0].replace('/watch/', '/embed/')
|
url = url.split('"')[0].replace('/watch/', '/embed/')
|
||||||
content = \
|
content = \
|
||||||
|
|
@ -216,9 +265,11 @@ def _addEmbeddedVideo(translate: {}, content: str,
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def addEmbeddedElements(translate: {}, content: str) -> str:
|
def addEmbeddedElements(translate: {}, content: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Adds embedded elements for various media types
|
"""Adds embedded elements for various media types
|
||||||
"""
|
"""
|
||||||
content = _addEmbeddedVideoFromSites(translate, content)
|
content = _addEmbeddedVideoFromSites(translate, content,
|
||||||
|
peertubeInstances)
|
||||||
content = _addEmbeddedAudio(translate, content)
|
content = _addEmbeddedAudio(translate, content)
|
||||||
return _addEmbeddedVideo(translate, content)
|
return _addEmbeddedVideo(translate, content)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, moderationActionStr: str,
|
authorized: bool, moderationActionStr: str,
|
||||||
theme: str) -> str:
|
theme: str, peertubeInstances: []) -> str:
|
||||||
"""Show the moderation feed as html
|
"""Show the moderation feed as html
|
||||||
This is what you see when selecting the "mod" timeline
|
This is what you see when selecting the "mod" timeline
|
||||||
"""
|
"""
|
||||||
|
|
@ -51,7 +51,8 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
||||||
newswire, False, False, positiveVoting,
|
newswire, False, False, positiveVoting,
|
||||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, moderationActionStr, theme)
|
authorized, moderationActionStr, theme,
|
||||||
|
peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlAccountInfo(cssCache: {}, translate: {},
|
def htmlAccountInfo(cssCache: {}, translate: {},
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ def htmlPersonOptions(defaultTimeline: str,
|
||||||
ssbAddress: str,
|
ssbAddress: str,
|
||||||
blogAddress: str,
|
blogAddress: str,
|
||||||
toxAddress: str,
|
toxAddress: str,
|
||||||
|
briarAddress: str,
|
||||||
jamiAddress: str,
|
jamiAddress: str,
|
||||||
PGPpubKey: str,
|
PGPpubKey: str,
|
||||||
PGPfingerprint: str,
|
PGPfingerprint: str,
|
||||||
|
|
@ -141,6 +142,15 @@ def htmlPersonOptions(defaultTimeline: str,
|
||||||
if toxAddress:
|
if toxAddress:
|
||||||
optionsStr += \
|
optionsStr += \
|
||||||
'<p class="imText">Tox: ' + removeHtml(toxAddress) + '</p>\n'
|
'<p class="imText">Tox: ' + removeHtml(toxAddress) + '</p>\n'
|
||||||
|
if briarAddress:
|
||||||
|
if briarAddress.startswith('briar://'):
|
||||||
|
optionsStr += \
|
||||||
|
'<p class="imText">' + \
|
||||||
|
removeHtml(briarAddress) + '</p>\n'
|
||||||
|
else:
|
||||||
|
optionsStr += \
|
||||||
|
'<p class="imText">briar://' + \
|
||||||
|
removeHtml(briarAddress) + '</p>\n'
|
||||||
if jamiAddress:
|
if jamiAddress:
|
||||||
optionsStr += \
|
optionsStr += \
|
||||||
'<p class="imText">Jami: ' + removeHtml(jamiAddress) + '</p>\n'
|
'<p class="imText">Jami: ' + removeHtml(jamiAddress) + '</p>\n'
|
||||||
|
|
|
||||||
|
|
@ -1076,6 +1076,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
httpPrefix: str, projectVersion: str,
|
httpPrefix: str, projectVersion: str,
|
||||||
boxName: str, YTReplacementDomain: str,
|
boxName: str, YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: [],
|
||||||
showRepeats=True,
|
showRepeats=True,
|
||||||
showIcons=False,
|
showIcons=False,
|
||||||
manuallyApprovesFollowers=False,
|
manuallyApprovesFollowers=False,
|
||||||
|
|
@ -1483,7 +1484,8 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
|
|
||||||
if not postIsSensitive:
|
if not postIsSensitive:
|
||||||
contentStr = objectContent + attachmentStr
|
contentStr = objectContent + attachmentStr
|
||||||
contentStr = addEmbeddedElements(translate, contentStr)
|
contentStr = addEmbeddedElements(translate, contentStr,
|
||||||
|
peertubeInstances)
|
||||||
contentStr = insertQuestion(baseDir, translate,
|
contentStr = insertQuestion(baseDir, translate,
|
||||||
nickname, domain, port,
|
nickname, domain, port,
|
||||||
contentStr, postJsonObject,
|
contentStr, postJsonObject,
|
||||||
|
|
@ -1499,7 +1501,8 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
# get the content warning text
|
# get the content warning text
|
||||||
cwContentStr = objectContent + attachmentStr
|
cwContentStr = objectContent + attachmentStr
|
||||||
if not isPatch:
|
if not isPatch:
|
||||||
cwContentStr = addEmbeddedElements(translate, cwContentStr)
|
cwContentStr = addEmbeddedElements(translate, cwContentStr,
|
||||||
|
peertubeInstances)
|
||||||
cwContentStr = \
|
cwContentStr = \
|
||||||
insertQuestion(baseDir, translate, nickname, domain, port,
|
insertQuestion(baseDir, translate, nickname, domain, port,
|
||||||
cwContentStr, postJsonObject, pageNumber)
|
cwContentStr, postJsonObject, pageNumber)
|
||||||
|
|
@ -1571,7 +1574,8 @@ def htmlIndividualPost(cssCache: {},
|
||||||
postJsonObject: {}, httpPrefix: str,
|
postJsonObject: {}, httpPrefix: str,
|
||||||
projectVersion: str, likedBy: str,
|
projectVersion: str, likedBy: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show an individual post as html
|
"""Show an individual post as html
|
||||||
"""
|
"""
|
||||||
postStr = ''
|
postStr = ''
|
||||||
|
|
@ -1611,6 +1615,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, authorized, False, False, False)
|
False, authorized, False, False, False)
|
||||||
messageId = removeIdEnding(postJsonObject['id'])
|
messageId = removeIdEnding(postJsonObject['id'])
|
||||||
|
|
||||||
|
|
@ -1636,6 +1641,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, authorized,
|
False, authorized,
|
||||||
False, False, False) + postStr
|
False, False, False) + postStr
|
||||||
|
|
||||||
|
|
@ -1664,6 +1670,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, authorized,
|
False, authorized,
|
||||||
False, False, False)
|
False, False, False)
|
||||||
cssFilename = baseDir + '/epicyon-profile.css'
|
cssFilename = baseDir + '/epicyon-profile.css'
|
||||||
|
|
@ -1680,7 +1687,8 @@ def htmlPostReplies(cssCache: {},
|
||||||
nickname: str, domain: str, port: int, repliesJson: {},
|
nickname: str, domain: str, port: int, repliesJson: {},
|
||||||
httpPrefix: str, projectVersion: str,
|
httpPrefix: str, projectVersion: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the replies to an individual post as html
|
"""Show the replies to an individual post as html
|
||||||
"""
|
"""
|
||||||
repliesStr = ''
|
repliesStr = ''
|
||||||
|
|
@ -1696,6 +1704,7 @@ def htmlPostReplies(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
|
|
||||||
cssFilename = baseDir + '/epicyon-profile.css'
|
cssFilename = baseDir + '/epicyon-profile.css'
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ __status__ = "Production"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
from utils import hasUsersPath
|
||||||
from utils import getFullDomain
|
from utils import getFullDomain
|
||||||
from utils import isDormant
|
from utils import isDormant
|
||||||
from utils import getNicknameFromActor
|
from utils import getNicknameFromActor
|
||||||
|
|
@ -33,6 +34,7 @@ from pgp import getEmailAddress
|
||||||
from pgp import getPGPfingerprint
|
from pgp import getPGPfingerprint
|
||||||
from pgp import getPGPpubKey
|
from pgp import getPGPpubKey
|
||||||
from tox import getToxAddress
|
from tox import getToxAddress
|
||||||
|
from briar import getBriarAddress
|
||||||
from jami import getJamiAddress
|
from jami import getJamiAddress
|
||||||
from filters import isFiltered
|
from filters import isFiltered
|
||||||
from webapp_frontscreen import htmlFrontScreen
|
from webapp_frontscreen import htmlFrontScreen
|
||||||
|
|
@ -58,14 +60,11 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
debug: bool, projectVersion: str,
|
debug: bool, projectVersion: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
defaultTimeline: str) -> str:
|
defaultTimeline: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show a profile page after a search for a fediverse address
|
"""Show a profile page after a search for a fediverse address
|
||||||
"""
|
"""
|
||||||
if '/users/' in profileHandle or \
|
if hasUsersPath(profileHandle) or '/@' in profileHandle:
|
||||||
'/accounts/' in profileHandle or \
|
|
||||||
'/channel/' in profileHandle or \
|
|
||||||
'/profile/' in profileHandle or \
|
|
||||||
'/@' in profileHandle:
|
|
||||||
searchNickname = getNicknameFromActor(profileHandle)
|
searchNickname = getNicknameFromActor(profileHandle)
|
||||||
searchDomain, searchPort = getDomainFromActor(profileHandle)
|
searchDomain, searchPort = getDomainFromActor(profileHandle)
|
||||||
else:
|
else:
|
||||||
|
|
@ -279,6 +278,7 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
i += 1
|
i += 1
|
||||||
if i >= 20:
|
if i >= 20:
|
||||||
|
|
@ -372,6 +372,7 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
newswire: {}, theme: str, dormantMonths: int,
|
newswire: {}, theme: str, dormantMonths: int,
|
||||||
|
peertubeInstances: [],
|
||||||
extraJson=None, pageNumber=None,
|
extraJson=None, pageNumber=None,
|
||||||
maxItemsPerPage=None) -> str:
|
maxItemsPerPage=None) -> str:
|
||||||
"""Show the profile page as html
|
"""Show the profile page as html
|
||||||
|
|
@ -443,9 +444,11 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
matrixAddress = getMatrixAddress(profileJson)
|
matrixAddress = getMatrixAddress(profileJson)
|
||||||
ssbAddress = getSSBAddress(profileJson)
|
ssbAddress = getSSBAddress(profileJson)
|
||||||
toxAddress = getToxAddress(profileJson)
|
toxAddress = getToxAddress(profileJson)
|
||||||
|
briarAddress = getBriarAddress(profileJson)
|
||||||
jamiAddress = getJamiAddress(profileJson)
|
jamiAddress = getJamiAddress(profileJson)
|
||||||
if donateUrl or xmppAddress or matrixAddress or \
|
if donateUrl or xmppAddress or matrixAddress or \
|
||||||
ssbAddress or toxAddress or jamiAddress or PGPpubKey or \
|
ssbAddress or toxAddress or briarAddress or \
|
||||||
|
jamiAddress or PGPpubKey or \
|
||||||
PGPfingerprint or emailAddress:
|
PGPfingerprint or emailAddress:
|
||||||
donateSection = '<div class="container">\n'
|
donateSection = '<div class="container">\n'
|
||||||
donateSection += ' <center>\n'
|
donateSection += ' <center>\n'
|
||||||
|
|
@ -473,6 +476,15 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
donateSection += \
|
donateSection += \
|
||||||
'<p>Tox: <label class="toxaddr">' + \
|
'<p>Tox: <label class="toxaddr">' + \
|
||||||
toxAddress + '</label></p>\n'
|
toxAddress + '</label></p>\n'
|
||||||
|
if briarAddress:
|
||||||
|
if briarAddress.startswith('briar://'):
|
||||||
|
donateSection += \
|
||||||
|
'<p><label class="toxaddr">' + \
|
||||||
|
briarAddress + '</label></p>\n'
|
||||||
|
else:
|
||||||
|
donateSection += \
|
||||||
|
'<p>briar://<label class="toxaddr">' + \
|
||||||
|
briarAddress + '</label></p>\n'
|
||||||
if jamiAddress:
|
if jamiAddress:
|
||||||
donateSection += \
|
donateSection += \
|
||||||
'<p>Jami: <label class="toxaddr">' + \
|
'<p>Jami: <label class="toxaddr">' + \
|
||||||
|
|
@ -628,7 +640,8 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
session, wfRequest, personCache,
|
session, wfRequest, personCache,
|
||||||
projectVersion,
|
projectVersion,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly) + licenseStr
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances) + licenseStr
|
||||||
elif selected == 'following':
|
elif selected == 'following':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
||||||
|
|
@ -674,7 +687,8 @@ def _htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
session, wfRequest: {}, personCache: {},
|
session, wfRequest: {}, personCache: {},
|
||||||
projectVersion: str,
|
projectVersion: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Shows posts on the profile screen
|
"""Shows posts on the profile screen
|
||||||
These should only be public posts
|
These should only be public posts
|
||||||
"""
|
"""
|
||||||
|
|
@ -712,6 +726,7 @@ def _htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
httpPrefix, projectVersion, 'inbox',
|
httpPrefix, projectVersion, 'inbox',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
False, False, False, True, False)
|
False, False, False, True, False)
|
||||||
if postStr:
|
if postStr:
|
||||||
profileStr += postStr + separatorStr
|
profileStr += postStr + separatorStr
|
||||||
|
|
@ -833,7 +848,8 @@ def _htmlProfileShares(actor: str, translate: {},
|
||||||
|
|
||||||
def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
domain: str, port: int, httpPrefix: str,
|
domain: str, port: int, httpPrefix: str,
|
||||||
defaultTimeline: str, theme: str) -> str:
|
defaultTimeline: str, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Shows the edit profile screen
|
"""Shows the edit profile screen
|
||||||
"""
|
"""
|
||||||
imageFormats = getImageFormats()
|
imageFormats = getImageFormats()
|
||||||
|
|
@ -873,6 +889,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
ssbAddress = ''
|
ssbAddress = ''
|
||||||
blogAddress = ''
|
blogAddress = ''
|
||||||
toxAddress = ''
|
toxAddress = ''
|
||||||
|
briarAddress = ''
|
||||||
manuallyApprovesFollowers = ''
|
manuallyApprovesFollowers = ''
|
||||||
actorJson = loadJson(actorFilename)
|
actorJson = loadJson(actorFilename)
|
||||||
if actorJson:
|
if actorJson:
|
||||||
|
|
@ -882,6 +899,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
ssbAddress = getSSBAddress(actorJson)
|
ssbAddress = getSSBAddress(actorJson)
|
||||||
blogAddress = getBlogAddress(actorJson)
|
blogAddress = getBlogAddress(actorJson)
|
||||||
toxAddress = getToxAddress(actorJson)
|
toxAddress = getToxAddress(actorJson)
|
||||||
|
briarAddress = getBriarAddress(actorJson)
|
||||||
jamiAddress = getJamiAddress(actorJson)
|
jamiAddress = getJamiAddress(actorJson)
|
||||||
emailAddress = getEmailAddress(actorJson)
|
emailAddress = getEmailAddress(actorJson)
|
||||||
PGPpubKey = getPGPpubKey(actorJson)
|
PGPpubKey = getPGPpubKey(actorJson)
|
||||||
|
|
@ -1029,6 +1047,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
themesDropdown = ''
|
themesDropdown = ''
|
||||||
instanceStr = ''
|
instanceStr = ''
|
||||||
editorsStr = ''
|
editorsStr = ''
|
||||||
|
peertubeStr = ''
|
||||||
|
|
||||||
adminNickname = getConfigParam(baseDir, 'admin')
|
adminNickname = getConfigParam(baseDir, 'admin')
|
||||||
if adminNickname:
|
if adminNickname:
|
||||||
|
|
@ -1145,6 +1164,21 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
'<option value="' + themeName +
|
'<option value="' + themeName +
|
||||||
'" selected>')
|
'" selected>')
|
||||||
|
|
||||||
|
peertubeStr = \
|
||||||
|
' <br><b><label class="labels">' + \
|
||||||
|
translate['Peertube Instances'] + '</label></b>\n'
|
||||||
|
idx = 'Show video previews for the following Peertube sites.'
|
||||||
|
peertubeStr += \
|
||||||
|
' <br><label class="labels">' + \
|
||||||
|
translate[idx] + '</label>\n'
|
||||||
|
peertubeInstancesStr = ''
|
||||||
|
for url in peertubeInstances:
|
||||||
|
peertubeInstancesStr += url + '\n'
|
||||||
|
peertubeStr += \
|
||||||
|
' <textarea id="message" name="ptInstances" ' + \
|
||||||
|
'style="height:200px">' + peertubeInstancesStr + \
|
||||||
|
'</textarea>\n'
|
||||||
|
|
||||||
editProfileForm = htmlHeaderWithExternalStyle(cssFilename)
|
editProfileForm = htmlHeaderWithExternalStyle(cssFilename)
|
||||||
|
|
||||||
# top banner
|
# top banner
|
||||||
|
|
@ -1220,6 +1254,11 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
' <input type="text" name="toxAddress" value="' + \
|
' <input type="text" name="toxAddress" value="' + \
|
||||||
toxAddress + '">\n'
|
toxAddress + '">\n'
|
||||||
|
|
||||||
|
editProfileForm += '<label class="labels">Briar</label><br>\n'
|
||||||
|
editProfileForm += \
|
||||||
|
' <input type="text" name="briarAddress" value="' + \
|
||||||
|
briarAddress + '">\n'
|
||||||
|
|
||||||
editProfileForm += '<label class="labels">Jami</label><br>\n'
|
editProfileForm += '<label class="labels">Jami</label><br>\n'
|
||||||
editProfileForm += \
|
editProfileForm += \
|
||||||
' <input type="text" name="jamiAddress" value="' + \
|
' <input type="text" name="jamiAddress" value="' + \
|
||||||
|
|
@ -1436,7 +1475,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||||
editProfileForm += ' <label class="labels">' + \
|
editProfileForm += ' <label class="labels">' + \
|
||||||
translate[idx] + '</label>\n'
|
translate[idx] + '</label>\n'
|
||||||
editProfileForm += skillsStr + themesDropdown
|
editProfileForm += skillsStr + themesDropdown
|
||||||
editProfileForm += moderatorsStr + editorsStr
|
editProfileForm += moderatorsStr + editorsStr + peertubeStr
|
||||||
editProfileForm += ' </div>\n' + instanceStr
|
editProfileForm += ' </div>\n' + instanceStr
|
||||||
editProfileForm += ' <div class="container">\n'
|
editProfileForm += ' <div class="container">\n'
|
||||||
editProfileForm += ' <b><label class="labels">' + \
|
editProfileForm += ' <b><label class="labels">' + \
|
||||||
|
|
|
||||||
|
|
@ -506,7 +506,8 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
personCache: {},
|
personCache: {},
|
||||||
port: int,
|
port: int,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show a page containing search results for your post history
|
"""Show a page containing search results for your post history
|
||||||
"""
|
"""
|
||||||
if historysearch.startswith('!'):
|
if historysearch.startswith('!'):
|
||||||
|
|
@ -579,6 +580,7 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
'search',
|
'search',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
False, False, False)
|
False, False, False)
|
||||||
|
|
@ -599,7 +601,8 @@ def htmlHashtagSearch(cssCache: {},
|
||||||
session, wfRequest: {}, personCache: {},
|
session, wfRequest: {}, personCache: {},
|
||||||
httpPrefix: str, projectVersion: str,
|
httpPrefix: str, projectVersion: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool) -> str:
|
showPublishedDateOnly: bool,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show a page containing search results for a hashtag
|
"""Show a page containing search results for a hashtag
|
||||||
"""
|
"""
|
||||||
if hashtag.startswith('#'):
|
if hashtag.startswith('#'):
|
||||||
|
|
@ -745,6 +748,7 @@ def htmlHashtagSearch(cssCache: {},
|
||||||
'search',
|
'search',
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
showRepeats, showIcons,
|
showRepeats, showIcons,
|
||||||
manuallyApprovesFollowers,
|
manuallyApprovesFollowers,
|
||||||
showPublicOnly,
|
showPublicOnly,
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,8 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool,
|
authorized: bool,
|
||||||
moderationActionStr: str,
|
moderationActionStr: str,
|
||||||
theme: str) -> str:
|
theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the timeline as html
|
"""Show the timeline as html
|
||||||
"""
|
"""
|
||||||
enableTimingLog = False
|
enableTimingLog = False
|
||||||
|
|
@ -566,6 +567,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
boxName,
|
boxName,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
|
peertubeInstances,
|
||||||
boxName != 'dm',
|
boxName != 'dm',
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
manuallyApproveFollowers,
|
manuallyApproveFollowers,
|
||||||
|
|
@ -720,7 +722,8 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the shares timeline as html
|
"""Show the shares timeline as html
|
||||||
"""
|
"""
|
||||||
manuallyApproveFollowers = \
|
manuallyApproveFollowers = \
|
||||||
|
|
@ -739,7 +742,7 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInbox(cssCache: {}, defaultTimeline: str,
|
def htmlInbox(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -757,7 +760,8 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the inbox as html
|
"""Show the inbox as html
|
||||||
"""
|
"""
|
||||||
manuallyApproveFollowers = \
|
manuallyApproveFollowers = \
|
||||||
|
|
@ -776,7 +780,7 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -794,7 +798,8 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the bookmarks as html
|
"""Show the bookmarks as html
|
||||||
"""
|
"""
|
||||||
manuallyApproveFollowers = \
|
manuallyApproveFollowers = \
|
||||||
|
|
@ -813,7 +818,7 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlEvents(cssCache: {}, defaultTimeline: str,
|
def htmlEvents(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -831,7 +836,8 @@ def htmlEvents(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the events as html
|
"""Show the events as html
|
||||||
"""
|
"""
|
||||||
manuallyApproveFollowers = \
|
manuallyApproveFollowers = \
|
||||||
|
|
@ -850,7 +856,7 @@ def htmlEvents(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -868,7 +874,8 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the DM timeline as html
|
"""Show the DM timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -882,7 +889,7 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
||||||
showPublishAsIcon,
|
showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -900,7 +907,8 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the replies timeline as html
|
"""Show the replies timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -915,7 +923,7 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -933,7 +941,8 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the media timeline as html
|
"""Show the media timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -948,7 +957,7 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -966,7 +975,8 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the blogs timeline as html
|
"""Show the blogs timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -981,7 +991,7 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -1000,7 +1010,8 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool,
|
authorized: bool,
|
||||||
theme: str) -> str:
|
theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the features timeline as html
|
"""Show the features timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -1015,7 +1026,7 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -1033,7 +1044,8 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the news timeline as html
|
"""Show the news timeline as html
|
||||||
"""
|
"""
|
||||||
return htmlTimeline(cssCache, defaultTimeline,
|
return htmlTimeline(cssCache, defaultTimeline,
|
||||||
|
|
@ -1048,7 +1060,7 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
||||||
positiveVoting, showPublishAsIcon,
|
positiveVoting, showPublishAsIcon,
|
||||||
fullWidthTimelineButtonHeader,
|
fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
||||||
|
|
||||||
def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
||||||
|
|
@ -1066,7 +1078,8 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
||||||
iconsAsButtons: bool,
|
iconsAsButtons: bool,
|
||||||
rssIconAtTop: bool,
|
rssIconAtTop: bool,
|
||||||
publishButtonAtTop: bool,
|
publishButtonAtTop: bool,
|
||||||
authorized: bool, theme: str) -> str:
|
authorized: bool, theme: str,
|
||||||
|
peertubeInstances: []) -> str:
|
||||||
"""Show the Outbox as html
|
"""Show the Outbox as html
|
||||||
"""
|
"""
|
||||||
manuallyApproveFollowers = \
|
manuallyApproveFollowers = \
|
||||||
|
|
@ -1082,4 +1095,4 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
||||||
newswire, False, False, positiveVoting,
|
newswire, False, False, positiveVoting,
|
||||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||||
authorized, None, theme)
|
authorized, None, theme, peertubeInstances)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue