Load hashtag swarm from cached version

merge-requests/30/head
Bob Mottram 2021-10-20 14:33:34 +01:00
parent 2873c4705b
commit b4e4159e8b
3 changed files with 95 additions and 11 deletions

View File

@ -15,6 +15,7 @@ import random
from linked_data_sig import verifyJsonSignature from linked_data_sig import verifyJsonSignature
from languages import understoodPostLanguage from languages import understoodPostLanguage
from like import updateLikesCollection from like import updateLikesCollection
from utils import fileLastModified
from utils import hasObjectString from utils import hasObjectString
from utils import hasObjectStringObject from utils import hasObjectStringObject
from utils import getReplyIntervalHours from utils import getReplyIntervalHours
@ -105,6 +106,7 @@ from announce import createAnnounce
from notifyOnPost import notifyWhenPersonPosts from notifyOnPost import notifyWhenPersonPosts
from conversation import updateConversation from conversation import updateConversation
from content import validHashTag from content import validHashTag
from webapp_hashtagswarm import htmlHashTagSwarm
def _storeLastPostId(baseDir: str, nickname: str, domain: str, def _storeLastPostId(baseDir: str, nickname: str, domain: str,
@ -138,7 +140,53 @@ def _storeLastPostId(baseDir: str, nickname: str, domain: str,
pass pass
def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None: def _updateCachedHashtagSwarm(baseDir: str, nickname: str, domain: str,
httpPrefix: str, domainFull: str,
translate: {}) -> bool:
"""Updates the hashtag swarm stored as a file
"""
cachedHashtagSwarmFilename = \
acctDir(baseDir, nickname, domain) + '/.hashtagSwarm'
saveSwarm = True
if os.path.isfile(cachedHashtagSwarmFilename):
lastModified = fileLastModified(cachedHashtagSwarmFilename)
modifiedDate = None
try:
modifiedDate = \
datetime.strptime(lastModified, "%Y-%m-%dT%H:%M:%SZ")
except BaseException:
print('WARN: unable to parse last modified cache date ' +
str(lastModified))
pass
if modifiedDate:
currDate = datetime.datetime.utcnow()
timeDiff = currDate - modifiedDate
diffMins = divmod(timeDiff.total_seconds(), 60)
if diffMins < 10:
# was saved recently, so don't save again
# This avoids too much disk I/O
saveSwarm = False
else:
print('Updating cached hashtag swarm, last changed ' +
str(diffMins) + ' minutes ago')
if saveSwarm:
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
newSwarmStr = htmlHashTagSwarm(baseDir, actor, translate)
if newSwarmStr:
try:
with open(cachedHashtagSwarmFilename, 'w+') as fp:
fp.write(newSwarmStr)
return True
except BaseException:
print('WARN: unable to write cached hashtag swarm ' +
cachedHashtagSwarmFilename)
pass
return False
def storeHashTags(baseDir: str, nickname: str, domain: str,
httpPrefix: str, domainFull: str,
postJsonObject: {}, translate: {}) -> None:
"""Extracts hashtags from an incoming post and updates the """Extracts hashtags from an incoming post and updates the
relevant tags files. relevant tags files.
""" """
@ -161,6 +209,7 @@ def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
hashtagCategories = getHashtagCategories(baseDir) hashtagCategories = getHashtagCategories(baseDir)
hashtagsCtr = 0
for tag in postJsonObject['object']['tag']: for tag in postJsonObject['object']['tag']:
if not tag.get('type'): if not tag.get('type'):
continue continue
@ -179,6 +228,7 @@ def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
daysDiff = datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1) daysDiff = datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1)
daysSinceEpoch = daysDiff.days daysSinceEpoch = daysDiff.days
tagline = str(daysSinceEpoch) + ' ' + nickname + ' ' + postUrl + '\n' tagline = str(daysSinceEpoch) + ' ' + nickname + ' ' + postUrl + '\n'
hashtagsCtr += 1
if not os.path.isfile(tagsFilename): if not os.path.isfile(tagsFilename):
with open(tagsFilename, 'w+') as tagsFile: with open(tagsFilename, 'w+') as tagsFile:
tagsFile.write(tagline) tagsFile.write(tagline)
@ -203,6 +253,12 @@ def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
if categoryStr: if categoryStr:
setHashtagCategory(baseDir, tagName, categoryStr, False) setHashtagCategory(baseDir, tagName, categoryStr, False)
# if some hashtags were found then recalculate the swarm
# ready for later display
if hashtagsCtr > 0:
_updateCachedHashtagSwarm(baseDir, nickname, domain,
httpPrefix, domainFull, translate)
def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int, def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
translate: {}, translate: {},
@ -1594,7 +1650,9 @@ def _receiveAnnounce(recentPostsCache: {},
if debug: if debug:
print('DEBUG: Announce post downloaded for ' + print('DEBUG: Announce post downloaded for ' +
messageJson['actor'] + ' -> ' + messageJson['object']) messageJson['actor'] + ' -> ' + messageJson['object'])
storeHashTags(baseDir, nickname, postJsonObject) storeHashTags(baseDir, nickname, domain,
httpPrefix, domainFull,
postJsonObject, translate)
# Try to obtain the actor for this person # Try to obtain the actor for this person
# so that their avatar can be shown # so that their avatar can be shown
lookupActor = None lookupActor = None
@ -2925,7 +2983,9 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
_inboxUpdateCalendar(baseDir, handle, postJsonObject) _inboxUpdateCalendar(baseDir, handle, postJsonObject)
storeHashTags(baseDir, handleName, postJsonObject) storeHashTags(baseDir, handleName, domain,
httpPrefix, domainFull,
postJsonObject, translate)
# send the post out to group members # send the post out to group members
if isGroup: if isGroup:

View File

@ -281,7 +281,8 @@ def hashtagRuleTree(operators: [],
def _hashtagAdd(baseDir: str, httpPrefix: str, domainFull: str, def _hashtagAdd(baseDir: str, httpPrefix: str, domainFull: str,
postJsonObject: {}, postJsonObject: {},
actionStr: str, hashtags: [], systemLanguage: str) -> None: actionStr: str, hashtags: [], systemLanguage: str,
translate: {}) -> None:
"""Adds a hashtag via a hashtag rule """Adds a hashtag via a hashtag rule
""" """
addHashtag = actionStr.split('add ', 1)[1].strip() addHashtag = actionStr.split('add ', 1)[1].strip()
@ -326,7 +327,12 @@ def _hashtagAdd(baseDir: str, httpPrefix: str, domainFull: str,
else: else:
content += hashtagHtml content += hashtagHtml
postJsonObject['object']['content'] = content postJsonObject['object']['content'] = content
storeHashTags(baseDir, 'news', postJsonObject) domain = domainFull
if ':' in domain:
domain = domain.split(':')[0]
storeHashTags(baseDir, 'news', domain,
httpPrefix, domainFull,
postJsonObject, translate)
def _hashtagRemove(httpPrefix: str, domainFull: str, postJsonObject: {}, def _hashtagRemove(httpPrefix: str, domainFull: str, postJsonObject: {},
@ -369,7 +375,8 @@ def _newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
federationList: [], federationList: [],
sendThreads: [], postLog: [], sendThreads: [], postLog: [],
moderated: bool, url: str, moderated: bool, url: str,
systemLanguage: str) -> bool: systemLanguage: str,
translate: {}) -> bool:
"""Applies hashtag rules to a news post. """Applies hashtag rules to a news post.
Returns true if the post should be saved to the news timeline Returns true if the post should be saved to the news timeline
of this instance of this instance
@ -413,7 +420,8 @@ def _newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
if actionStr.startswith('add '): if actionStr.startswith('add '):
# add a hashtag # add a hashtag
_hashtagAdd(baseDir, httpPrefix, domainFull, _hashtagAdd(baseDir, httpPrefix, domainFull,
postJsonObject, actionStr, hashtags, systemLanguage) postJsonObject, actionStr, hashtags, systemLanguage,
translate)
elif actionStr.startswith('remove '): elif actionStr.startswith('remove '):
# remove a hashtag # remove a hashtag
_hashtagRemove(httpPrefix, domainFull, postJsonObject, _hashtagRemove(httpPrefix, domainFull, postJsonObject,
@ -659,7 +667,8 @@ def _convertRSStoActivityPub(baseDir: str, httpPrefix: str,
personCache, cachedWebfingers, personCache, cachedWebfingers,
federationList, federationList,
sendThreads, postLog, sendThreads, postLog,
moderated, url, systemLanguage) moderated, url, systemLanguage,
translate)
# save the post and update the index # save the post and update the index
if savePost: if savePost:
@ -698,7 +707,9 @@ def _convertRSStoActivityPub(baseDir: str, httpPrefix: str,
if tag not in newswire[originalDateStr][6]: if tag not in newswire[originalDateStr][6]:
newswire[originalDateStr][6].append(tag) newswire[originalDateStr][6].append(tag)
storeHashTags(baseDir, 'news', blog) storeHashTags(baseDir, 'news', domain,
httpPrefix, domainFull,
blog, translate)
clearFromPostCaches(baseDir, recentPostsCache, postId) clearFromPostCaches(baseDir, recentPostsCache, postId)
if saveJson(blog, filename): if saveJson(blog, filename):

View File

@ -419,8 +419,21 @@ def htmlSearch(cssCache: {}, translate: {},
'name="submitSearch" accesskey="' + submitKey + '">' + \ 'name="submitSearch" accesskey="' + submitKey + '">' + \
translate['Submit'] + '</button>\n' translate['Submit'] + '</button>\n'
followStr += ' </form>\n' followStr += ' </form>\n'
followStr += ' <p class="hashtagswarm">' + \
htmlHashTagSwarm(baseDir, actor, translate) + '</p>\n' cachedHashtagSwarmFilename = \
acctDir(baseDir, searchNickname, domain) + '/.hashtagSwarm'
swarmStr = ''
if os.path.isfile(cachedHashtagSwarmFilename):
try:
with open(cachedHashtagSwarmFilename, 'r') as fp:
swarmStr = fp.read()
except BaseException:
print('WARN: Unable to read cached hashtag swarm')
pass
if not swarmStr:
swarmStr = htmlHashTagSwarm(baseDir, actor, translate)
followStr += ' <p class="hashtagswarm">' + swarmStr + '</p>\n'
followStr += ' </center>\n' followStr += ' </center>\n'
followStr += ' </div>\n' followStr += ' </div>\n'
followStr += '</div>\n' followStr += '</div>\n'