forked from indymedia/epicyon
Mute button
parent
39b8f337a6
commit
ec6bd97e1c
66
daemon.py
66
daemon.py
|
@ -39,6 +39,7 @@ from person import removeAccount
|
|||
from person import canRemovePost
|
||||
from person import personSnooze
|
||||
from person import personUnsnooze
|
||||
from posts import mutePost
|
||||
from posts import createQuestionPost
|
||||
from posts import outboxMessageCreateWrap
|
||||
from posts import savePostToBox
|
||||
|
@ -2058,6 +2059,11 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
deleteUrl=self.path.split('?delete=')[1]
|
||||
if '?' in deleteUrl:
|
||||
deleteUrl=deleteUrl.split('?')[0]
|
||||
timelineStr=self.server.defaultTimeline
|
||||
if '?tl=' in self.path:
|
||||
timelineStr=self.path.split('?tl=')[1]
|
||||
if '?' in timelineStr:
|
||||
timelineStr=timelineStr.split('?')[0]
|
||||
actor= \
|
||||
self.server.httpPrefix+'://'+ \
|
||||
self.server.domainFull+self.path.split('?delete=')[0]
|
||||
|
@ -2069,13 +2075,13 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if actor not in deleteUrl:
|
||||
# You can only delete your own posts
|
||||
self.server.GETbusy=False
|
||||
self._redirect_headers(actor+'/'+self.server.defaultTimeline,cookie)
|
||||
self._redirect_headers(actor+'/'+timelineStr,cookie)
|
||||
return
|
||||
self.postToNickname=getNicknameFromActor(actor)
|
||||
if not self.postToNickname:
|
||||
print('WARN: unable to find nickname in '+actor)
|
||||
self.server.GETbusy=False
|
||||
self._redirect_headers(actor+'/'+self.server.defaultTimeline,cookie)
|
||||
self._redirect_headers(actor+'/'+timelineStr,cookie)
|
||||
return
|
||||
if not self.server.session:
|
||||
self.server.session= \
|
||||
|
@ -2095,7 +2101,61 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.GETbusy=False
|
||||
return
|
||||
self.server.GETbusy=False
|
||||
self._redirect_headers(actor+'/'+self.server.defaultTimeline,cookie)
|
||||
self._redirect_headers(actor+'/'+timelineStr,cookie)
|
||||
return
|
||||
|
||||
# mute a post from the web interface icon
|
||||
if htmlGET and '?mute=' in self.path:
|
||||
pageNumber=1
|
||||
if '?page=' in self.path:
|
||||
pageNumberStr=self.path.split('?page=')[1]
|
||||
if '?' in pageNumberStr:
|
||||
pageNumberStr=pageNumberStr.split('?')[0]
|
||||
if pageNumberStr.isdigit():
|
||||
pageNumber=int(pageNumberStr)
|
||||
muteUrl=self.path.split('?mute=')[1]
|
||||
if '?' in muteUrl:
|
||||
muteUrl=muteUrl.split('?')[0]
|
||||
timelineStr=self.server.defaultTimeline
|
||||
if '?tl=' in self.path:
|
||||
timelineStr=self.path.split('?tl=')[1]
|
||||
if '?' in timelineStr:
|
||||
timelineStr=timelineStr.split('?')[0]
|
||||
actor= \
|
||||
self.server.httpPrefix+'://'+ \
|
||||
self.server.domainFull+self.path.split('?mute=')[0]
|
||||
nickname=getNicknameFromActor(actor)
|
||||
mutePost(self.server.baseDir,nickname,self.server.domain, \
|
||||
muteUrl,self.server.recentPostsCache)
|
||||
self.server.GETbusy=False
|
||||
self._redirect_headers(actor+'/'+timelineStr,cookie)
|
||||
return
|
||||
|
||||
# unmute a post from the web interface icon
|
||||
if htmlGET and '?unmute=' in self.path:
|
||||
pageNumber=1
|
||||
if '?page=' in self.path:
|
||||
pageNumberStr=self.path.split('?page=')[1]
|
||||
if '?' in pageNumberStr:
|
||||
pageNumberStr=pageNumberStr.split('?')[0]
|
||||
if pageNumberStr.isdigit():
|
||||
pageNumber=int(pageNumberStr)
|
||||
muteUrl=self.path.split('?unmute=')[1]
|
||||
if '?' in muteUrl:
|
||||
muteUrl=muteUrl.split('?')[0]
|
||||
timelineStr=self.server.defaultTimeline
|
||||
if '?tl=' in self.path:
|
||||
timelineStr=self.path.split('?tl=')[1]
|
||||
if '?' in timelineStr:
|
||||
timelineStr=timelineStr.split('?')[0]
|
||||
actor= \
|
||||
self.server.httpPrefix+'://'+ \
|
||||
self.server.domainFull+self.path.split('?mute=')[0]
|
||||
nickname=getNicknameFromActor(actor)
|
||||
unmutePost(self.server.baseDir,nickname,self.server.domain, \
|
||||
muteUrl,self.server.recentPostsCache)
|
||||
self.server.GETbusy=False
|
||||
self._redirect_headers(actor+'/'+timelineStr,cookie)
|
||||
return
|
||||
|
||||
# reply from the web interface icon
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
46
posts.py
46
posts.py
|
@ -2635,3 +2635,49 @@ def downloadAnnounce(session,baseDir: str,httpPrefix: str,nickname: str,domain:
|
|||
if saveJson(postJsonObject,announceFilename):
|
||||
return postJsonObject
|
||||
return None
|
||||
|
||||
def mutePost(baseDir: str,nickname: str,domain: str,postId: str, \
|
||||
recentPostsCache: {}) -> None:
|
||||
""" Mutes the given post
|
||||
"""
|
||||
postFilename=locatePost(baseDir,nickname,domain,postId)
|
||||
if not postFilename:
|
||||
return
|
||||
postJsonObject=loadJson(postFilename)
|
||||
if not postJsonObject:
|
||||
return
|
||||
|
||||
muteFile=open(postFilename+'.muted', "w")
|
||||
muteFile.write('\n')
|
||||
muteFile.close()
|
||||
|
||||
# remove cached posts so that the muted version gets created
|
||||
cachedPostFilename= \
|
||||
getCachedPostFilename(baseDir,nickname,postJsonObject)
|
||||
if cachedPostFilename:
|
||||
if os.path.isfile(cachedPostFilename):
|
||||
os.remove(cachedPostFilename)
|
||||
removePostFromCache(postJsonObject,recentPostsCache)
|
||||
|
||||
def unmutePost(baseDir: str,nickname: str,domain: str,postId: str, \
|
||||
recentPostsCache: {}) -> None:
|
||||
""" Unmutes the given post
|
||||
"""
|
||||
postFilename=locatePost(baseDir,nickname,domain,postId)
|
||||
if not postFilename:
|
||||
return
|
||||
postJsonObject=loadJson(postFilename)
|
||||
if not postJsonObject:
|
||||
return
|
||||
|
||||
muteFilename=postFilename+'.muted'
|
||||
if os.path.isfile(muteFilename):
|
||||
os.remove(muteFilename)
|
||||
|
||||
# remove cached posts so that it gets recreated
|
||||
cachedPostFilename= \
|
||||
getCachedPostFilename(baseDir,nickname,postJsonObject)
|
||||
if cachedPostFilename:
|
||||
if os.path.isfile(cachedPostFilename):
|
||||
os.remove(cachedPostFilename)
|
||||
removePostFromCache(postJsonObject,recentPostsCache)
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "الشهر الماضى",
|
||||
"Next month": "الشهر القادم",
|
||||
"Get the source code": "الحصول على شفرة المصدر",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Mes anterior",
|
||||
"Next month": "El mes que ve",
|
||||
"Get the source code": "Obteniu el codi font",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Y mis blaenorol",
|
||||
"Next month": "Mis nesaf",
|
||||
"Get the source code": "Sicrhewch y cod ffynhonnell",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Vorheriger Monat",
|
||||
"Next month": "Nächsten Monat",
|
||||
"Get the source code": "Holen Sie sich den Quellcode",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Previous month",
|
||||
"Next month": "Next month",
|
||||
"Get the source code": "Get the source code",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Mes anterior",
|
||||
"Next month": "Próximo mes",
|
||||
"Get the source code": "Obtén el código fuente",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Le mois précédent",
|
||||
"Next month": "Le mois prochain",
|
||||
"Get the source code": "Obtenir le code source",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "An mhí roimhe seo",
|
||||
"Next month": "An mhí seo chugainn",
|
||||
"Get the source code": "Faigh an cód foinse",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "पिछ्ला महिना",
|
||||
"Next month": "अगले महीने",
|
||||
"Get the source code": "स्रोत कोड प्राप्त करें",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Il mese scorso",
|
||||
"Next month": "Il prossimo mese",
|
||||
"Get the source code": "Ottieni il codice sorgente",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "前月",
|
||||
"Next month": "来月",
|
||||
"Get the source code": "ソースコードを入手する",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -194,5 +194,7 @@
|
|||
"Previous month": "Previous month",
|
||||
"Next month": "Next month",
|
||||
"Get the source code": "Get the source code",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Mês anterior",
|
||||
"Next month": "Próximo mês",
|
||||
"Get the source code": "Obter o código fonte",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "Предыдущий месяц",
|
||||
"Next month": "В следующем месяце",
|
||||
"Get the source code": "Получить исходный код",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
|
@ -198,5 +198,7 @@
|
|||
"Previous month": "前一个月",
|
||||
"Next month": "下个月",
|
||||
"Get the source code": "获取源代码",
|
||||
"This is a media instance": "This is a media instance"
|
||||
"This is a media instance": "This is a media instance",
|
||||
"Mute this post": "Mute this post",
|
||||
"Undo mute": "Undo mute"
|
||||
}
|
||||
|
|
13
utils.py
13
utils.py
|
@ -312,6 +312,19 @@ def deletePost(baseDir: str,httpPrefix: str,nickname: str,domain: str,postFilena
|
|||
# remove any attachment
|
||||
removeAttachment(baseDir,httpPrefix,domain,postJsonObject)
|
||||
|
||||
# remove any mute file
|
||||
muteFilename=postFilename+'.muted'
|
||||
if os.path.isfile(muteFilename):
|
||||
os.remove(muteFilename)
|
||||
|
||||
# remove cached html version of the post
|
||||
cachedPostFilename= \
|
||||
getCachedPostFilename(baseDir,nickname,postJsonObject)
|
||||
if cachedPostFilename:
|
||||
if os.path.isfile(cachedPostFilename):
|
||||
os.remove(cachedPostFilename)
|
||||
#removePostFromCache(postJsonObject,recentPostsCache)
|
||||
|
||||
hasObject=False
|
||||
if postJsonObject.get('object'):
|
||||
hasObject=True
|
||||
|
|
|
@ -1995,6 +1995,18 @@ def preparePostFromHtmlCache(postHtml: str,boxName: str,pageNumber: int) -> str:
|
|||
postHtml=postHtml.replace('?tl=inbox','?tl=tlbookmarks')
|
||||
return postHtml.replace(';-999;',';'+str(pageNumber)+';').replace('?page=-999','?page='+str(pageNumber))
|
||||
|
||||
def postIsMuted(baseDir: str,nickname: str,domain: str, messageId: str) -> bool:
|
||||
""" Returns true if the given post is muted
|
||||
"""
|
||||
postDir=baseDir+'/accounts/'+nickname+'@'+domain
|
||||
muteFilename=postDir+'/inbox/'+messageId.replace('/','#')+'.json.muted'
|
||||
if os.path.isfile(muteFilename):
|
||||
return True
|
||||
muteFilename=postDir+'/outbox/'+messageId.replace('/','#')+'.json.muted'
|
||||
if os.path.isfile(muteFilename):
|
||||
return True
|
||||
return False
|
||||
|
||||
def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
|
||||
iconsDir: str,translate: {}, \
|
||||
pageNumber: int,baseDir: str, \
|
||||
|
@ -2238,14 +2250,24 @@ def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
|
|||
'?tl='+boxName+'" title="'+bookmarkTitle+'">'
|
||||
bookmarkStr+='<img loading="lazy" title="'+bookmarkTitle+' |" alt="'+bookmarkTitle+' |" src="/'+iconsDir+'/'+bookmarkIcon+'"/></a>'
|
||||
|
||||
isMuted=postIsMuted(baseDir,nickname,domain,messageId)
|
||||
|
||||
deleteStr=''
|
||||
muteStr=''
|
||||
if allowDeletion or \
|
||||
('/'+fullDomain+'/' in postActor and \
|
||||
postJsonObject['object']['id'].startswith(postActor)):
|
||||
if '/users/'+nickname+'/' in postJsonObject['object']['id']:
|
||||
deleteStr='<a href="/users/'+nickname+'?delete='+postJsonObject['object']['id']+pageNumberParam+'" title="'+translate['Delete this post']+'">'
|
||||
deleteStr+='<img loading="lazy" alt="'+translate['Delete this post']+'" title="'+translate['Delete this post']+'" src="/'+iconsDir+'/delete.png"/></a>'
|
||||
|
||||
else:
|
||||
if not isMuted:
|
||||
muteStr='<a href="/users/'+nickname+'?mute='+postJsonObject['object']['id']+pageNumberParam+'" title="'+translate['Mute this post']+'">'
|
||||
muteStr+='<img loading="lazy" alt="'+translate['Mute this post']+'" title="'+translate['Mute this post']+'" src="/'+iconsDir+'/mute.png"/></a>'
|
||||
else:
|
||||
muteStr='<a href="/users/'+nickname+'?unmute='+postJsonObject['object']['id']+pageNumberParam+'" title="'+translate['Undo mute']+'">'
|
||||
muteStr+='<img loading="lazy" alt="'+translate['Undo mute']+'" title="'+translate['Undo mute']+'" src="/'+iconsDir+'/mute.png"/></a>'
|
||||
|
||||
replyAvatarImageInPost=''
|
||||
if showRepeatIcon:
|
||||
if isAnnounced:
|
||||
|
@ -2468,7 +2490,7 @@ def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
|
|||
|
||||
if showIcons:
|
||||
footerStr='<div class="'+containerClassIcons+'">'
|
||||
footerStr+=replyStr+announceStr+likeStr+bookmarkStr+deleteStr
|
||||
footerStr+=replyStr+announceStr+likeStr+bookmarkStr+deleteStr+muteStr
|
||||
footerStr+='<span class="'+timeClass+'">'+publishedStr+'</span>'
|
||||
footerStr+='</div>'
|
||||
|
||||
|
@ -2503,12 +2525,10 @@ def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
|
|||
if postJsonObject['object'].get('tag'):
|
||||
contentStr=replaceEmojiFromTags(contentStr,postJsonObject['object']['tag'],'content')
|
||||
|
||||
# replace 's
|
||||
contentStr=contentStr.replace("\ufffd\ufffd\ufffds","'s")
|
||||
|
||||
contentStrMedia=contentStr
|
||||
|
||||
contentStr='<div class="message">'+contentStr+'</div>'
|
||||
if isMuted:
|
||||
contentStr=''
|
||||
else:
|
||||
contentStr='<div class="message">'+contentStr+'</div>'
|
||||
|
||||
postHtml=''
|
||||
if boxName!='tlmedia':
|
||||
|
|
Loading…
Reference in New Issue