Undoing likes

master
Bob Mottram 2019-07-12 10:10:09 +01:00
parent f2741f9194
commit 7a891e4cd2
2 changed files with 153 additions and 2 deletions

View File

@ -33,6 +33,7 @@ from capabilities import getOcapFilename
from capabilities import CapablePost from capabilities import CapablePost
from capabilities import capabilitiesReceiveUpdate from capabilities import capabilitiesReceiveUpdate
from like import updateLikesCollection from like import updateLikesCollection
from like import undoLikesCollectionEntry
def getPersonPubKey(session,personUrl: str,personCache: {},debug: bool) -> str: def getPersonPubKey(session,personUrl: str,personCache: {},debug: bool) -> str:
if not personUrl: if not personUrl:
@ -439,6 +440,55 @@ def receiveLike(session,handle: str,baseDir: str, \
updateLikesCollection(postFilename,messageJson['object'],messageJson['actor'],debug) updateLikesCollection(postFilename,messageJson['object'],messageJson['actor'],debug)
return True return True
def receiveUndoLike(session,handle: str,baseDir: str, \
httpPrefix: str,domain :str,port: int, \
sendThreads: [],postLog: [],cachedWebfingers: {}, \
personCache: {},messageJson: {},federationList: [], \
debug : bool) -> bool:
"""Receives an undo like activity within the POST section of HTTPServer
"""
if messageJson['type']!='Undo':
return False
if not messageJson.get('actor'):
return False
if not messageJson.get('object'):
return False
if not isinstance(messageJson['object'], dict):
return False
if not messageJson['object'].get('type'):
return False
if messageJson['object']['type']!='Like':
return False
if not messageJson['object'].get('object'):
if debug:
print('DEBUG: '+messageJson['type']+' like has no object')
return False
if not isinstance(messageJson['object']['object'], str):
if debug:
print('DEBUG: '+messageJson['type']+' like object is not a string')
return False
if '/users/' not in messageJson['actor']:
if debug:
print('DEBUG: "users" missing from actor in '+messageJson['type']+' like')
return False
if '/statuses/' not in messageJson['object']['object']:
if debug:
print('DEBUG: "statuses" missing from like object in '+messageJson['type'])
return False
if not os.path.isdir(baseDir+'/accounts/'+handle):
print('DEBUG: unknown recipient of undo like - '+handle)
# if this post in the outbox of the person?
postFilename=locatePost(baseDir,handle.split('@')[0],handle.split('@')[1],messageJson['object']['object'])
if not postFilename:
if debug:
print('DEBUG: post not found in inbox or outbox')
print(messageJson['object']['object'])
return True
if debug:
print('DEBUG: liked post found in inbox. Now undoing.')
undoLikesCollectionEntry(postFilename,messageJson['object'],messageJson['actor'],debug)
return True
def receiveDelete(session,handle: str,baseDir: str, \ def receiveDelete(session,handle: str,baseDir: str, \
httpPrefix: str,domain :str,port: int, \ httpPrefix: str,domain :str,port: int, \
sendThreads: [],postLog: [],cachedWebfingers: {}, \ sendThreads: [],postLog: [],cachedWebfingers: {}, \
@ -557,6 +607,19 @@ def inboxAfterCapabilities(session,keyId: str,handle: str,messageJson: {}, \
print('DEBUG: Like accepted from '+keyId) print('DEBUG: Like accepted from '+keyId)
return False return False
if receiveUndoLike(session,handle, \
baseDir,httpPrefix, \
domain,port, \
sendThreads,postLog, \
cachedWebfingers, \
personCache, \
messageJson, \
federationList, \
debug):
if debug:
print('DEBUG: Undo like accepted from '+keyId)
return False
if receiveAnnounce(session,handle, \ if receiveAnnounce(session,handle, \
baseDir,httpPrefix, \ baseDir,httpPrefix, \
domain,port, \ domain,port, \

92
like.py
View File

@ -103,8 +103,9 @@ def like(session,baseDir: str,federationList: [],nickname: str,domain: str,port:
sendThreads: [],postLog: [],personCache: {},cachedWebfingers: {}, \ sendThreads: [],postLog: [],personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}: debug: bool) -> {}:
"""Creates a like """Creates a like
ccUrl might be a specific person whose post was liked actor is the person doing the liking
objectUrl is typically the url of the message, corresponding to url or atomUri in createPostBase 'to' might be a specific person (actor) whose post was liked
object is typically the url of the message which was liked
""" """
if not urlPermitted(objectUrl,federationList,"inbox:write"): if not urlPermitted(objectUrl,federationList,"inbox:write"):
return None return None
@ -176,3 +177,90 @@ def likePost(session,baseDir: str,federationList: [], \
ccList,httpPrefix,objectUrl,clientToServer, \ ccList,httpPrefix,objectUrl,clientToServer, \
sendThreads,postLog,personCache,cachedWebfingers,debug) sendThreads,postLog,personCache,cachedWebfingers,debug)
def undolike(session,baseDir: str,federationList: [],nickname: str,domain: str,port: int, \
ccList: [],httpPrefix: str,objectUrl: str,clientToServer: bool, \
sendThreads: [],postLog: [],personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}:
"""Removes a like
actor is the person doing the liking
'to' might be a specific person (actor) whose post was liked
object is typically the url of the message which was liked
"""
if not urlPermitted(objectUrl,federationList,"inbox:write"):
return None
fullDomain=domain
if port!=80 and port!=443:
if ':' not in domain:
fullDomain=domain+':'+str(port)
newUndoLikeJson = {
'type': 'Undo',
'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
'object': {
'type': 'Like',
'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
'object': objectUrl,
'to': [httpPrefix+'://'+fullDomain+'/users/'+nickname+'/followers'],
'cc': []
},
'to': [httpPrefix+'://'+fullDomain+'/users/'+nickname+'/followers'],
'cc': []
}
if ccList:
if len(ccList)>0:
newUndoLikeJson['cc']=ccList
newUndoLikeJson['object']['cc']=ccList
# Extract the domain and nickname from a statuses link
likedPostNickname=None
likedPostDomain=None
likedPostPort=None
if '/users/' in objectUrl:
likedPostNickname=getNicknameFromActor(objectUrl)
likedPostDomain,likedPostPort=getDomainFromActor(objectUrl)
if likedPostNickname:
postFilename=locatePost(baseDir,nickname,domain,objectUrl)
if not postFilename:
return None
undoLikesCollectionEntry(postFilename,objectUrl,newLikeJson['actor'],debug)
sendSignedJson(newLikeJson,session,baseDir, \
nickname,domain,port, \
likedPostNickname,likedPostDomain,likedPostPort, \
'https://www.w3.org/ns/activitystreams#Public', \
httpPrefix,True,clientToServer,federationList, \
sendThreads,postLog,cachedWebfingers,personCache,debug)
else:
return None
return newLikeJson
def undoLikePost(session,baseDir: str,federationList: [], \
nickname: str,domain: str,port: int,httpPrefix: str, \
likeNickname: str,likeDomain: str,likePort: int, \
ccList: [], \
likeStatusNumber: int,clientToServer: bool, \
sendThreads: [],postLog: [], \
personCache: {},cachedWebfingers: {}, \
debug: bool) -> {}:
"""Removes a liked post
"""
likeDomain=likeDomain
if likePort!=80 and likePort!=443:
likeDomain=likeDomain+':'+str(likePort)
objectUrl = \
httpPrefix + '://'+likeDomain+'/users/'+likeNickname+ \
'/statuses/'+str(likeStatusNumber)
if likePort!=80 and likePort!=443:
ccUrl=httpPrefix+'://'+likeDomain+':'+str(likePort)+'/users/'+likeNickname
else:
ccUrl=httpPrefix+'://'+likeDomain+'/users/'+likeNickname
return undoLike(session,baseDir,federationList,nickname,domain,port, \
ccList,httpPrefix,objectUrl,clientToServer, \
sendThreads,postLog,personCache,cachedWebfingers,debug)