Add hashtag conversion to html

master
Bob Mottram 2019-08-09 12:12:08 +01:00
parent 9976e016b1
commit 52162d1b9b
4 changed files with 71 additions and 9 deletions

View File

@ -9,6 +9,37 @@ __status__ = "Production"
import os
import commentjson
def validHashTag(hashtag: str) -> bool:
"""Returns true if the give hashtag contains valid characters
"""
validChars = set('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
if set(hashtag).issubset(validChars):
return True
return False
def addHashTags(wordStr: str,httpPrefix: str,domain: str,replaceHashTags: {},postHashtags: {}) -> bool:
"""Detects hashtags and adds them to the replacements dict
Also updates the hashtags list to be added to the post
"""
if not wordStr.startswith('#'):
return False
if len(wordStr)<2:
return False
if replaceHashTags.get(wordStr):
return True
hashtag=wordStr[1:]
if not validHashTag(hashtag):
return False
hashtagUrl=httpPrefix+"://"+domain+"/tags/"+hashtag
postHashtags[hashtag]= {
'href': hashtagUrl,
'name': '#'+hashtag,
'type': 'Hashtag'
}
replaceHashTags[wordStr]= \
"<a href=\""+hashtagUrl+"\" class=\"mention hashtag\" rel=\"tag\">#<span>"+hashtag+"</span></a>"
return True
def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},recipients: []) -> bool:
"""Detects mentions and adds them to the replacements dict and recipients list
"""
@ -44,7 +75,7 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
def addHtmlTags(baseDir: str,httpPrefix: str, \
nickname: str,domain: str,content: str, \
recipients: []) -> str:
recipients: [],hashtags: {}) -> str:
""" Replaces plaintext mentions such as @nick@domain into html
by matching against known following accounts
"""
@ -53,6 +84,7 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
wordsOnly=content.replace(',',' ').replace(';',' ').replace('.',' ').replace(':',' ')
words=wordsOnly.split(' ')
replaceMentions={}
replaceHashTags={}
if ':' in domain:
domain=domain.split(':')[0]
followingFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/following.txt'
@ -70,10 +102,14 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
for wordStr in words:
if addMention(wordStr,httpPrefix,following,replaceMentions,recipients):
continue
addHashTags(wordStr,httpPrefix,domain,replaceHashTags,hashtags)
# replace words with their html versions
for wordStr,replaceStr in replaceMentions.items():
content=content.replace(wordStr,replaceStr)
for wordStr,replaceStr in replaceHashTags.items():
content=content.replace(wordStr,replaceStr)
content=content.replace('\n','</p><p>')
return '<p>'+content+'</p>'

View File

@ -1838,7 +1838,7 @@ class PubServer(BaseHTTPRequestHandler):
addHtmlTags(self.server.baseDir, \
self.server.httpPrefix, \
nickname, \
self.server.domain,fields['bio'],[])
self.server.domain,fields['bio'],[],{})
actorChanged=True
approveFollowers=False
if fields.get('approveFollowers'):

View File

@ -371,6 +371,22 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
commentjson.dump(postJsonObject, fp, indent=4, sort_keys=False)
return filename
def updateHashtagsIndex(baseDir: str,tag: {},newPostId: str) -> None:
"""Writes the post url for hashtags to a file
This allows posts for a hashtag to be quickly looked up
"""
# create hashtags directory
tagsDir=baseDir+'/tags'
if not os.path.isdir(tagsDir):
os.mkdir(tagsDir)
tagName=tag['name']
tagsFilename=tagsDir+'/'+tagName[1:]+'.txt'
tagFile=open(tagsFilename, "a+")
if not tagFile:
return
tagFile.write(newPostId+'\n')
tagFile.close()
def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
followersOnly: bool, saveToFile: bool, clientToServer: bool,
@ -379,11 +395,15 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
"""Creates a message
"""
mentionedRecipients=[]
tags=[]
hashtagsDict={}
if not clientToServer:
# convert content to html
content=addHtmlTags(baseDir,httpPrefix, \
content= \
addHtmlTags(baseDir,httpPrefix, \
nickname,domain,content, \
mentionedRecipients)
mentionedRecipients, \
hashtagsDict)
if port!=80 and port!=443:
if ':' not in domain:
@ -408,6 +428,12 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
# who to send to
toRecipients=[toUrl] + mentionedRecipients
# create a list of hashtags
if hashtagsDict:
for tagName,tag in hashtagsDict.items():
tags.append(tag)
updateHashtagsIndex(baseDir,tag,newPostId)
if not clientToServer:
actorUrl=httpPrefix+'://'+domain+'/users/'+nickname
@ -449,7 +475,7 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
'en': content
},
'attachment': [],
'tag': [],
'tag': tags,
'replies': {
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
'type': 'Collection',
@ -486,7 +512,7 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
'en': content
},
'attachment': [],
'tag': [],
'tag': tags,
'replies': {
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
'type': 'Collection',

View File

@ -353,7 +353,7 @@ def testPostMessageBetweenServers():
sendResult = \
sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
'bob', bobDomain, bobPort, ccUrl, httpPrefix, \
'Why is a mouse when it spins?', followersOnly, \
'Why is a mouse when it spins? #sillyquestion', followersOnly, \
saveToFile, clientToServer,attachedImageFilename, \
attachedImageDescription,useBlurhash, federationList, \
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \