forked from indymedia/epicyon
Add hashtag conversion to html
parent
9976e016b1
commit
52162d1b9b
38
content.py
38
content.py
|
@ -9,6 +9,37 @@ __status__ = "Production"
|
||||||
import os
|
import os
|
||||||
import commentjson
|
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:
|
def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},recipients: []) -> bool:
|
||||||
"""Detects mentions and adds them to the replacements dict and recipients list
|
"""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, \
|
def addHtmlTags(baseDir: str,httpPrefix: str, \
|
||||||
nickname: str,domain: str,content: str, \
|
nickname: str,domain: str,content: str, \
|
||||||
recipients: []) -> str:
|
recipients: [],hashtags: {}) -> str:
|
||||||
""" Replaces plaintext mentions such as @nick@domain into html
|
""" Replaces plaintext mentions such as @nick@domain into html
|
||||||
by matching against known following accounts
|
by matching against known following accounts
|
||||||
"""
|
"""
|
||||||
|
@ -53,6 +84,7 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
|
||||||
wordsOnly=content.replace(',',' ').replace(';',' ').replace('.',' ').replace(':',' ')
|
wordsOnly=content.replace(',',' ').replace(';',' ').replace('.',' ').replace(':',' ')
|
||||||
words=wordsOnly.split(' ')
|
words=wordsOnly.split(' ')
|
||||||
replaceMentions={}
|
replaceMentions={}
|
||||||
|
replaceHashTags={}
|
||||||
if ':' in domain:
|
if ':' in domain:
|
||||||
domain=domain.split(':')[0]
|
domain=domain.split(':')[0]
|
||||||
followingFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/following.txt'
|
followingFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/following.txt'
|
||||||
|
@ -70,10 +102,14 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
|
||||||
for wordStr in words:
|
for wordStr in words:
|
||||||
if addMention(wordStr,httpPrefix,following,replaceMentions,recipients):
|
if addMention(wordStr,httpPrefix,following,replaceMentions,recipients):
|
||||||
continue
|
continue
|
||||||
|
addHashTags(wordStr,httpPrefix,domain,replaceHashTags,hashtags)
|
||||||
|
|
||||||
# replace words with their html versions
|
# replace words with their html versions
|
||||||
for wordStr,replaceStr in replaceMentions.items():
|
for wordStr,replaceStr in replaceMentions.items():
|
||||||
content=content.replace(wordStr,replaceStr)
|
content=content.replace(wordStr,replaceStr)
|
||||||
|
for wordStr,replaceStr in replaceHashTags.items():
|
||||||
|
content=content.replace(wordStr,replaceStr)
|
||||||
|
|
||||||
content=content.replace('\n','</p><p>')
|
content=content.replace('\n','</p><p>')
|
||||||
return '<p>'+content+'</p>'
|
return '<p>'+content+'</p>'
|
||||||
|
|
||||||
|
|
|
@ -1838,7 +1838,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
addHtmlTags(self.server.baseDir, \
|
addHtmlTags(self.server.baseDir, \
|
||||||
self.server.httpPrefix, \
|
self.server.httpPrefix, \
|
||||||
nickname, \
|
nickname, \
|
||||||
self.server.domain,fields['bio'],[])
|
self.server.domain,fields['bio'],[],{})
|
||||||
actorChanged=True
|
actorChanged=True
|
||||||
approveFollowers=False
|
approveFollowers=False
|
||||||
if fields.get('approveFollowers'):
|
if fields.get('approveFollowers'):
|
||||||
|
|
38
posts.py
38
posts.py
|
@ -371,6 +371,22 @@ def savePostToBox(baseDir: str,httpPrefix: str,postId: str, \
|
||||||
commentjson.dump(postJsonObject, fp, indent=4, sort_keys=False)
|
commentjson.dump(postJsonObject, fp, indent=4, sort_keys=False)
|
||||||
return filename
|
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, \
|
def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
|
toUrl: str, ccUrl: str, httpPrefix: str, content: str, \
|
||||||
followersOnly: bool, saveToFile: bool, clientToServer: bool,
|
followersOnly: bool, saveToFile: bool, clientToServer: bool,
|
||||||
|
@ -379,11 +395,15 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
"""Creates a message
|
"""Creates a message
|
||||||
"""
|
"""
|
||||||
mentionedRecipients=[]
|
mentionedRecipients=[]
|
||||||
|
tags=[]
|
||||||
|
hashtagsDict={}
|
||||||
if not clientToServer:
|
if not clientToServer:
|
||||||
# convert content to html
|
# convert content to html
|
||||||
content=addHtmlTags(baseDir,httpPrefix, \
|
content= \
|
||||||
nickname,domain,content, \
|
addHtmlTags(baseDir,httpPrefix, \
|
||||||
mentionedRecipients)
|
nickname,domain,content, \
|
||||||
|
mentionedRecipients, \
|
||||||
|
hashtagsDict)
|
||||||
|
|
||||||
if port!=80 and port!=443:
|
if port!=80 and port!=443:
|
||||||
if ':' not in domain:
|
if ':' not in domain:
|
||||||
|
@ -407,7 +427,13 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
|
|
||||||
# who to send to
|
# who to send to
|
||||||
toRecipients=[toUrl] + mentionedRecipients
|
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:
|
if not clientToServer:
|
||||||
actorUrl=httpPrefix+'://'+domain+'/users/'+nickname
|
actorUrl=httpPrefix+'://'+domain+'/users/'+nickname
|
||||||
|
|
||||||
|
@ -449,7 +475,7 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
'en': content
|
'en': content
|
||||||
},
|
},
|
||||||
'attachment': [],
|
'attachment': [],
|
||||||
'tag': [],
|
'tag': tags,
|
||||||
'replies': {
|
'replies': {
|
||||||
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
||||||
'type': 'Collection',
|
'type': 'Collection',
|
||||||
|
@ -486,7 +512,7 @@ def createPostBase(baseDir: str,nickname: str, domain: str, port: int, \
|
||||||
'en': content
|
'en': content
|
||||||
},
|
},
|
||||||
'attachment': [],
|
'attachment': [],
|
||||||
'tag': [],
|
'tag': tags,
|
||||||
'replies': {
|
'replies': {
|
||||||
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
'id': 'https://'+domain+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
|
||||||
'type': 'Collection',
|
'type': 'Collection',
|
||||||
|
|
2
tests.py
2
tests.py
|
@ -353,7 +353,7 @@ def testPostMessageBetweenServers():
|
||||||
sendResult = \
|
sendResult = \
|
||||||
sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
|
sendPost(sessionAlice,aliceDir,'alice', aliceDomain, alicePort, \
|
||||||
'bob', bobDomain, bobPort, ccUrl, httpPrefix, \
|
'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, \
|
saveToFile, clientToServer,attachedImageFilename, \
|
||||||
attachedImageDescription,useBlurhash, federationList, \
|
attachedImageDescription,useBlurhash, federationList, \
|
||||||
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \
|
aliceSendThreads, alicePostLog, aliceCachedWebfingers, \
|
||||||
|
|
Loading…
Reference in New Issue