Shorter cached favicon filename

main
Bob Mottram 2021-12-17 12:01:54 +00:00
parent adedd62251
commit c6516b55c3
4 changed files with 63 additions and 36 deletions

View File

@ -7412,12 +7412,12 @@ class PubServer(BaseHTTPRequestHandler):
"""Shows a favicon image obtained from the cache """Shows a favicon image obtained from the cache
""" """
favFile = path.replace('/favicons/', '') favFile = path.replace('/favicons/', '')
mediaFilename = baseDir + urllib.parse.unquote_plus(path) favFilename = baseDir + urllib.parse.unquote_plus(path)
print('showCachedFavicon: ' + mediaFilename) print('showCachedFavicon: ' + favFilename)
if self.server.faviconsCache.get(favFile): if self.server.faviconsCache.get(favFile):
mediaBinary = self.server.faviconsCache[favFile] mediaBinary = self.server.faviconsCache[favFile]
mimeType = mediaFileMimeType(mediaFilename) mimeType = mediaFileMimeType(favFilename)
self._set_headers_etag(mediaFilename, self._set_headers_etag(favFilename,
mimeType, mimeType,
mediaBinary, None, mediaBinary, None,
refererDomain, refererDomain,
@ -7427,25 +7427,22 @@ class PubServer(BaseHTTPRequestHandler):
'_GET', '_showCachedFavicon2', '_GET', '_showCachedFavicon2',
self.server.debug) self.server.debug)
return return
if not os.path.isfile(mediaFilename): if not os.path.isfile(favFilename):
originalMediaFilename = mediaFilename self._404()
mediaFilename = originalMediaFilename.replace('.ico', '.png') return
if not os.path.isfile(mediaFilename): if self._etag_exists(favFilename):
self._404()
return
if self._etag_exists(mediaFilename):
# The file has not changed # The file has not changed
self._304() self._304()
return return
mediaBinary = None mediaBinary = None
try: try:
with open(mediaFilename, 'rb') as avFile: with open(favFilename, 'rb') as avFile:
mediaBinary = avFile.read() mediaBinary = avFile.read()
except OSError: except OSError:
print('EX: unable to read cached favicon ' + mediaFilename) print('EX: unable to read cached favicon ' + favFilename)
if mediaBinary: if mediaBinary:
mimeType = mediaFileMimeType(mediaFilename) mimeType = mediaFileMimeType(favFilename)
self._set_headers_etag(mediaFilename, self._set_headers_etag(favFilename,
mimeType, mimeType,
mediaBinary, None, mediaBinary, None,
refererDomain, refererDomain,

View File

@ -18,6 +18,7 @@ from datetime import timezone
from collections import OrderedDict from collections import OrderedDict
from utils import validPostDate from utils import validPostDate
from categories import setHashtagCategory from categories import setHashtagCategory
from utils import getFavFilenameFromUrl
from utils import getBaseContentFromPost from utils import getBaseContentFromPost
from utils import hasObjectDict from utils import hasObjectDict
from utils import firstParagraphFromString from utils import firstParagraphFromString
@ -155,23 +156,35 @@ def _downloadNewswireFeedFavicon(session, baseDir: str,
downloadImageAnyMimeType(session, favUrl, timeoutSec, debug) downloadImageAnyMimeType(session, favUrl, timeoutSec, debug)
if not imageData or not mimeType: if not imageData or not mimeType:
return False return False
if 'image/png' in mimeType:
favUrl = favUrl.replace('.ico', '.png') # update the favicon url
elif 'image/webp' in mimeType: extensionsToMime = {
favUrl = favUrl.replace('.ico', '.webp') 'ico': 'x-icon',
elif 'image/gif' in mimeType: 'png': 'png',
favUrl = favUrl.replace('.ico', '.gif') 'jpg': 'jpeg',
'gif': 'gif',
'avif': 'avif',
'svg': 'svg+xml',
'webp': 'webp'
}
for ext, mimeExt in extensionsToMime.items():
if 'image/' + mimeExt in mimeType:
favUrl = favUrl.replace('.ico', '.' + mimeExt)
break
# create cached favicons directory if needed
if not os.path.isdir(baseDir + '/favicons'): if not os.path.isdir(baseDir + '/favicons'):
os.mkdir(baseDir + '/favicons') os.mkdir(baseDir + '/favicons')
linkFilename = favUrl.replace('/', '-')
imageFilename = baseDir + '/favicons/' + linkFilename # save to the cache
if os.path.isfile(imageFilename): favFilename = getFavFilenameFromUrl(baseDir, favUrl)
if os.path.isfile(favFilename):
return True return True
try: try:
with open(imageFilename, 'wb+') as fp: with open(favFilename, 'wb+') as fp:
fp.write(imageData) fp.write(imageData)
except OSError: except OSError:
print('EX: failed writing favicon ' + favUrl) print('EX: failed writing favicon ' + favFilename)
return False return False
return True return True

View File

@ -346,7 +346,7 @@ def getAudioExtensions() -> []:
def getImageExtensions() -> []: def getImageExtensions() -> []:
"""Returns a list of the possible image file extensions """Returns a list of the possible image file extensions
""" """
return ('png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg') return ('png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg', 'ico')
def getImageMimeType(imageFilename: str) -> str: def getImageMimeType(imageFilename: str) -> str:
@ -358,7 +358,8 @@ def getImageMimeType(imageFilename: str) -> str:
'gif': 'gif', 'gif': 'gif',
'avif': 'avif', 'avif': 'avif',
'svg': 'svg+xml', 'svg': 'svg+xml',
'webp': 'webp' 'webp': 'webp',
'ico': 'x-icon'
} }
for ext, mimeExt in extensionsToMime.items(): for ext, mimeExt in extensionsToMime.items():
if imageFilename.endswith('.' + ext): if imageFilename.endswith('.' + ext):
@ -375,7 +376,8 @@ def getImageExtensionFromMimeType(contentType: str) -> str:
'gif': 'gif', 'gif': 'gif',
'svg+xml': 'svg', 'svg+xml': 'svg',
'webp': 'webp', 'webp': 'webp',
'avif': 'avif' 'avif': 'avif',
'x-icon': 'ico'
} }
for mimeExt, ext in imageMedia.items(): for mimeExt, ext in imageMedia.items():
if contentType.endswith(mimeExt): if contentType.endswith(mimeExt):
@ -3220,3 +3222,11 @@ def getNewPostEndpoints() -> []:
'newreminder', 'newreport', 'newquestion', 'newshare', 'newwanted', 'newreminder', 'newreport', 'newquestion', 'newshare', 'newwanted',
'editblogpost' 'editblogpost'
) )
def getFavFilenameFromUrl(baseDir: str, faviconUrl: str) -> str:
"""Returns the cached filename for a favicon based upon its url
"""
if '://' in faviconUrl:
faviconUrl = faviconUrl.split('://')[1]
return baseDir + '/favicons/' + faviconUrl.replace('/', '-')

View File

@ -11,6 +11,7 @@ import os
from datetime import datetime from datetime import datetime
from content import removeLongWords from content import removeLongWords
from content import limitRepeatedWords from content import limitRepeatedWords
from utils import getFavFilenameFromUrl
from utils import getBaseContentFromPost from utils import getBaseContentFromPost
from utils import removeHtml from utils import removeHtml
from utils import locatePost from utils import locatePost
@ -240,15 +241,21 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
faviconUrl = getNewswireFaviconUrl(url) faviconUrl = getNewswireFaviconUrl(url)
faviconLink = '' faviconLink = ''
if faviconUrl: if faviconUrl:
favBase = '/favicons/' + faviconUrl.replace('/', '-') cachedFaviconFilename = getFavFilenameFromUrl(baseDir, faviconUrl)
cachedFaviconFilename = baseDir + favBase
if os.path.isfile(cachedFaviconFilename): if os.path.isfile(cachedFaviconFilename):
faviconUrl = favBase faviconUrl = \
cachedFaviconFilename.replace(baseDir + '/favicons', '')
else: else:
favBase = favBase.replace('.ico', '.png') extensions = ('png', 'jpg', 'gif', 'avif', 'svg', 'webp')
cachedFaviconFilename = baseDir + favBase for ext in extensions:
if os.path.isfile(cachedFaviconFilename): cachedFaviconFilename = \
faviconUrl = favBase getFavFilenameFromUrl(baseDir, faviconUrl)
cachedFaviconFilename = \
cachedFaviconFilename.replace('.ico', '.' + ext)
if os.path.isfile(cachedFaviconFilename):
faviconUrl = \
cachedFaviconFilename.replace(baseDir +
'/favicons', '')
faviconLink = \ faviconLink = \
'<img loading="lazy" src="' + faviconUrl + '" ' + \ '<img loading="lazy" src="' + faviconUrl + '" ' + \