Mute button

main
Bob Mottram 2019-12-01 13:45:30 +00:00
parent 39b8f337a6
commit ec6bd97e1c
23 changed files with 195 additions and 26 deletions

View File

@ -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

BIN
img/icons/mute.png 100644

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -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)

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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"
}

View File

@ -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

View File

@ -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':