epicyon/shares.py

631 lines
22 KiB
Python
Raw Normal View History

2020-04-04 11:27:51 +00:00
__filename__ = "shares.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
2019-07-23 12:33:09 +00:00
import os
import time
from webfinger import webfingerHandle
from auth import createBasicAuthHeader
from posts import getPersonBox
from session import postJson
2020-04-04 11:27:51 +00:00
from session import postImage
2019-07-27 22:48:34 +00:00
from utils import validNickname
2019-10-22 11:55:06 +00:00
from utils import loadJson
from utils import saveJson
2019-07-24 13:21:47 +00:00
from media import removeMetaData
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
2019-11-03 09:48:01 +00:00
def getValidSharedItemID(displayName: str) -> str:
2019-11-02 10:24:25 +00:00
"""Removes any invalid characters from the display name to
produce an item ID
"""
2020-06-11 22:04:41 +00:00
removeChars = (' ', '\n', '\r')
for ch in removeChars:
displayName = displayName.replace(ch, '')
removeChars2 = ('+', '/', '\\', '?', '&')
for ch in removeChars2:
displayName = displayName.replace(ch, '-')
displayName = displayName.replace('.', '_')
2020-05-22 11:32:38 +00:00
displayName = displayName.replace("", "'")
2020-06-11 22:04:41 +00:00
return displayName
2019-11-02 10:24:25 +00:00
2020-04-04 11:27:51 +00:00
def removeShare(baseDir: str, nickname: str, domain: str,
2019-07-23 12:33:09 +00:00
displayName: str) -> None:
"""Removes a share for a person
"""
2020-04-04 11:27:51 +00:00
sharesFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/shares.json'
2019-11-03 10:04:28 +00:00
if not os.path.isfile(sharesFilename):
2020-04-04 11:27:51 +00:00
print('ERROR: missing shares.json ' + sharesFilename)
2019-11-03 10:04:28 +00:00
return
2020-04-04 11:27:51 +00:00
sharesJson = loadJson(sharesFilename)
2019-11-03 10:04:28 +00:00
if not sharesJson:
2020-04-04 11:27:51 +00:00
print('ERROR: shares.json could not be loaded from ' + sharesFilename)
2019-11-03 10:04:28 +00:00
return
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
itemID = getValidSharedItemID(displayName)
2019-07-23 12:33:09 +00:00
if sharesJson.get(itemID):
# remove any image for the item
2020-04-04 11:27:51 +00:00
itemIDfile = baseDir + '/sharefiles/' + nickname + '/' + itemID
2019-07-23 12:33:09 +00:00
if sharesJson[itemID]['imageUrl']:
if sharesJson[itemID]['imageUrl'].endswith('.png'):
2020-04-04 11:27:51 +00:00
if os.path.isfile(itemIDfile + '.png'):
os.remove(itemIDfile + '.png')
2019-07-23 12:33:09 +00:00
if sharesJson[itemID]['imageUrl'].endswith('.jpg'):
2020-04-04 11:27:51 +00:00
if os.path.isfile(itemIDfile + '.jpg'):
os.remove(itemIDfile + '.jpg')
2019-07-23 12:33:09 +00:00
if sharesJson[itemID]['imageUrl'].endswith('.gif'):
2020-04-04 11:27:51 +00:00
if os.path.isfile(itemIDfile + '.gif'):
os.remove(itemIDfile + '.gif')
2019-07-23 12:33:09 +00:00
# remove the item itself
del sharesJson[itemID]
2020-04-04 11:27:51 +00:00
saveJson(sharesJson, sharesFilename)
2019-11-03 10:04:28 +00:00
else:
2020-04-04 11:27:51 +00:00
print('ERROR: share index "' + itemID +
'" does not exist in ' + sharesFilename)
def addShare(baseDir: str,
httpPrefix: str, nickname: str, domain: str, port: int,
displayName: str, summary: str, imageFilename: str,
itemType: str, itemCategory: str, location: str,
duration: str, debug: bool) -> None:
2019-07-23 12:33:09 +00:00
"""Updates the likes collection within a post
"""
2020-04-04 11:27:51 +00:00
sharesFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/shares.json'
sharesJson = {}
2019-09-30 22:39:02 +00:00
if os.path.isfile(sharesFilename):
2020-04-04 11:27:51 +00:00
sharesJson = loadJson(sharesFilename)
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
duration = duration.lower()
durationSec = 0
published = int(time.time())
2019-07-23 12:33:09 +00:00
if ' ' in duration:
2020-04-04 11:27:51 +00:00
durationList = duration.split(' ')
2019-07-23 12:33:09 +00:00
if durationList[0].isdigit():
if 'hour' in durationList[1]:
2020-04-04 11:27:51 +00:00
durationSec = published + (int(durationList[0]) * 60 * 60)
2019-07-23 12:33:09 +00:00
if 'day' in durationList[1]:
2020-04-04 11:27:51 +00:00
durationSec = published + (int(durationList[0]) * 60 * 60 * 24)
2019-07-23 12:33:09 +00:00
if 'week' in durationList[1]:
2020-04-04 11:27:51 +00:00
durationSec = \
published + (int(durationList[0]) * 60 * 60 * 24 * 7)
2019-07-23 12:33:09 +00:00
if 'month' in durationList[1]:
2020-04-04 11:27:51 +00:00
durationSec = \
published + (int(durationList[0]) * 60 * 60 * 24 * 30)
2019-07-23 12:33:09 +00:00
if 'year' in durationList[1]:
2020-04-04 11:27:51 +00:00
durationSec = \
published + (int(durationList[0]) * 60 * 60 * 24 * 365)
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
itemID = getValidSharedItemID(displayName)
2019-07-23 12:33:09 +00:00
2019-07-23 19:02:26 +00:00
# has an image for this share been uploaded?
2020-04-04 11:27:51 +00:00
imageUrl = None
moveImage = False
2019-07-23 19:02:26 +00:00
if not imageFilename:
2020-04-04 11:27:51 +00:00
sharesImageFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/upload'
if os.path.isfile(sharesImageFilename + '.png'):
imageFilename = sharesImageFilename + '.png'
moveImage = True
elif os.path.isfile(sharesImageFilename + '.jpg'):
imageFilename = sharesImageFilename + '.jpg'
moveImage = True
elif os.path.isfile(sharesImageFilename + '.gif'):
imageFilename = sharesImageFilename + '.gif'
moveImage = True
domainFull = domain
if port:
2020-04-04 11:27:51 +00:00
if port != 80 and port != 443:
if ':' not in domain:
2020-04-04 11:27:51 +00:00
domainFull = domain + ':' + str(port)
2019-07-23 19:02:26 +00:00
# copy or move the image for the shared item to its destination
2019-07-23 12:33:09 +00:00
if imageFilename:
if os.path.isfile(imageFilename):
2020-04-04 11:27:51 +00:00
if not os.path.isdir(baseDir + '/sharefiles'):
os.mkdir(baseDir + '/sharefiles')
if not os.path.isdir(baseDir + '/sharefiles/' + nickname):
os.mkdir(baseDir + '/sharefiles/' + nickname)
itemIDfile = baseDir + '/sharefiles/' + nickname + '/' + itemID
2019-07-23 22:12:19 +00:00
if imageFilename.endswith('.png'):
2020-04-04 11:27:51 +00:00
removeMetaData(imageFilename, itemIDfile + '.png')
2019-07-23 19:02:26 +00:00
if moveImage:
2019-07-24 13:21:47 +00:00
os.remove(imageFilename)
2020-04-04 11:27:51 +00:00
imageUrl = \
httpPrefix + '://' + domainFull + \
'/sharefiles/' + nickname + '/' + itemID + '.png'
2019-07-23 22:12:19 +00:00
if imageFilename.endswith('.jpg'):
2020-04-04 11:27:51 +00:00
removeMetaData(imageFilename, itemIDfile + '.jpg')
2019-07-23 19:02:26 +00:00
if moveImage:
2019-07-24 13:21:47 +00:00
os.remove(imageFilename)
2020-04-04 11:27:51 +00:00
imageUrl = \
httpPrefix + '://' + domainFull + \
'/sharefiles/' + nickname + '/' + itemID + '.jpg'
2019-07-23 22:12:19 +00:00
if imageFilename.endswith('.gif'):
2020-04-04 11:27:51 +00:00
removeMetaData(imageFilename, itemIDfile + '.gif')
2019-07-23 19:02:26 +00:00
if moveImage:
2019-07-24 13:21:47 +00:00
os.remove(imageFilename)
2020-04-04 11:27:51 +00:00
imageUrl = \
httpPrefix + '://' + domainFull + \
'/sharefiles/' + nickname + '/' + itemID + '.gif'
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
sharesJson[itemID] = {
2019-07-23 12:33:09 +00:00
"displayName": displayName,
"summary": summary,
"imageUrl": imageUrl,
2019-07-23 19:02:26 +00:00
"itemType": itemType,
2019-07-23 22:12:19 +00:00
"category": itemCategory,
2019-07-23 12:33:09 +00:00
"location": location,
"published": published,
"expire": durationSec
}
2020-04-04 11:27:51 +00:00
saveJson(sharesJson, sharesFilename)
2019-07-23 12:33:09 +00:00
# indicate that a new share is available
2020-04-04 11:27:51 +00:00
for subdir, dirs, files in os.walk(baseDir + '/accounts'):
for handle in dirs:
2020-06-11 22:08:50 +00:00
if '@' not in handle:
continue
accountDir = baseDir + '/accounts/' + handle
newShareFile = accountDir + '/.newShare'
if not os.path.isfile(newShareFile):
nickname = handle.split('@')[0]
try:
with open(newShareFile, 'w') as fp:
fp.write(httpPrefix + '://' + domainFull +
'/users/' + nickname + '/tlshares')
except BaseException:
pass
2020-04-04 11:27:51 +00:00
2019-10-17 09:58:30 +00:00
def expireShares(baseDir: str) -> None:
"""Removes expired items from shares
"""
2020-04-04 11:27:51 +00:00
for subdir, dirs, files in os.walk(baseDir + '/accounts'):
2019-10-17 09:58:30 +00:00
for account in dirs:
if '@' not in account:
continue
2020-04-04 11:27:51 +00:00
nickname = account.split('@')[0]
domain = account.split('@')[1]
expireSharesForAccount(baseDir, nickname, domain)
2019-10-17 09:58:30 +00:00
2020-04-04 11:27:51 +00:00
def expireSharesForAccount(baseDir: str, nickname: str, domain: str) -> None:
2019-07-23 12:33:09 +00:00
"""Removes expired items from shares
"""
2020-04-04 11:27:51 +00:00
handleDomain = domain
2019-07-23 12:33:09 +00:00
if ':' in handleDomain:
2020-04-04 11:27:51 +00:00
handleDomain = domain.split(':')[0]
handle = nickname + '@' + handleDomain
sharesFilename = baseDir + '/accounts/' + handle + '/shares.json'
2019-07-23 12:33:09 +00:00
if os.path.isfile(sharesFilename):
2020-04-04 11:27:51 +00:00
sharesJson = loadJson(sharesFilename)
2019-09-30 22:39:02 +00:00
if sharesJson:
2020-04-04 11:27:51 +00:00
currTime = int(time.time())
deleteItemID = []
for itemID, item in sharesJson.items():
if currTime > item['expire']:
2019-07-23 12:33:09 +00:00
deleteItemID.append(itemID)
if deleteItemID:
for itemID in deleteItemID:
del sharesJson[itemID]
2019-07-24 09:17:57 +00:00
# remove any associated images
2020-04-04 11:27:51 +00:00
itemIDfile = \
baseDir + '/sharefiles/' + nickname + '/' + itemID
if os.path.isfile(itemIDfile + '.png'):
os.remove(itemIDfile + '.png')
if os.path.isfile(itemIDfile + '.jpg'):
os.remove(itemIDfile + '.jpg')
if os.path.isfile(itemIDfile + '.gif'):
os.remove(itemIDfile + '.gif')
saveJson(sharesJson, sharesFilename)
def getSharesFeedForPerson(baseDir: str,
domain: str, port: int,
path: str, httpPrefix: str,
2019-07-23 12:33:09 +00:00
sharesPerPage=12) -> {}:
"""Returns the shares for an account from GET requests
"""
if '/shares' not in path:
return None
# handle page numbers
2020-04-04 11:27:51 +00:00
headerOnly = True
pageNumber = None
2019-07-23 12:33:09 +00:00
if '?page=' in path:
2020-04-04 11:27:51 +00:00
pageNumber = path.split('?page=')[1]
if pageNumber == 'true':
pageNumber = 1
2019-07-23 12:33:09 +00:00
else:
try:
2020-04-04 11:27:51 +00:00
pageNumber = int(pageNumber)
except BaseException:
2019-07-23 12:33:09 +00:00
pass
2020-04-04 11:27:51 +00:00
path = path.split('?page=')[0]
headerOnly = False
2020-03-22 21:16:02 +00:00
2019-07-23 12:33:09 +00:00
if not path.endswith('/shares'):
return None
2020-04-04 11:27:51 +00:00
nickname = None
2019-07-23 12:33:09 +00:00
if path.startswith('/users/'):
2020-04-04 11:27:51 +00:00
nickname = path.replace('/users/', '', 1).replace('/shares', '')
2019-07-23 12:33:09 +00:00
if path.startswith('/@'):
2020-04-04 11:27:51 +00:00
nickname = path.replace('/@', '', 1).replace('/shares', '')
2019-07-23 12:33:09 +00:00
if not nickname:
return None
2020-04-04 11:27:51 +00:00
if not validNickname(domain, nickname):
2019-07-23 12:33:09 +00:00
return None
2019-07-24 09:53:07 +00:00
if port:
2020-04-04 11:27:51 +00:00
if port != 80 and port != 443:
if ':' not in domain:
2020-04-04 11:27:51 +00:00
domain = domain + ':' + str(port)
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
handleDomain = domain
2019-07-23 12:33:09 +00:00
if ':' in handleDomain:
2020-04-04 11:27:51 +00:00
handleDomain = domain.split(':')[0]
handle = nickname + '@' + handleDomain
sharesFilename = baseDir + '/accounts/' + handle + '/shares.json'
2019-07-23 12:33:09 +00:00
if headerOnly:
2020-04-04 11:27:51 +00:00
noOfShares = 0
2019-07-23 12:33:09 +00:00
if os.path.isfile(sharesFilename):
2020-04-04 11:27:51 +00:00
sharesJson = loadJson(sharesFilename)
2019-10-22 11:55:06 +00:00
if sharesJson:
2020-04-04 11:27:51 +00:00
noOfShares = len(sharesJson.items())
idStr = httpPrefix + '://' + domain + '/users/' + nickname
shares = {
2019-07-23 12:33:09 +00:00
'@context': 'https://www.w3.org/ns/activitystreams',
2020-04-04 11:27:51 +00:00
'first': idStr+'/shares?page=1',
'id': idStr+'/shares',
2019-07-23 12:33:09 +00:00
'totalItems': str(noOfShares),
2020-03-22 20:36:19 +00:00
'type': 'OrderedCollection'
}
2019-07-23 12:33:09 +00:00
return shares
if not pageNumber:
2020-04-04 11:27:51 +00:00
pageNumber = 1
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
nextPageNumber = int(pageNumber + 1)
idStr = httpPrefix + '://' + domain + '/users/' + nickname
shares = {
2019-07-23 12:33:09 +00:00
'@context': 'https://www.w3.org/ns/activitystreams',
2020-04-04 11:27:51 +00:00
'id': idStr+'/shares?page='+str(pageNumber),
2019-07-23 12:33:09 +00:00
'orderedItems': [],
2020-04-04 11:27:51 +00:00
'partOf': idStr+'/shares',
2019-07-23 12:33:09 +00:00
'totalItems': 0,
2020-03-22 20:36:19 +00:00
'type': 'OrderedCollectionPage'
}
2019-07-23 12:33:09 +00:00
if not os.path.isfile(sharesFilename):
2019-07-24 09:53:07 +00:00
print("test5")
2019-07-23 12:33:09 +00:00
return shares
2020-04-04 11:27:51 +00:00
currPage = 1
pageCtr = 0
totalCtr = 0
2019-07-23 12:33:09 +00:00
2020-04-04 11:27:51 +00:00
sharesJson = loadJson(sharesFilename)
2019-09-30 22:39:02 +00:00
if sharesJson:
2020-04-04 11:27:51 +00:00
for itemID, item in sharesJson.items():
2019-07-23 12:33:09 +00:00
pageCtr += 1
totalCtr += 1
2020-04-04 11:27:51 +00:00
if currPage == pageNumber:
2019-07-23 12:33:09 +00:00
shares['orderedItems'].append(item)
2020-04-04 11:27:51 +00:00
if pageCtr >= sharesPerPage:
pageCtr = 0
2019-07-23 12:33:09 +00:00
currPage += 1
2020-04-04 11:27:51 +00:00
shares['totalItems'] = totalCtr
lastPage = int(totalCtr / sharesPerPage)
if lastPage < 1:
lastPage = 1
if nextPageNumber > lastPage:
shares['next'] = \
httpPrefix + '://' + domain + '/users/' + nickname + \
'/shares?page=' + str(lastPage)
2019-07-23 12:33:09 +00:00
return shares
2019-07-23 19:02:26 +00:00
2020-04-04 11:27:51 +00:00
def sendShareViaServer(baseDir, session,
fromNickname: str, password: str,
fromDomain: str, fromPort: int,
httpPrefix: str, displayName: str,
summary: str, imageFilename: str,
itemType: str, itemCategory: str,
location: str, duration: str,
cachedWebfingers: {}, personCache: {},
debug: bool, projectVersion: str) -> {}:
2019-07-23 19:02:26 +00:00
"""Creates an item share via c2s
"""
if not session:
print('WARN: No session for sendShareViaServer')
return 6
2020-04-04 11:27:51 +00:00
fromDomainFull = fromDomain
if fromPort:
2020-04-04 11:27:51 +00:00
if fromPort != 80 and fromPort != 443:
if ':' not in fromDomain:
2020-04-04 11:27:51 +00:00
fromDomainFull = fromDomain + ':' + str(fromPort)
2019-07-23 19:02:26 +00:00
2020-04-04 11:27:51 +00:00
toUrl = 'https://www.w3.org/ns/activitystreams#Public'
ccUrl = httpPrefix + '://' + fromDomainFull + \
'/users/' + fromNickname + '/followers'
2019-07-23 19:02:26 +00:00
2020-04-04 11:27:51 +00:00
actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname
newShareJson = {
2019-08-18 11:07:06 +00:00
"@context": "https://www.w3.org/ns/activitystreams",
2019-07-23 19:02:26 +00:00
'type': 'Add',
2020-04-04 11:27:51 +00:00
'actor': actor,
'target': actor+'/shares',
2019-07-23 19:02:26 +00:00
'object': {
"type": "Offer",
"displayName": displayName,
"summary": summary,
"itemType": itemType,
2020-04-04 11:27:51 +00:00
"category": itemCategory,
2019-07-23 19:02:26 +00:00
"location": location,
"duration": duration,
'to': [toUrl],
'cc': [ccUrl]
},
'to': [toUrl],
'cc': [ccUrl]
}
2020-04-04 11:27:51 +00:00
handle = httpPrefix + '://' + fromDomainFull + '/@' + fromNickname
2019-07-23 19:02:26 +00:00
# lookup the inbox for the To handle
2020-04-04 11:27:51 +00:00
wfRequest = \
webfingerHandle(session, handle, httpPrefix,
cachedWebfingers,
fromDomain, projectVersion)
2019-07-23 19:02:26 +00:00
if not wfRequest:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: announce webfinger failed for ' + handle)
2019-07-23 19:02:26 +00:00
return 1
2020-06-23 10:41:12 +00:00
if not isinstance(wfRequest, dict):
print('WARN: Webfinger for ' + handle + ' did not return a dict. ' +
str(wfRequest))
return 1
2019-07-23 19:02:26 +00:00
2020-04-04 11:27:51 +00:00
postToBox = 'outbox'
2019-07-23 19:02:26 +00:00
# get the actor inbox for the To handle
2020-04-04 11:27:51 +00:00
(inboxUrl, pubKeyId, pubKey,
fromPersonId, sharedInbox,
capabilityAcquisition,
avatarUrl, displayName) = getPersonBox(baseDir, session, wfRequest,
personCache, projectVersion,
httpPrefix, fromNickname,
fromDomain, postToBox)
2020-03-22 21:16:02 +00:00
2019-07-23 19:02:26 +00:00
if not inboxUrl:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: No ' + postToBox + ' was found for ' + handle)
2019-07-23 19:02:26 +00:00
return 3
if not fromPersonId:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: No actor was found for ' + handle)
2019-07-23 19:02:26 +00:00
return 4
2020-03-22 21:16:02 +00:00
2020-04-04 11:27:51 +00:00
authHeader = createBasicAuthHeader(fromNickname, password)
2019-07-23 19:02:26 +00:00
if imageFilename:
2020-04-04 11:27:51 +00:00
headers = {
'host': fromDomain,
2020-03-22 20:36:19 +00:00
'Authorization': authHeader
}
2020-04-04 11:27:51 +00:00
postResult = \
postImage(session, imageFilename, [],
inboxUrl.replace('/' + postToBox, '/shares'),
headers, "inbox:write")
headers = {
'host': fromDomain,
'Content-type': 'application/json',
2020-03-22 20:36:19 +00:00
'Authorization': authHeader
}
2020-04-04 11:27:51 +00:00
postResult = \
postJson(session, newShareJson, [], inboxUrl, headers, "inbox:write")
if not postResult:
if debug:
print('DEBUG: POST announce failed for c2s to ' + inboxUrl)
# return 5
2019-07-23 19:02:26 +00:00
if debug:
2019-07-23 21:14:16 +00:00
print('DEBUG: c2s POST share item success')
2019-07-23 19:02:26 +00:00
return newShareJson
2019-07-23 20:00:17 +00:00
2020-04-04 11:27:51 +00:00
def sendUndoShareViaServer(baseDir: str, session,
fromNickname: str, password: str,
fromDomain: str, fromPort: int,
httpPrefix: str, displayName: str,
cachedWebfingers: {}, personCache: {},
debug: bool, projectVersion: str) -> {}:
2019-07-23 21:14:16 +00:00
"""Undoes a share via c2s
"""
if not session:
print('WARN: No session for sendUndoShareViaServer')
return 6
2020-04-04 11:27:51 +00:00
fromDomainFull = fromDomain
if fromPort:
2020-04-04 11:27:51 +00:00
if fromPort != 80 and fromPort != 443:
if ':' not in fromDomain:
2020-04-04 11:27:51 +00:00
fromDomainFull = fromDomain + ':' + str(fromPort)
2019-07-23 21:14:16 +00:00
2020-04-04 11:27:51 +00:00
toUrl = 'https://www.w3.org/ns/activitystreams#Public'
ccUrl = httpPrefix + '://' + fromDomainFull + \
'/users/' + fromNickname + '/followers'
2019-07-23 21:14:16 +00:00
2020-04-04 11:27:51 +00:00
actor = httpPrefix + '://' + fromDomainFull + '/users/' + fromNickname
undoShareJson = {
2019-08-18 11:07:06 +00:00
"@context": "https://www.w3.org/ns/activitystreams",
2019-07-23 21:14:16 +00:00
'type': 'Remove',
2020-04-04 11:27:51 +00:00
'actor': actor,
'target': actor + '/shares',
2019-07-23 21:14:16 +00:00
'object': {
"type": "Offer",
"displayName": displayName,
'to': [toUrl],
'cc': [ccUrl]
},
'to': [toUrl],
'cc': [ccUrl]
}
2020-04-04 11:27:51 +00:00
handle = httpPrefix + '://' + fromDomainFull + '/@' + fromNickname
2019-07-23 21:14:16 +00:00
# lookup the inbox for the To handle
2020-04-04 11:27:51 +00:00
wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion)
2019-07-23 21:14:16 +00:00
if not wfRequest:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: announce webfinger failed for ' + handle)
2019-07-23 21:14:16 +00:00
return 1
2020-06-23 10:41:12 +00:00
if not isinstance(wfRequest, dict):
print('WARN: Webfinger for ' + handle + ' did not return a dict. ' +
str(wfRequest))
return 1
2019-07-23 21:14:16 +00:00
2020-04-04 11:27:51 +00:00
postToBox = 'outbox'
2019-07-23 21:14:16 +00:00
# get the actor inbox for the To handle
2020-04-04 11:27:51 +00:00
(inboxUrl, pubKeyId, pubKey,
fromPersonId, sharedInbox,
capabilityAcquisition,
avatarUrl, displayName) = getPersonBox(baseDir, session, wfRequest,
personCache, projectVersion,
httpPrefix, fromNickname,
fromDomain, postToBox)
2020-03-22 21:16:02 +00:00
2019-07-23 21:14:16 +00:00
if not inboxUrl:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: No '+postToBox+' was found for ' + handle)
2019-07-23 21:14:16 +00:00
return 3
if not fromPersonId:
if debug:
2020-04-04 11:27:51 +00:00
print('DEBUG: No actor was found for ' + handle)
2019-07-23 21:14:16 +00:00
return 4
2020-03-22 21:16:02 +00:00
2020-04-04 11:27:51 +00:00
authHeader = createBasicAuthHeader(fromNickname, password)
2020-03-22 21:16:02 +00:00
2020-04-04 11:27:51 +00:00
headers = {
'host': fromDomain,
'Content-type': 'application/json',
2020-03-22 20:36:19 +00:00
'Authorization': authHeader
}
2020-04-04 11:27:51 +00:00
postResult = \
postJson(session, undoShareJson, [], inboxUrl, headers, "inbox:write")
if not postResult:
if debug:
print('DEBUG: POST announce failed for c2s to ' + inboxUrl)
# return 5
2019-07-23 21:14:16 +00:00
if debug:
print('DEBUG: c2s POST undo share success')
return undoShareJson
2020-04-04 11:27:51 +00:00
def outboxShareUpload(baseDir: str, httpPrefix: str,
nickname: str, domain: str, port: int,
messageJson: {}, debug: bool) -> None:
2019-07-23 20:00:17 +00:00
""" When a shared item is received by the outbox from c2s
"""
if not messageJson.get('type'):
return
2020-04-04 11:27:51 +00:00
if not messageJson['type'] == 'Add':
2019-07-23 20:00:17 +00:00
return
if not messageJson.get('object'):
return
if not isinstance(messageJson['object'], dict):
return
if not messageJson['object'].get('type'):
if debug:
print('DEBUG: undo block - no type')
return
2020-04-04 11:27:51 +00:00
if not messageJson['object']['type'] == 'Offer':
2019-07-23 20:00:17 +00:00
if debug:
print('DEBUG: not an Offer activity')
return
if not messageJson['object'].get('displayName'):
if debug:
print('DEBUG: displayName missing from Offer')
return
if not messageJson['object'].get('summary'):
if debug:
print('DEBUG: summary missing from Offer')
return
if not messageJson['object'].get('itemType'):
if debug:
print('DEBUG: itemType missing from Offer')
return
if not messageJson['object'].get('category'):
if debug:
print('DEBUG: category missing from Offer')
return
if not messageJson['object'].get('location'):
if debug:
print('DEBUG: location missing from Offer')
return
if not messageJson['object'].get('duration'):
if debug:
print('DEBUG: duration missing from Offer')
return
2020-04-04 11:27:51 +00:00
addShare(baseDir,
httpPrefix, nickname, domain, port,
messageJson['object']['displayName'],
messageJson['object']['summary'],
messageJson['object']['imageFilename'],
messageJson['object']['itemType'],
messageJson['object']['itemCategory'],
messageJson['object']['location'],
messageJson['object']['duration'],
2019-07-23 20:00:17 +00:00
debug)
if debug:
print('DEBUG: shared item received via c2s')
2019-07-23 21:14:16 +00:00
2020-04-04 11:27:51 +00:00
def outboxUndoShareUpload(baseDir: str, httpPrefix: str,
nickname: str, domain: str, port: int,
messageJson: {}, debug: bool) -> None:
2019-07-23 21:14:16 +00:00
""" When a shared item is removed via c2s
"""
if not messageJson.get('type'):
return
2020-04-04 11:27:51 +00:00
if not messageJson['type'] == 'Remove':
2019-07-23 21:14:16 +00:00
return
if not messageJson.get('object'):
return
if not isinstance(messageJson['object'], dict):
return
if not messageJson['object'].get('type'):
if debug:
print('DEBUG: undo block - no type')
return
2020-04-04 11:27:51 +00:00
if not messageJson['object']['type'] == 'Offer':
2019-07-23 21:14:16 +00:00
if debug:
print('DEBUG: not an Offer activity')
return
if not messageJson['object'].get('displayName'):
if debug:
print('DEBUG: displayName missing from Offer')
return
2020-04-04 11:27:51 +00:00
removeShare(baseDir, nickname, domain,
2019-07-23 21:14:16 +00:00
messageJson['object']['displayName'])
if debug:
print('DEBUG: shared item removed via c2s')