From cd64d747d1d9077114664011833be3ec8387167a Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 29 Oct 2020 12:48:58 +0000 Subject: [PATCH] CSS cache --- daemon.py | 186 +++++++++++++++++--------- utils.py | 29 +++++ webinterface.py | 339 ++++++++++++++++++++++++++++-------------------- 3 files changed, 347 insertions(+), 207 deletions(-) diff --git a/daemon.py b/daemon.py index 74337cc44..7e9c3a606 100644 --- a/daemon.py +++ b/daemon.py @@ -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) diff --git a/utils.py b/utils.py index f23b2ed25..08d21f159 100644 --- a/utils.py +++ b/utils.py @@ -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 """ diff --git a/webinterface.py b/webinterface.py index 9f11436b4..14aeec907 100644 --- a/webinterface.py +++ b/webinterface.py @@ -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 += '
\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 += '
\n' suspendedForm += '

Account Suspended

\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 += '