CSS cache

merge-requests/8/head
Bob Mottram 2020-10-29 12:48:58 +00:00
parent 1caa61c94a
commit cd64d747d1
3 changed files with 347 additions and 207 deletions

186
daemon.py
View File

@ -1298,7 +1298,8 @@ class PubServer(BaseHTTPRequestHandler):
else:
if isSuspended(baseDir, loginNickname):
msg = \
htmlSuspended(baseDir).encode('utf-8')
htmlSuspended(self.server.cssCache,
baseDir).encode('utf-8')
self._login_headers('text/html',
len(msg), callingDomain)
self._write(msg)
@ -1420,7 +1421,8 @@ class PubServer(BaseHTTPRequestHandler):
moderationText = \
urllib.parse.unquote_plus(modText.strip())
elif moderationStr.startswith('submitInfo'):
msg = htmlModerationInfo(self.server.translate,
msg = htmlModerationInfo(self.server.cssCache,
self.server.translate,
baseDir, httpPrefix)
msg = msg.encode('utf-8')
self._login_headers('text/html',
@ -1763,7 +1765,8 @@ class PubServer(BaseHTTPRequestHandler):
if debug:
print('Unblocking ' + optionsActor)
msg = \
htmlUnblockConfirm(self.server.translate,
htmlUnblockConfirm(self.server.cssCache,
self.server.translate,
baseDir,
usersPath,
optionsActor,
@ -1780,7 +1783,8 @@ class PubServer(BaseHTTPRequestHandler):
if debug:
print('Following ' + optionsActor)
msg = \
htmlFollowConfirm(self.server.translate,
htmlFollowConfirm(self.server.cssCache,
self.server.translate,
baseDir,
usersPath,
optionsActor,
@ -1797,7 +1801,8 @@ class PubServer(BaseHTTPRequestHandler):
if debug:
print('Unfollowing ' + optionsActor)
msg = \
htmlUnfollowConfirm(self.server.translate,
htmlUnfollowConfirm(self.server.cssCache,
self.server.translate,
baseDir,
usersPath,
optionsActor,
@ -1814,7 +1819,8 @@ class PubServer(BaseHTTPRequestHandler):
if debug:
print('Sending DM to ' + optionsActor)
reportPath = path.replace('/personoptions', '') + '/newdm'
msg = htmlNewPost(False, self.server.translate,
msg = htmlNewPost(self.server.cssCache,
False, self.server.translate,
baseDir,
httpPrefix,
reportPath, None,
@ -1881,7 +1887,8 @@ class PubServer(BaseHTTPRequestHandler):
print('Reporting ' + optionsActor)
reportPath = \
path.replace('/personoptions', '') + '/newreport'
msg = htmlNewPost(False, self.server.translate,
msg = htmlNewPost(self.server.cssCache,
False, self.server.translate,
baseDir,
httpPrefix,
reportPath, None, [],
@ -2307,9 +2314,8 @@ class PubServer(BaseHTTPRequestHandler):
nickname = getNicknameFromActor(actorStr)
# hashtag search
hashtagStr = \
htmlHashtagSearch(nickname,
domain,
port,
htmlHashtagSearch(self.server.cssCache,
nickname, domain, port,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -2334,7 +2340,8 @@ class PubServer(BaseHTTPRequestHandler):
# skill search
searchStr = searchStr.replace('*', '').strip()
skillStr = \
htmlSkillsSearch(self.server.translate,
htmlSkillsSearch(self.server.cssCache,
self.server.translate,
baseDir,
httpPrefix,
searchStr,
@ -2352,7 +2359,8 @@ class PubServer(BaseHTTPRequestHandler):
nickname = getNicknameFromActor(actorStr)
searchStr = searchStr.replace('!', '').strip()
historyStr = \
htmlHistorySearch(self.server.translate,
htmlHistorySearch(self.server.cssCache,
self.server.translate,
baseDir,
httpPrefix,
nickname,
@ -2396,7 +2404,8 @@ class PubServer(BaseHTTPRequestHandler):
return
profilePathStr = path.replace('/searchhandle', '')
profileStr = \
htmlProfileAfterSearch(self.server.recentPostsCache,
htmlProfileAfterSearch(self.server.cssCache,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
baseDir,
@ -2437,7 +2446,8 @@ class PubServer(BaseHTTPRequestHandler):
searchStr.replace(' emoji', '')
# emoji search
emojiStr = \
htmlSearchEmoji(self.server.translate,
htmlSearchEmoji(self.server.cssCache,
self.server.translate,
baseDir,
httpPrefix,
searchStr)
@ -2451,7 +2461,8 @@ class PubServer(BaseHTTPRequestHandler):
else:
# shared items search
sharedItemsStr = \
htmlSearchSharedItems(self.server.translate,
htmlSearchSharedItems(self.server.cssCache,
self.server.translate,
baseDir,
searchStr, pageNumber,
maxPostsInFeed,
@ -4540,7 +4551,8 @@ class PubServer(BaseHTTPRequestHandler):
emailAddress = getEmailAddress(actorJson)
PGPpubKey = getPGPpubKey(actorJson)
PGPfingerprint = getPGPfingerprint(actorJson)
msg = htmlPersonOptions(self.server.translate,
msg = htmlPersonOptions(self.server.cssCache,
self.server.translate,
baseDir, domain,
domainFull,
originPathStr,
@ -4772,7 +4784,7 @@ class PubServer(BaseHTTPRequestHandler):
if '?page=' in hashtag:
hashtag = hashtag.split('?page=')[0]
if isBlockedHashtag(baseDir, hashtag):
msg = htmlHashtagBlocked(baseDir,
msg = htmlHashtagBlocked(self.server.cssCache, baseDir,
self.server.translate).encode('utf-8')
self._login_headers('text/html', len(msg), callingDomain)
self._write(msg)
@ -4785,8 +4797,8 @@ class PubServer(BaseHTTPRequestHandler):
nickname = \
getNicknameFromActor(actor)
hashtagStr = \
htmlHashtagSearch(nickname,
domain, port,
htmlHashtagSearch(self.server.cssCache,
nickname, domain, port,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -5696,7 +5708,8 @@ class PubServer(BaseHTTPRequestHandler):
return
deleteStr = \
htmlDeletePost(self.server.recentPostsCache,
htmlDeletePost(self.server.cssCache,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate, pageNumber,
self.server.session, baseDir,
@ -5890,7 +5903,8 @@ class PubServer(BaseHTTPRequestHandler):
projectVersion = self.server.projectVersion
ytDomain = self.server.YTReplacementDomain
msg = \
htmlPostReplies(recentPostsCache,
htmlPostReplies(self.server.cssCache,
recentPostsCache,
maxRecentPosts,
translate,
baseDir,
@ -5971,7 +5985,8 @@ class PubServer(BaseHTTPRequestHandler):
projectVersion = self.server.projectVersion
ytDomain = self.server.YTReplacementDomain
msg = \
htmlPostReplies(recentPostsCache,
htmlPostReplies(self.server.cssCache,
recentPostsCache,
maxRecentPosts,
translate,
baseDir,
@ -6051,7 +6066,8 @@ class PubServer(BaseHTTPRequestHandler):
iconsAsButtons = \
self.server.iconsAsButtons
msg = \
htmlProfile(iconsAsButtons,
htmlProfile(self.server.cssCache,
iconsAsButtons,
defaultTimeline,
recentPostsCache,
self.server.maxRecentPosts,
@ -6128,7 +6144,8 @@ class PubServer(BaseHTTPRequestHandler):
iconsAsButtons = \
self.server.iconsAsButtons
msg = \
htmlProfile(iconsAsButtons,
htmlProfile(self.server.cssCache,
iconsAsButtons,
defaultTimeline,
recentPostsCache,
self.server.maxRecentPosts,
@ -6244,8 +6261,10 @@ class PubServer(BaseHTTPRequestHandler):
self.server.YTReplacementDomain
showPublishedDateOnly = \
self.server.showPublishedDateOnly
cssCache = self.server.cssCache
msg = \
htmlIndividualPost(recentPostsCache,
htmlIndividualPost(cssCache,
recentPostsCache,
maxRecentPosts,
translate,
self.server.session,
@ -6355,7 +6374,8 @@ class PubServer(BaseHTTPRequestHandler):
showPublishedDateOnly = \
self.server.showPublishedDateOnly
msg = \
htmlIndividualPost(recentPostsCache,
htmlIndividualPost(self.server.cssCache,
recentPostsCache,
maxRecentPosts,
translate,
baseDir,
@ -6472,7 +6492,8 @@ class PubServer(BaseHTTPRequestHandler):
'show inbox page')
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = htmlInbox(defaultTimeline,
msg = htmlInbox(self.server.cssCache,
defaultTimeline,
recentPostsCache,
maxRecentPosts,
translate,
@ -6593,7 +6614,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlInboxDMs(self.server.defaultTimeline,
htmlInboxDMs(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -6707,7 +6729,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlInboxReplies(self.server.defaultTimeline,
htmlInboxReplies(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -6821,7 +6844,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlInboxMedia(self.server.defaultTimeline,
htmlInboxMedia(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -6935,7 +6959,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlInboxBlogs(self.server.defaultTimeline,
htmlInboxBlogs(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7057,7 +7082,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlInboxNews(self.server.defaultTimeline,
htmlInboxNews(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7142,7 +7168,8 @@ class PubServer(BaseHTTPRequestHandler):
else:
pageNumber = 1
msg = \
htmlShares(self.server.defaultTimeline,
htmlShares(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7238,7 +7265,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlBookmarks(self.server.defaultTimeline,
htmlBookmarks(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7355,7 +7383,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlEvents(self.server.defaultTimeline,
htmlEvents(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7464,7 +7493,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlOutbox(self.server.defaultTimeline,
htmlOutbox(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7564,7 +7594,8 @@ class PubServer(BaseHTTPRequestHandler):
fullWidthTimelineButtonHeader = \
self.server.fullWidthTimelineButtonHeader
msg = \
htmlModeration(self.server.defaultTimeline,
htmlModeration(self.server.cssCache,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
self.server.translate,
@ -7666,7 +7697,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.GETbusy = False
return True
msg = \
htmlProfile(self.server.iconsAsButtons,
htmlProfile(self.server.cssCache,
self.server.iconsAsButtons,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
@ -7755,7 +7787,8 @@ class PubServer(BaseHTTPRequestHandler):
return True
msg = \
htmlProfile(self.server.iconsAsButtons,
htmlProfile(self.server.cssCache,
self.server.iconsAsButtons,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
@ -7843,7 +7876,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.GETbusy = False
return True
msg = \
htmlProfile(self.server.iconsAsButtons,
htmlProfile(self.server.cssCache,
self.server.iconsAsButtons,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
@ -7907,7 +7941,8 @@ class PubServer(BaseHTTPRequestHandler):
self.server.GETbusy = False
return True
msg = \
htmlProfile(self.server.iconsAsButtons,
htmlProfile(self.server.cssCache,
self.server.iconsAsButtons,
self.server.defaultTimeline,
self.server.recentPostsCache,
self.server.maxRecentPosts,
@ -8362,9 +8397,9 @@ class PubServer(BaseHTTPRequestHandler):
if '?' in postDay:
postDay = postDay.split('?')[0]
# show the confirmation screen screen
msg = htmlCalendarDeleteConfirm(translate,
baseDir,
path,
msg = htmlCalendarDeleteConfirm(self.server.cssCache,
translate,
baseDir, path,
httpPrefix,
domainFull,
postId, postTime,
@ -8418,7 +8453,8 @@ class PubServer(BaseHTTPRequestHandler):
break
if isNewPostEndpoint:
nickname = getNicknameFromActor(path)
msg = htmlNewPost(mediaInstance,
msg = htmlNewPost(self.server.cssCache,
mediaInstance,
translate,
baseDir,
httpPrefix,
@ -8451,7 +8487,8 @@ class PubServer(BaseHTTPRequestHandler):
"""Show the edit profile screen
"""
if '/users/' in path and path.endswith('/editprofile'):
msg = htmlEditProfile(translate,
msg = htmlEditProfile(self.server.cssCache,
translate,
baseDir,
path, domain,
port,
@ -8473,7 +8510,8 @@ class PubServer(BaseHTTPRequestHandler):
"""Show the links from the left column
"""
if '/users/' in path and path.endswith('/editlinks'):
msg = htmlEditLinks(translate,
msg = htmlEditLinks(self.server.cssCache,
translate,
baseDir,
path, domain,
port,
@ -8495,7 +8533,8 @@ class PubServer(BaseHTTPRequestHandler):
"""Show the newswire from the right column
"""
if '/users/' in path and path.endswith('/editnewswire'):
msg = htmlEditNewswire(translate,
msg = htmlEditNewswire(self.server.cssCache,
translate,
baseDir,
path, domain,
port,
@ -8524,7 +8563,8 @@ class PubServer(BaseHTTPRequestHandler):
postUrl = httpPrefix + '://' + domainFull + \
'/users/news/statuses/' + postId
path = path.split('/editnewspost=')[0]
msg = htmlEditNewsPost(translate, baseDir,
msg = htmlEditNewsPost(self.server.cssCache,
translate, baseDir,
path, domain, port,
httpPrefix,
postUrl).encode('utf-8')
@ -8618,7 +8658,8 @@ class PubServer(BaseHTTPRequestHandler):
if self.path == '/logout':
if not self.server.newsInstance:
msg = \
htmlLogin(self.server.translate,
htmlLogin(self.server.cssCache,
self.server.translate,
self.server.baseDir, False).encode('utf-8')
self._logout_headers('text/html', len(msg), callingDomain)
self._write(msg)
@ -8957,7 +8998,8 @@ class PubServer(BaseHTTPRequestHandler):
actor = \
self.server.httpPrefix + '://' + \
self.server.domainFull + usersPath
msg = htmlRemoveSharedItem(self.server.translate,
msg = htmlRemoveSharedItem(self.server.cssCache,
self.server.translate,
self.server.baseDir,
actor, shareName,
callingDomain).encode('utf-8')
@ -8986,14 +9028,17 @@ class PubServer(BaseHTTPRequestHandler):
if self.path.startswith('/terms'):
if callingDomain.endswith('.onion') and \
self.server.onionDomain:
msg = htmlTermsOfService(self.server.baseDir, 'http',
msg = htmlTermsOfService(self.server.cssCache,
self.server.baseDir, 'http',
self.server.onionDomain)
elif (callingDomain.endswith('.i2p') and
self.server.i2pDomain):
msg = htmlTermsOfService(self.server.baseDir, 'http',
msg = htmlTermsOfService(self.server.cssCache,
self.server.baseDir, 'http',
self.server.i2pDomain)
else:
msg = htmlTermsOfService(self.server.baseDir,
msg = htmlTermsOfService(self.server.cssCache,
self.server.baseDir,
self.server.httpPrefix,
self.server.domainFull)
msg = msg.encode('utf-8')
@ -9018,7 +9063,8 @@ class PubServer(BaseHTTPRequestHandler):
if not os.path.isfile(followingFilename):
self._404()
return
msg = htmlFollowingList(self.server.baseDir, followingFilename)
msg = htmlFollowingList(self.server.cssCache,
self.server.baseDir, followingFilename)
self._login_headers('text/html', len(msg), callingDomain)
self._write(msg.encode('utf-8'))
self._benchmarkGETtimings(GETstartTime, GETtimings,
@ -9033,17 +9079,20 @@ class PubServer(BaseHTTPRequestHandler):
if self.path.endswith('/about'):
if callingDomain.endswith('.onion'):
msg = \
htmlAbout(self.server.baseDir, 'http',
htmlAbout(self.server.cssCache,
self.server.baseDir, 'http',
self.server.onionDomain,
None)
elif callingDomain.endswith('.i2p'):
msg = \
htmlAbout(self.server.baseDir, 'http',
htmlAbout(self.server.cssCache,
self.server.baseDir, 'http',
self.server.i2pDomain,
None)
else:
msg = \
htmlAbout(self.server.baseDir,
htmlAbout(self.server.cssCache,
self.server.baseDir,
self.server.httpPrefix,
self.server.domainFull,
self.server.onionDomain)
@ -9393,7 +9442,8 @@ class PubServer(BaseHTTPRequestHandler):
not authorized and
not self.server.newsInstance)):
# request basic auth
msg = htmlLogin(self.server.translate,
msg = htmlLogin(self.server.cssCache,
self.server.translate,
self.server.baseDir).encode('utf-8')
self._login_headers('text/html', len(msg), callingDomain)
self._write(msg)
@ -9448,7 +9498,8 @@ class PubServer(BaseHTTPRequestHandler):
timelinePath = \
'/users/' + nickname + '/' + self.server.defaultTimeline
showPublishAsIcon = self.server.showPublishAsIcon
msg = htmlNewswireMobile(self.server.baseDir,
msg = htmlNewswireMobile(self.server.cssCache,
self.server.baseDir,
nickname,
self.server.domain,
self.server.domainFull,
@ -9473,7 +9524,8 @@ class PubServer(BaseHTTPRequestHandler):
return
timelinePath = \
'/users/' + nickname + '/' + self.server.defaultTimeline
msg = htmlLinksMobile(self.server.baseDir, nickname,
msg = htmlLinksMobile(self.server.cssCache,
self.server.baseDir, nickname,
self.server.domainFull,
self.server.httpPrefix,
self.server.translate,
@ -9541,7 +9593,8 @@ class PubServer(BaseHTTPRequestHandler):
if '?' in self.path:
self.path = self.path.split('?')[0]
# show the search screen
msg = htmlSearch(self.server.translate,
msg = htmlSearch(self.server.cssCache,
self.server.translate,
self.server.baseDir, self.path,
self.server.domain).encode('utf-8')
self._set_headers('text/html', len(msg), cookie, callingDomain)
@ -9560,7 +9613,8 @@ class PubServer(BaseHTTPRequestHandler):
if htmlGET and '/users/' in self.path:
if '/calendar' in self.path:
# show the calendar screen
msg = htmlCalendar(self.server.translate,
msg = htmlCalendar(self.server.cssCache,
self.server.translate,
self.server.baseDir, self.path,
self.server.httpPrefix,
self.server.domainFull).encode('utf-8')
@ -9600,7 +9654,8 @@ class PubServer(BaseHTTPRequestHandler):
if htmlGET and '/users/' in self.path:
if self.path.endswith('/searchemoji'):
# show the search screen
msg = htmlSearchEmojiTextEntry(self.server.translate,
msg = htmlSearchEmojiTextEntry(self.server.cssCache,
self.server.translate,
self.server.baseDir,
self.path).encode('utf-8')
self._set_headers('text/html', len(msg),
@ -12344,6 +12399,9 @@ def runDaemon(publishButtonAtTop: bool,
# contains threads used to send posts to followers
httpd.followersThreads = []
# cache to store css files
httpd.cssCache = {}
if not os.path.isdir(baseDir + '/accounts/inbox@' + domain):
print('Creating shared inbox: inbox@' + domain)
createSharedInbox(baseDir, 'inbox', domain, port, httpPrefix)

View File

@ -1053,6 +1053,35 @@ def fileLastModified(filename: str) -> str:
return modifiedTime.strftime("%Y-%m-%dT%H:%M:%SZ")
def getCSS(baseDir: str, cssFilename: str, cssCache: {}) -> str:
"""Retrieves the css for a given file, or from a cache
"""
# does the css file exist?
if not os.path.isfile(cssFilename):
return None
lastModified = fileLastModified(cssFilename)
# has this already been loaded into the cache?
if cssCache.get(cssFilename):
if cssCache[cssFilename][0] == lastModified:
# file hasn't changed, so return the version in the cache
return cssCache[cssFilename][1]
with open(cssFilename, 'r') as fpCSS:
css = fpCSS.read()
if cssCache.get(cssFilename):
# alter the cache contents
cssCache[cssFilename][0] = lastModified
cssCache[cssFilename][1] = css
else:
# add entry to the cache
cssCache[cssFilename] = [lastModified, css]
return css
return None
def daysInMonth(year: int, monthNumber: int) -> int:
"""Returns the number of days in the month
"""

View File

@ -25,6 +25,7 @@ from ssb import getSSBAddress
from tox import getToxAddress
from matrix import getMatrixAddress
from donate import getDonationUrl
from utils import getCSS
from utils import isSystemAccount
from utils import removeIdEnding
from utils import getProtocolPrefixes
@ -327,7 +328,8 @@ def getPersonAvatarUrl(baseDir: str, personUrl: str, personCache: {},
return None
def htmlFollowingList(baseDir: str, followingFilename: str) -> str:
def htmlFollowingList(cssCache: {}, baseDir: str,
followingFilename: str) -> str:
"""Returns a list of handles being followed
"""
with open(followingFilename, 'r') as followingFile:
@ -338,8 +340,9 @@ def htmlFollowingList(baseDir: str, followingFilename: str) -> str:
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
profileCSS = cssFile.read()
profileCSS = getCSS(baseDir, cssFilename, cssCache)
if profileCSS:
followingListHtml = htmlHeader(cssFilename, profileCSS)
for followingAddress in followingList:
if followingAddress:
@ -391,7 +394,8 @@ def htmlFollowingDataList(baseDir: str, nickname: str,
return listStr
def htmlSearchEmoji(translate: {}, baseDir: str, httpPrefix: str,
def htmlSearchEmoji(cssCache: {}, translate: {},
baseDir: str, httpPrefix: str,
searchStr: str) -> str:
"""Search results for emoji
"""
@ -405,8 +409,9 @@ def htmlSearchEmoji(translate: {}, baseDir: str, httpPrefix: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
emojiCSS = cssFile.read()
emojiCSS = getCSS(baseDir, cssFilename, cssCache)
if emojiCSS:
if httpPrefix != 'https':
emojiCSS = emojiCSS.replace('https://',
httpPrefix + '://')
@ -465,7 +470,7 @@ def getIconsDir(baseDir: str) -> str:
return iconsDir
def htmlSearchSharedItems(translate: {},
def htmlSearchSharedItems(cssCache: {}, translate: {},
baseDir: str, searchStr: str,
pageNumber: int,
resultsPerPage: int,
@ -485,8 +490,8 @@ def htmlSearchSharedItems(translate: {},
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
sharedItemsCSS = cssFile.read()
sharedItemsCSS = getCSS(baseDir, cssFilename, cssCache)
if sharedItemsCSS:
if httpPrefix != 'https':
sharedItemsCSS = \
sharedItemsCSS.replace('https://',
@ -640,7 +645,8 @@ def htmlSearchSharedItems(translate: {},
return sharedItemsForm
def htmlModerationInfo(translate: {}, baseDir: str, httpPrefix: str) -> str:
def htmlModerationInfo(cssCache: {}, translate: {},
baseDir: str, httpPrefix: str) -> str:
msgStr1 = \
'These are globally blocked for all accounts on this instance'
msgStr2 = \
@ -649,8 +655,9 @@ def htmlModerationInfo(translate: {}, baseDir: str, httpPrefix: str) -> str:
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
infoCSS = cssFile.read()
infoCSS = getCSS(baseDir, cssFilename, cssCache)
if infoCSS:
if httpPrefix != 'https':
infoCSS = infoCSS.replace('https://',
httpPrefix + '://')
@ -704,7 +711,8 @@ def htmlModerationInfo(translate: {}, baseDir: str, httpPrefix: str) -> str:
return infoForm
def htmlHashtagSearch(nickname: str, domain: str, port: int,
def htmlHashtagSearch(cssCache: {},
nickname: str, domain: str, port: int,
recentPostsCache: {}, maxRecentPosts: int,
translate: {},
baseDir: str, hashtag: str, pageNumber: int,
@ -743,8 +751,9 @@ def htmlHashtagSearch(nickname: str, domain: str, port: int,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
hashtagSearchCSS = cssFile.read()
hashtagSearchCSS = getCSS(baseDir, cssFilename, cssCache)
if hashtagSearchCSS:
if httpPrefix != 'https':
hashtagSearchCSS = \
hashtagSearchCSS.replace('https://',
@ -979,7 +988,7 @@ def rssHashtagSearch(nickname: str, domain: str, port: int,
return hashtagFeed + rss2TagFooter()
def htmlSkillsSearch(translate: {}, baseDir: str,
def htmlSkillsSearch(cssCache: {}, translate: {}, baseDir: str,
httpPrefix: str,
skillsearch: str, instanceOnly: bool,
postsPerPage: int) -> str:
@ -1067,8 +1076,9 @@ def htmlSkillsSearch(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
skillSearchCSS = cssFile.read()
skillSearchCSS = getCSS(baseDir, cssFilename, cssCache)
if skillSearchCSS:
if httpPrefix != 'https':
skillSearchCSS = \
skillSearchCSS.replace('https://',
@ -1107,7 +1117,7 @@ def htmlSkillsSearch(translate: {}, baseDir: str,
return skillSearchForm
def htmlHistorySearch(translate: {}, baseDir: str,
def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
httpPrefix: str,
nickname: str, domain: str,
historysearch: str,
@ -1135,8 +1145,9 @@ def htmlHistorySearch(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
historySearchCSS = cssFile.read()
historySearchCSS = getCSS(baseDir, cssFilename, cssCache)
if historySearchCSS:
if httpPrefix != 'https':
historySearchCSS = \
historySearchCSS.replace('https://',
@ -1214,7 +1225,7 @@ def scheduledPostsExist(baseDir: str, nickname: str, domain: str) -> bool:
return False
def htmlEditLinks(translate: {}, baseDir: str, path: str,
def htmlEditLinks(cssCache: {}, translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str) -> str:
"""Shows the edit links screen
"""
@ -1235,8 +1246,9 @@ def htmlEditLinks(translate: {}, baseDir: str, path: str,
cssFilename = baseDir + '/epicyon-links.css'
if os.path.isfile(baseDir + '/links.css'):
cssFilename = baseDir + '/links.css'
with open(cssFilename, 'r') as cssFile:
editCSS = cssFile.read()
editCSS = getCSS(baseDir, cssFilename, cssCache)
if editCSS:
if httpPrefix != 'https':
editCSS = \
editCSS.replace('https://', httpPrefix + '://')
@ -1282,7 +1294,7 @@ def htmlEditLinks(translate: {}, baseDir: str, path: str,
return editLinksForm
def htmlEditNewswire(translate: {}, baseDir: str, path: str,
def htmlEditNewswire(cssCache: {}, translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str) -> str:
"""Shows the edit newswire screen
"""
@ -1303,8 +1315,9 @@ def htmlEditNewswire(translate: {}, baseDir: str, path: str,
cssFilename = baseDir + '/epicyon-links.css'
if os.path.isfile(baseDir + '/links.css'):
cssFilename = baseDir + '/links.css'
with open(cssFilename, 'r') as cssFile:
editCSS = cssFile.read()
editCSS = getCSS(baseDir, cssFilename, cssCache)
if editCSS:
if httpPrefix != 'https':
editCSS = \
editCSS.replace('https://', httpPrefix + '://')
@ -1388,7 +1401,7 @@ def htmlEditNewswire(translate: {}, baseDir: str, path: str,
return editNewswireForm
def htmlEditNewsPost(translate: {}, baseDir: str, path: str,
def htmlEditNewsPost(cssCache: {}, translate: {}, baseDir: str, path: str,
domain: str, port: int,
httpPrefix: str, postUrl: str) -> str:
"""Edits a news post
@ -1416,8 +1429,9 @@ def htmlEditNewsPost(translate: {}, baseDir: str, path: str,
cssFilename = baseDir + '/epicyon-links.css'
if os.path.isfile(baseDir + '/links.css'):
cssFilename = baseDir + '/links.css'
with open(cssFilename, 'r') as cssFile:
editCSS = cssFile.read()
editCSS = getCSS(baseDir, cssFilename, cssCache)
if editCSS:
if httpPrefix != 'https':
editCSS = \
editCSS.replace('https://', httpPrefix + '://')
@ -1465,7 +1479,7 @@ def htmlEditNewsPost(translate: {}, baseDir: str, path: str,
return editNewsPostForm
def htmlEditProfile(translate: {}, baseDir: str, path: str,
def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str) -> str:
"""Shows the edit profile screen
"""
@ -1652,8 +1666,9 @@ def htmlEditProfile(translate: {}, baseDir: str, path: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
editProfileCSS = cssFile.read()
editProfileCSS = getCSS(baseDir, cssFilename, cssCache)
if editProfileCSS:
if httpPrefix != 'https':
editProfileCSS = \
editProfileCSS.replace('https://', httpPrefix + '://')
@ -2095,7 +2110,8 @@ def htmlGetLoginCredentials(loginParams: str,
return nickname, password, register
def htmlLogin(translate: {}, baseDir: str, autocomplete=True) -> str:
def htmlLogin(cssCache: {}, translate: {},
baseDir: str, autocomplete=True) -> str:
"""Shows the login screen
"""
accounts = noOfAccounts(baseDir)
@ -2150,8 +2166,11 @@ def htmlLogin(translate: {}, baseDir: str, autocomplete=True) -> str:
cssFilename = baseDir + '/epicyon-login.css'
if os.path.isfile(baseDir + '/login.css'):
cssFilename = baseDir + '/login.css'
with open(cssFilename, 'r') as cssFile:
loginCSS = cssFile.read()
loginCSS = getCSS(baseDir, cssFilename, cssCache)
if not loginCSS:
print('ERROR: login css file missing ' + cssFilename)
return None
# show the register button
registerButtonStr = ''
@ -2218,7 +2237,8 @@ def htmlLogin(translate: {}, baseDir: str, autocomplete=True) -> str:
return loginForm
def htmlTermsOfService(baseDir: str, httpPrefix: str, domainFull: str) -> str:
def htmlTermsOfService(cssCache: {}, baseDir: str,
httpPrefix: str, domainFull: str) -> str:
"""Show the terms of service screen
"""
adminNickname = getConfigParam(baseDir, 'admin')
@ -2240,8 +2260,9 @@ def htmlTermsOfService(baseDir: str, httpPrefix: str, domainFull: str) -> str:
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
termsCSS = cssFile.read()
termsCSS = getCSS(baseDir, cssFilename, cssCache)
if termsCSS:
if httpPrefix != 'https':
termsCSS = termsCSS.replace('https://', httpPrefix+'://')
@ -2259,7 +2280,7 @@ def htmlTermsOfService(baseDir: str, httpPrefix: str, domainFull: str) -> str:
return TOSForm
def htmlAbout(baseDir: str, httpPrefix: str,
def htmlAbout(cssCache: {}, baseDir: str, httpPrefix: str,
domainFull: str, onionDomain: str) -> str:
"""Show the about screen
"""
@ -2282,8 +2303,9 @@ def htmlAbout(baseDir: str, httpPrefix: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
aboutCSS = cssFile.read()
aboutCSS = getCSS(baseDir, cssFilename, cssCache)
if aboutCSS:
if httpPrefix != 'http':
aboutCSS = aboutCSS.replace('https://',
httpPrefix + '://')
@ -2306,15 +2328,16 @@ def htmlAbout(baseDir: str, httpPrefix: str,
return aboutForm
def htmlHashtagBlocked(baseDir: str, translate: {}) -> str:
def htmlHashtagBlocked(cssCache: {}, baseDir: str, translate: {}) -> str:
"""Show the screen for a blocked hashtag
"""
blockedHashtagForm = ''
cssFilename = baseDir + '/epicyon-suspended.css'
if os.path.isfile(baseDir + '/suspended.css'):
cssFilename = baseDir + '/suspended.css'
with open(cssFilename, 'r') as cssFile:
blockedHashtagCSS = cssFile.read()
blockedHashtagCSS = getCSS(baseDir, cssFilename, cssCache)
if blockedHashtagCSS:
blockedHashtagForm = htmlHeader(cssFilename, blockedHashtagCSS)
blockedHashtagForm += '<div><center>\n'
blockedHashtagForm += \
@ -2328,15 +2351,16 @@ def htmlHashtagBlocked(baseDir: str, translate: {}) -> str:
return blockedHashtagForm
def htmlSuspended(baseDir: str) -> str:
def htmlSuspended(cssCache: {}, baseDir: str) -> str:
"""Show the screen for suspended accounts
"""
suspendedForm = ''
cssFilename = baseDir + '/epicyon-suspended.css'
if os.path.isfile(baseDir + '/suspended.css'):
cssFilename = baseDir + '/suspended.css'
with open(cssFilename, 'r') as cssFile:
suspendedCSS = cssFile.read()
suspendedCSS = getCSS(baseDir, cssFilename, cssCache)
if suspendedCSS:
suspendedForm = htmlHeader(cssFilename, suspendedCSS)
suspendedForm += '<div><center>\n'
suspendedForm += ' <p class="screentitle">Account Suspended</p>\n'
@ -2346,7 +2370,7 @@ def htmlSuspended(baseDir: str) -> str:
return suspendedForm
def htmlNewPost(mediaInstance: bool, translate: {},
def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
baseDir: str, httpPrefix: str,
path: str, inReplyTo: str,
mentions: [],
@ -2433,8 +2457,9 @@ def htmlNewPost(mediaInstance: bool, translate: {},
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
newPostCSS = cssFile.read()
newPostCSS = getCSS(baseDir, cssFilename, cssCache)
if newPostCSS:
if httpPrefix != 'https':
newPostCSS = newPostCSS.replace('https://',
httpPrefix + '://')
@ -3273,7 +3298,8 @@ def htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
return timelineStr
def htmlProfile(iconsAsButtons: bool, defaultTimeline: str,
def htmlProfile(cssCache: {}, iconsAsButtons: bool,
defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, projectVersion: str,
baseDir: str, httpPrefix: str, authorized: bool,
@ -3572,10 +3598,12 @@ def htmlProfile(iconsAsButtons: bool, defaultTimeline: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
profileStyle = \
cssFile.read().replace('image.png',
profileJson['image']['url'])
profileStyle.replace('image.png',
profileJson['image']['url'])
if isSystemAccount(nickname):
bannerFile, bannerFilename = \
getBannerFile(baseDir, nickname, domain)
@ -5854,7 +5882,8 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
return htmlStr
def htmlLinksMobile(baseDir: str, nickname: str, domainFull: str,
def htmlLinksMobile(cssCache: {}, baseDir: str,
nickname: str, domainFull: str,
httpPrefix: str, translate,
timelinePath: str) -> str:
"""Show the left column links within mobile view
@ -5866,11 +5895,8 @@ def htmlLinksMobile(baseDir: str, nickname: str, domainFull: str,
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
profileStyle = None
with open(cssFilename, 'r') as cssFile:
# load css
profileStyle = \
cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
# replace any https within the css with whatever prefix is needed
if httpPrefix != 'https':
profileStyle = \
@ -5894,7 +5920,7 @@ def htmlLinksMobile(baseDir: str, nickname: str, domainFull: str,
return htmlStr
def htmlNewswireMobile(baseDir: str, nickname: str,
def htmlNewswireMobile(cssCache: {}, baseDir: str, nickname: str,
domain: str, domainFull: str,
httpPrefix: str, translate: {},
newswire: {},
@ -5910,11 +5936,8 @@ def htmlNewswireMobile(baseDir: str, nickname: str,
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
profileStyle = None
with open(cssFilename, 'r') as cssFile:
# load css
profileStyle = \
cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
# replace any https within the css with whatever prefix is needed
if httpPrefix != 'https':
profileStyle = \
@ -6273,7 +6296,7 @@ def getTimelineButtonHeader(defaultTimeline: str,
return tlStr
def htmlTimeline(defaultTimeline: str,
def htmlTimeline(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int,
itemsPerPage: int, session, baseDir: str,
@ -6360,16 +6383,20 @@ def htmlTimeline(defaultTimeline: str,
if timeDiff > 100:
print('TIMELINE TIMING ' + boxName + ' 1 = ' + str(timeDiff))
with open(cssFilename, 'r') as cssFile:
# load css
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if not profileStyle:
print('ERROR: css file not found ' + cssFilename)
return None
# load css
profileStyle = \
profileStyle.replace('banner.png',
'/users/' + nickname + '/' + bannerFile)
# replace any https within the css with whatever prefix is needed
if httpPrefix != 'https':
profileStyle = \
cssFile.read().replace('banner.png',
'/users/' + nickname + '/' + bannerFile)
# replace any https within the css with whatever prefix is needed
if httpPrefix != 'https':
profileStyle = \
profileStyle.replace('https://',
httpPrefix + '://')
profileStyle.replace('https://',
httpPrefix + '://')
# is the user a moderator?
if not moderator:
@ -6856,7 +6883,7 @@ def htmlTimeline(defaultTimeline: str,
return tlStr
def htmlShares(defaultTimeline: str,
def htmlShares(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -6876,7 +6903,8 @@ def htmlShares(defaultTimeline: str,
manuallyApproveFollowers = \
followerApprovalActive(baseDir, nickname, domain)
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, None,
@ -6890,7 +6918,7 @@ def htmlShares(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInbox(defaultTimeline: str,
def htmlInbox(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -6910,7 +6938,8 @@ def htmlInbox(defaultTimeline: str,
manuallyApproveFollowers = \
followerApprovalActive(baseDir, nickname, domain)
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson,
@ -6924,7 +6953,7 @@ def htmlInbox(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlBookmarks(defaultTimeline: str,
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -6944,7 +6973,8 @@ def htmlBookmarks(defaultTimeline: str,
manuallyApproveFollowers = \
followerApprovalActive(baseDir, nickname, domain)
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, bookmarksJson,
@ -6958,7 +6988,7 @@ def htmlBookmarks(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlEvents(defaultTimeline: str,
def htmlEvents(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -6978,7 +7008,8 @@ def htmlEvents(defaultTimeline: str,
manuallyApproveFollowers = \
followerApprovalActive(baseDir, nickname, domain)
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, bookmarksJson,
@ -6992,7 +7023,7 @@ def htmlEvents(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInboxDMs(defaultTimeline: str,
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7009,7 +7040,8 @@ def htmlInboxDMs(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the DM timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'dm', allowDeletion,
@ -7021,7 +7053,7 @@ def htmlInboxDMs(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInboxReplies(defaultTimeline: str,
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7038,7 +7070,8 @@ def htmlInboxReplies(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the replies timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'tlreplies',
@ -7051,7 +7084,7 @@ def htmlInboxReplies(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInboxMedia(defaultTimeline: str,
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7068,7 +7101,8 @@ def htmlInboxMedia(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the media timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'tlmedia',
@ -7081,7 +7115,7 @@ def htmlInboxMedia(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInboxBlogs(defaultTimeline: str,
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7098,7 +7132,8 @@ def htmlInboxBlogs(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the blogs timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'tlblogs',
@ -7111,7 +7146,7 @@ def htmlInboxBlogs(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlInboxNews(defaultTimeline: str,
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7128,7 +7163,8 @@ def htmlInboxNews(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the news timeline as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'tlnews',
@ -7141,7 +7177,7 @@ def htmlInboxNews(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlModeration(defaultTimeline: str,
def htmlModeration(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7158,7 +7194,8 @@ def htmlModeration(defaultTimeline: str,
publishButtonAtTop: bool) -> str:
"""Show the moderation feed as html
"""
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, inboxJson, 'moderation',
@ -7169,7 +7206,7 @@ def htmlModeration(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlOutbox(defaultTimeline: str,
def htmlOutbox(cssCache: {}, defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, pageNumber: int, itemsPerPage: int,
session, baseDir: str, wfRequest: {}, personCache: {},
@ -7188,7 +7225,8 @@ def htmlOutbox(defaultTimeline: str,
"""
manuallyApproveFollowers = \
followerApprovalActive(baseDir, nickname, domain)
return htmlTimeline(defaultTimeline, recentPostsCache, maxRecentPosts,
return htmlTimeline(cssCache, defaultTimeline,
recentPostsCache, maxRecentPosts,
translate, pageNumber,
itemsPerPage, session, baseDir, wfRequest, personCache,
nickname, domain, port, outboxJson, 'outbox',
@ -7200,7 +7238,8 @@ def htmlOutbox(defaultTimeline: str,
iconsAsButtons, rssIconAtTop, publishButtonAtTop)
def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int,
def htmlIndividualPost(cssCache: {},
recentPostsCache: {}, maxRecentPosts: int,
translate: {},
baseDir: str, session, wfRequest: {}, personCache: {},
nickname: str, domain: str, port: int, authorized: bool,
@ -7311,15 +7350,17 @@ def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
postsCSS = cssFile.read()
postsCSS = getCSS(baseDir, cssFilename, cssCache)
if postsCSS:
if httpPrefix != 'https':
postsCSS = postsCSS.replace('https://',
httpPrefix + '://')
return htmlHeader(cssFilename, postsCSS) + postStr + htmlFooter()
def htmlPostReplies(recentPostsCache: {}, maxRecentPosts: int,
def htmlPostReplies(cssCache: {},
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, baseDir: str,
session, wfRequest: {}, personCache: {},
nickname: str, domain: str, port: int, repliesJson: {},
@ -7347,15 +7388,16 @@ def htmlPostReplies(recentPostsCache: {}, maxRecentPosts: int,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
postsCSS = cssFile.read()
postsCSS = getCSS(baseDir, cssFilename, cssCache)
if postsCSS:
if httpPrefix != 'https':
postsCSS = postsCSS.replace('https://',
httpPrefix + '://')
return htmlHeader(cssFilename, postsCSS) + repliesStr + htmlFooter()
def htmlRemoveSharedItem(translate: {}, baseDir: str,
def htmlRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str,
actor: str, shareName: str,
callingDomain: str) -> str:
"""Shows a screen asking to confirm the removal of a shared item
@ -7392,8 +7434,8 @@ def htmlRemoveSharedItem(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-follow.css'
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
sharesStr = htmlHeader(cssFilename, profileStyle)
sharesStr += '<div class="follow">\n'
sharesStr += ' <div class="followAvatar">\n'
@ -7424,7 +7466,8 @@ def htmlRemoveSharedItem(translate: {}, baseDir: str,
return sharesStr
def htmlDeletePost(recentPostsCache: {}, maxRecentPosts: int,
def htmlDeletePost(cssCache: {},
recentPostsCache: {}, maxRecentPosts: int,
translate, pageNumber: int,
session, baseDir: str, messageId: str,
httpPrefix: str, projectVersion: str,
@ -7462,8 +7505,9 @@ def htmlDeletePost(recentPostsCache: {}, maxRecentPosts: int,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
if httpPrefix != 'https':
profileStyle = profileStyle.replace('https://',
httpPrefix + '://')
@ -7504,7 +7548,7 @@ def htmlDeletePost(recentPostsCache: {}, maxRecentPosts: int,
return deletePostStr
def htmlCalendarDeleteConfirm(translate: {}, baseDir: str,
def htmlCalendarDeleteConfirm(cssCache: {}, translate: {}, baseDir: str,
path: str, httpPrefix: str,
domainFull: str, postId: str, postTime: str,
year: int, monthNumber: int,
@ -7533,8 +7577,9 @@ def htmlCalendarDeleteConfirm(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
if httpPrefix != 'https':
profileStyle = profileStyle.replace('https://',
httpPrefix + '://')
@ -7575,7 +7620,7 @@ def htmlCalendarDeleteConfirm(translate: {}, baseDir: str,
return deletePostStr
def htmlFollowConfirm(translate: {}, baseDir: str,
def htmlFollowConfirm(cssCache: {}, translate: {}, baseDir: str,
originPathStr: str,
followActor: str,
followProfileUrl: str) -> str:
@ -7591,8 +7636,8 @@ def htmlFollowConfirm(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-follow.css'
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
followStr = htmlHeader(cssFilename, profileStyle)
followStr += '<div class="follow">\n'
followStr += ' <div class="followAvatar">\n'
@ -7620,7 +7665,7 @@ def htmlFollowConfirm(translate: {}, baseDir: str,
return followStr
def htmlUnfollowConfirm(translate: {}, baseDir: str,
def htmlUnfollowConfirm(cssCache: {}, translate: {}, baseDir: str,
originPathStr: str,
followActor: str,
followProfileUrl: str) -> str:
@ -7636,8 +7681,9 @@ def htmlUnfollowConfirm(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-follow.css'
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
followStr = htmlHeader(cssFilename, profileStyle)
followStr += '<div class="follow">\n'
followStr += ' <div class="followAvatar">\n'
@ -7666,7 +7712,7 @@ def htmlUnfollowConfirm(translate: {}, baseDir: str,
return followStr
def htmlPersonOptions(translate: {}, baseDir: str,
def htmlPersonOptions(cssCache: {}, translate: {}, baseDir: str,
domain: str, domainFull: str,
originPathStr: str,
optionsActor: str,
@ -7726,8 +7772,9 @@ def htmlPersonOptions(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-options.css'
if os.path.isfile(baseDir + '/options.css'):
cssFilename = baseDir + '/options.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
profileStyle = \
profileStyle.replace('--follow-text-entry-width: 90%;',
'--follow-text-entry-width: 20%;')
@ -7888,7 +7935,7 @@ def htmlPersonOptions(translate: {}, baseDir: str,
return optionsStr
def htmlUnblockConfirm(translate: {}, baseDir: str,
def htmlUnblockConfirm(cssCache: {}, translate: {}, baseDir: str,
originPathStr: str,
blockActor: str,
blockProfileUrl: str) -> str:
@ -7904,8 +7951,9 @@ def htmlUnblockConfirm(translate: {}, baseDir: str,
cssFilename = baseDir + '/epicyon-follow.css'
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
blockStr = htmlHeader(cssFilename, profileStyle)
blockStr += '<div class="block">\n'
blockStr += ' <div class="blockAvatar">\n'
@ -7933,7 +7981,7 @@ def htmlUnblockConfirm(translate: {}, baseDir: str,
return blockStr
def htmlSearchEmojiTextEntry(translate: {},
def htmlSearchEmojiTextEntry(cssCache: {}, translate: {},
baseDir: str, path: str) -> str:
"""Search for an emoji by name
"""
@ -7954,8 +8002,9 @@ def htmlSearchEmojiTextEntry(translate: {},
cssFilename = baseDir + '/epicyon-follow.css'
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
emojiStr = htmlHeader(cssFilename, profileStyle)
emojiStr += '<div class="follow">\n'
emojiStr += ' <div class="followAvatar">\n'
@ -7987,7 +8036,7 @@ def weekDayOfMonthStart(monthNumber: int, year: int) -> int:
return int(firstDayOfMonth.strftime("%w")) + 1
def htmlCalendarDay(translate: {},
def htmlCalendarDay(cssCache: {}, translate: {},
baseDir: str, path: str,
year: int, monthNumber: int, dayNumber: int,
nickname: str, domain: str, dayEvents: [],
@ -8002,8 +8051,8 @@ def htmlCalendarDay(translate: {},
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
with open(cssFilename, 'r') as cssFile:
calendarStyle = cssFile.read()
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
@ -8095,7 +8144,7 @@ def htmlCalendarDay(translate: {},
return calendarStr
def htmlCalendar(translate: {},
def htmlCalendar(cssCache: {}, translate: {},
baseDir: str, path: str,
httpPrefix: str, domainFull: str) -> str:
"""Show the calendar for a person
@ -8154,7 +8203,7 @@ def htmlCalendar(translate: {},
if events:
if events.get(str(dayNumber)):
dayEvents = events[str(dayNumber)]
return htmlCalendarDay(translate, baseDir, path,
return htmlCalendarDay(cssCache, translate, baseDir, path,
year, monthNumber, dayNumber,
nickname, domain, dayEvents,
monthName, actor)
@ -8188,8 +8237,8 @@ def htmlCalendar(translate: {},
cssFilename = baseDir + '/epicyon-calendar.css'
if os.path.isfile(baseDir + '/calendar.css'):
cssFilename = baseDir + '/calendar.css'
with open(cssFilename, 'r') as cssFile:
calendarStyle = cssFile.read()
calendarStyle = getCSS(baseDir, cssFilename, cssCache)
calActor = actor
if '/users/' in actor:
@ -8393,7 +8442,7 @@ def htmlHashTagSwarm(baseDir: str, actor: str) -> str:
return tagSwarmHtml
def htmlSearch(translate: {},
def htmlSearch(cssCache: {}, translate: {},
baseDir: str, path: str, domain: str) -> str:
"""Search called from the timeline icon
"""
@ -8408,8 +8457,9 @@ def htmlSearch(translate: {},
cssFilename = baseDir + '/epicyon-search.css'
if os.path.isfile(baseDir + '/search.css'):
cssFilename = baseDir + '/search.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = cssFile.read()
profileStyle = getCSS(baseDir, cssFilename, cssCache)
followStr = htmlHeader(cssFilename, profileStyle)
# show a banner above the search box
@ -8458,7 +8508,8 @@ def htmlSearch(translate: {},
return followStr
def htmlProfileAfterSearch(recentPostsCache: {}, maxRecentPosts: int,
def htmlProfileAfterSearch(cssCache: {},
recentPostsCache: {}, maxRecentPosts: int,
translate: {},
baseDir: str, path: str, httpPrefix: str,
nickname: str, domain: str, port: int,
@ -8517,7 +8568,9 @@ def htmlProfileAfterSearch(recentPostsCache: {}, maxRecentPosts: int,
cssFilename = baseDir + '/epicyon-profile.css'
if os.path.isfile(baseDir + '/epicyon.css'):
cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
profileStyle = getCSS(baseDir, cssFilename, cssCache)
if profileStyle:
wf = \
webfingerHandle(session,
searchNickname + '@' + searchDomainFull,
@ -8592,8 +8645,8 @@ def htmlProfileAfterSearch(recentPostsCache: {}, maxRecentPosts: int,
if profileJson['image'].get('url'):
profileBackgroundImage = profileJson['image']['url']
profileStyle = cssFile.read().replace('image.png',
profileBackgroundImage)
profileStyle = profileStyle.replace('image.png',
profileBackgroundImage)
if httpPrefix != 'https':
profileStyle = profileStyle.replace('https://',
httpPrefix + '://')