Function to check that activitypub posts have an object dictionary

merge-requests/30/head
Bob Mottram 2021-06-22 16:45:59 +01:00
parent 80f43a728a
commit 939e053e5b
20 changed files with 274 additions and 381 deletions

View File

@ -15,6 +15,7 @@ from utils import getDomainFromActor
from utils import getNicknameFromActor from utils import getNicknameFromActor
from utils import domainPermitted from utils import domainPermitted
from utils import followPerson from utils import followPerson
from utils import hasObjectDict
def _createAcceptReject(baseDir: str, federationList: [], def _createAcceptReject(baseDir: str, federationList: [],
@ -73,7 +74,7 @@ def _acceptFollow(baseDir: str, domain: str, messageJson: {},
federationList: [], debug: bool) -> None: federationList: [], debug: bool) -> None:
"""Receiving a follow Accept activity """Receiving a follow Accept activity
""" """
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
return return

View File

@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
__status__ = "Production" __status__ = "Production"
__module_group__ = "ActivityPub" __module_group__ = "ActivityPub"
from utils import hasObjectDict
from utils import removeIdEnding from utils import removeIdEnding
from utils import hasUsersPath from utils import hasUsersPath
from utils import getFullDomain from utils import getFullDomain
@ -356,9 +357,7 @@ def outboxUndoAnnounce(recentPostsCache: {},
return return
if not messageJson['type'] == 'Undo': if not messageJson['type'] == 'Undo':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
if debug: if debug:
print('DEBUG: undo like object is not dict') print('DEBUG: undo like object is not dict')
return return

View File

@ -11,6 +11,7 @@ import os
import json import json
import time import time
from datetime import datetime from datetime import datetime
from utils import hasObjectDict
from utils import isAccountDir from utils import isAccountDir
from utils import getCachedPostFilename from utils import getCachedPostFilename
from utils import loadJson from utils import loadJson
@ -372,11 +373,7 @@ def outboxUndoBlock(baseDir: str, httpPrefix: str,
if debug: if debug:
print('DEBUG: not an undo block') print('DEBUG: not an undo block')
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug:
print('DEBUG: no object in undo block')
return
if not isinstance(messageJson['object'], dict):
if debug: if debug:
print('DEBUG: undo block object is not string') print('DEBUG: undo block object is not string')
return return
@ -444,8 +441,7 @@ def mutePost(baseDir: str, nickname: str, domain: str, port: int,
if not postJsonObject: if not postJsonObject:
return return
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
actor = httpPrefix + '://' + domainFull + '/users/' + nickname actor = httpPrefix + '://' + domainFull + '/users/' + nickname
# does this post have ignores on it from differenent actors? # does this post have ignores on it from differenent actors?
@ -525,8 +521,7 @@ def unmutePost(baseDir: str, nickname: str, domain: str, port: int,
os.remove(muteFilename) os.remove(muteFilename)
print('UNMUTE: ' + muteFilename + ' file removed') print('UNMUTE: ' + muteFilename + ' file removed')
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('ignores'): if postJsonObject['object'].get('ignores'):
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
actor = httpPrefix + '://' + domainFull + '/users/' + nickname actor = httpPrefix + '://' + domainFull + '/users/' + nickname
@ -646,9 +641,7 @@ def outboxUndoMute(baseDir: str, httpPrefix: str,
return return
if not messageJson['type'] == 'Undo': if not messageJson['type'] == 'Undo':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
return return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
return return

View File

@ -22,6 +22,7 @@ from utils import locatePost
from utils import getCachedPostFilename from utils import getCachedPostFilename
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import hasObjectDict
from posts import getPersonBox from posts import getPersonBox
from session import postJson from session import postJson
@ -68,13 +69,11 @@ def undoBookmarksCollectionEntry(recentPostsCache: {},
return return
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return return
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
if debug: if debug:
print('DEBUG: bookmarked post has no object ' + print('DEBUG: bookmarked post has no object ' +
str(postJsonObject)) str(postJsonObject))
return return
if not isinstance(postJsonObject['object'], dict):
return
if not postJsonObject['object'].get('bookmarks'): if not postJsonObject['object'].get('bookmarks'):
return return
if not isinstance(postJsonObject['object']['bookmarks'], dict): if not isinstance(postJsonObject['object']['bookmarks'], dict):
@ -123,9 +122,7 @@ def bookmarkedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool:
def _noOfBookmarks(postJsonObject: {}) -> int: def _noOfBookmarks(postJsonObject: {}) -> int:
"""Returns the number of bookmarks ona given post """Returns the number of bookmarks ona given post
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return 0
if not isinstance(postJsonObject['object'], dict):
return 0 return 0
if not postJsonObject['object'].get('bookmarks'): if not postJsonObject['object'].get('bookmarks'):
return 0 return 0
@ -527,7 +524,7 @@ def outboxBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no actor in bookmark Add') print('DEBUG: no actor in bookmark Add')
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: no object in bookmark Add') print('DEBUG: no object in bookmark Add')
return return
@ -535,10 +532,6 @@ def outboxBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no target in bookmark Add') print('DEBUG: no target in bookmark Add')
return return
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: bookmark Add object is not dict')
return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: no object type in bookmark Add') print('DEBUG: no object type in bookmark Add')
@ -596,7 +589,7 @@ def outboxUndoBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no actor in unbookmark Remove') print('DEBUG: no actor in unbookmark Remove')
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: no object in unbookmark Remove') print('DEBUG: no object in unbookmark Remove')
return return
@ -604,10 +597,6 @@ def outboxUndoBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no target in unbookmark Remove') print('DEBUG: no target in unbookmark Remove')
return return
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: unbookmark Remove object is not dict')
return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: no object type in bookmark Remove') print('DEBUG: no object type in bookmark Remove')

View File

@ -208,6 +208,7 @@ from shares import addShare
from shares import removeShare from shares import removeShare
from shares import expireShares from shares import expireShares
from categories import setHashtagCategory from categories import setHashtagCategory
from utils import hasObjectDict
from utils import userAgentDomain from utils import userAgentDomain
from utils import isLocalNetworkAddress from utils import isLocalNetworkAddress
from utils import permittedDir from utils import permittedDir
@ -1173,8 +1174,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.POSTbusy = False self.server.POSTbusy = False
return 3 return 3
if messageJson.get('object'): if hasObjectDict(messageJson):
if isinstance(messageJson['object'], dict):
stringFields = ( stringFields = (
'id', 'actor', 'type', 'content', 'published', 'id', 'actor', 'type', 'content', 'published',
'summary', 'url', 'attributedTo' 'summary', 'url', 'attributedTo'

View File

@ -16,6 +16,7 @@ import webbrowser
import urllib.parse import urllib.parse
from pathlib import Path from pathlib import Path
from random import randint from random import randint
from utils import hasObjectDict
from utils import getFullDomain from utils import getFullDomain
from utils import isDM from utils import isDM
from utils import loadTranslationsFromFile from utils import loadTranslationsFromFile
@ -207,8 +208,7 @@ def _postIsToYou(actor: str, postJsonObject: {}) -> bool:
if not toYourActor and postJsonObject.get('cc'): if not toYourActor and postJsonObject.get('cc'):
if actor in postJsonObject['cc']: if actor in postJsonObject['cc']:
toYourActor = True toYourActor = True
if not toYourActor and postJsonObject.get('object'): if not toYourActor and hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('to'): if postJsonObject['object'].get('to'):
if actor in postJsonObject['object']['to']: if actor in postJsonObject['object']['to']:
toYourActor = True toYourActor = True
@ -606,9 +606,7 @@ def _getImageDescription(postJsonObject: {}) -> str:
def _showLikesOnPost(postJsonObject: {}, maxLikes: int) -> None: def _showLikesOnPost(postJsonObject: {}, maxLikes: int) -> None:
"""Shows the likes on a post """Shows the likes on a post
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('likes'): if not postJsonObject['object'].get('likes'):
return return
@ -630,9 +628,7 @@ def _showLikesOnPost(postJsonObject: {}, maxLikes: int) -> None:
def _showRepliesOnPost(postJsonObject: {}, maxReplies: int) -> None: def _showRepliesOnPost(postJsonObject: {}, maxReplies: int) -> None:
"""Shows the replies on a post """Shows the replies on a post
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('replies'): if not postJsonObject['object'].get('replies'):
return return
@ -693,7 +689,7 @@ def _readLocalBoxPost(session, nickname: str, domain: str,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache, False) recentPostsCache, False)
if postJsonObject2: if postJsonObject2:
if postJsonObject2.get('object'): if hasObjectDict(postJsonObject2):
if postJsonObject2['object'].get('attributedTo') and \ if postJsonObject2['object'].get('attributedTo') and \
postJsonObject2['object'].get('content'): postJsonObject2['object'].get('content'):
actor = postJsonObject2['object']['attributedTo'] actor = postJsonObject2['object']['attributedTo']
@ -879,7 +875,7 @@ def _desktopGetBoxPostObject(boxJson: {}, index: int) -> {}:
if ctr == index: if ctr == index:
return postJsonObject return postJsonObject
continue continue
if not isinstance(postJsonObject['object'], dict): if not hasObjectDict(postJsonObject):
continue continue
if not postJsonObject['object'].get('published'): if not postJsonObject['object'].get('published'):
continue continue
@ -991,9 +987,7 @@ def _desktopShowBox(indent: str,
ctr += 1 ctr += 1
continue continue
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
continue
if not isinstance(postJsonObject['object'], dict):
continue continue
if not postJsonObject['object'].get('published'): if not postJsonObject['object'].get('published'):
continue continue
@ -1888,7 +1882,7 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
if postJsonObject: if postJsonObject:
if postJsonObject.get('id') and \ if postJsonObject.get('id') and \
postJsonObject.get('object'): postJsonObject.get('object'):
if isinstance(postJsonObject['object'], dict): if hasObjectDict(postJsonObject):
if postJsonObject['object'].get('attributedTo'): if postJsonObject['object'].get('attributedTo'):
blockActor = \ blockActor = \
postJsonObject['object']['attributedTo'] postJsonObject['object']['attributedTo']
@ -1932,7 +1926,7 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str,
if postJsonObject and not blockActor: if postJsonObject and not blockActor:
if postJsonObject.get('id') and \ if postJsonObject.get('id') and \
postJsonObject.get('object'): postJsonObject.get('object'):
if isinstance(postJsonObject['object'], dict): if hasObjectDict(postJsonObject):
if postJsonObject['object'].get('attributedTo'): if postJsonObject['object'].get('attributedTo'):
blockActor = \ blockActor = \
postJsonObject['object']['attributedTo'] postJsonObject['object']['attributedTo']

View File

@ -9,6 +9,7 @@ __module_group__ = "ActivityPub"
from pprint import pprint from pprint import pprint
import os import os
from utils import hasObjectDict
from utils import hasUsersPath from utils import hasUsersPath
from utils import getFullDomain from utils import getFullDomain
from utils import isSystemAccount from utils import isSystemAccount
@ -1391,9 +1392,7 @@ def outboxUndoFollow(baseDir: str, messageJson: {}, debug: bool) -> None:
return return
if not messageJson['type'] == 'Undo': if not messageJson['type'] == 'Undo':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
return return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
return return

5
git.py
View File

@ -9,6 +9,7 @@ __module_group__ = "ActivityPub"
import os import os
import html import html
from utils import hasObjectDict
def _gitFormatContent(content: str) -> str: def _gitFormatContent(content: str) -> str:
@ -113,9 +114,7 @@ def convertPostToPatch(baseDir: str, nickname: str, domain: str,
"""Detects whether the given post contains a patch """Detects whether the given post contains a patch
and if so then converts it to a Patch ActivityPub type and if so then converts it to a Patch ActivityPub type
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('type'): if not postJsonObject['object'].get('type'):
return False return False

View File

@ -16,6 +16,7 @@ from utils import isPublicPost
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import locatePost from utils import locatePost
from utils import hasObjectDict
def _validUuid(testUuid: str, version=4): def _validUuid(testUuid: str, version=4):
@ -155,9 +156,7 @@ def _isHappeningPost(postJsonObject: {}) -> bool:
""" """
if not postJsonObject: if not postJsonObject:
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('tag'): if not postJsonObject['object'].get('tag'):
return False return False

View File

@ -13,6 +13,7 @@ import datetime
import time import time
import random import random
from linked_data_sig import verifyJsonSignature from linked_data_sig import verifyJsonSignature
from utils import hasObjectDict
from utils import dmAllowedFromDomain from utils import dmAllowedFromDomain
from utils import isRecentPost from utils import isRecentPost
from utils import getConfigParam from utils import getConfigParam
@ -91,9 +92,7 @@ def storeHashTags(baseDir: str, nickname: str, postJsonObject: {}) -> None:
""" """
if not isPublicPost(postJsonObject): if not isPublicPost(postJsonObject):
return return
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('tag'): if not postJsonObject['object'].get('tag'):
return return
@ -331,10 +330,8 @@ def inboxPermittedMessage(domain: str, messageJson: {},
alwaysAllowedTypes = ('Follow', 'Join', 'Like', 'Delete', 'Announce') alwaysAllowedTypes = ('Follow', 'Join', 'Like', 'Delete', 'Announce')
if messageJson['type'] not in alwaysAllowedTypes: if messageJson['type'] not in alwaysAllowedTypes:
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return True return True
if not isinstance(messageJson['object'], dict):
return False
if messageJson['object'].get('inReplyTo'): if messageJson['object'].get('inReplyTo'):
inReplyTo = messageJson['object']['inReplyTo'] inReplyTo = messageJson['object']['inReplyTo']
if not isinstance(inReplyTo, str): if not isinstance(inReplyTo, str):
@ -390,8 +387,7 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str,
return None return None
postDomain = getFullDomain(postDomain, postPort) postDomain = getFullDomain(postDomain, postPort)
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('inReplyTo'): if postJsonObject['object'].get('inReplyTo'):
if isinstance(postJsonObject['object']['inReplyTo'], str): if isinstance(postJsonObject['object']['inReplyTo'], str):
inReplyTo = \ inReplyTo = \
@ -550,8 +546,7 @@ def _inboxPostRecipients(baseDir: str, postJsonObject: {},
# first get any specific people which the post is addressed to # first get any specific people which the post is addressed to
followerRecipients = False followerRecipients = False
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('to'): if postJsonObject['object'].get('to'):
if isinstance(postJsonObject['object']['to'], list): if isinstance(postJsonObject['object']['to'], list):
recipientsList = postJsonObject['object']['to'] recipientsList = postJsonObject['object']['to']
@ -588,7 +583,7 @@ def _inboxPostRecipients(baseDir: str, postJsonObject: {},
if debug: if debug:
print('DEBUG: inbox post has no cc') print('DEBUG: inbox post has no cc')
else: else:
if debug: if debug and postJsonObject.get('object'):
if isinstance(postJsonObject['object'], str): if isinstance(postJsonObject['object'], str):
if '/statuses/' in postJsonObject['object']: if '/statuses/' in postJsonObject['object']:
print('DEBUG: inbox item is a link to a post') print('DEBUG: inbox item is a link to a post')
@ -709,14 +704,10 @@ def _receiveUndo(session, baseDir: str, httpPrefix: str,
if debug: if debug:
print('DEBUG: "users" or "profile" missing from actor') print('DEBUG: "users" or "profile" missing from actor')
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: ' + messageJson['type'] + ' has no object') print('DEBUG: ' + messageJson['type'] + ' has no object')
return False return False
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: ' + messageJson['type'] + ' object is not a dict')
return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: ' + messageJson['type'] + ' has no object type') print('DEBUG: ' + messageJson['type'] + ' has no object type')
@ -884,14 +875,10 @@ def _receiveUpdate(recentPostsCache: {}, session, baseDir: str,
if debug: if debug:
print('DEBUG: ' + messageJson['type'] + ' has no actor') print('DEBUG: ' + messageJson['type'] + ' has no actor')
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: ' + messageJson['type'] + ' has no object') print('DEBUG: ' + messageJson['type'] + ' has no object')
return False return False
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: ' + messageJson['type'] + ' object is not a dict')
return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: ' + messageJson['type'] + ' object has no type') print('DEBUG: ' + messageJson['type'] + ' object has no type')
@ -1031,9 +1018,7 @@ def _receiveUndoLike(recentPostsCache: {},
return False return False
if not messageJson.get('actor'): if not messageJson.get('actor'):
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return False
if not isinstance(messageJson['object'], dict):
return False return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
return False return False
@ -1095,7 +1080,7 @@ def _receiveBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no actor in inbox bookmark Add') print('DEBUG: no actor in inbox bookmark Add')
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: no object in inbox bookmark Add') print('DEBUG: no object in inbox bookmark Add')
return False return False
@ -1103,10 +1088,6 @@ def _receiveBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no target in inbox bookmark Add') print('DEBUG: no target in inbox bookmark Add')
return False return False
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: inbox bookmark Add object is not string')
return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: no object type in inbox bookmark Add') print('DEBUG: no object type in inbox bookmark Add')
@ -1174,7 +1155,7 @@ def _receiveUndoBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no actor in inbox undo bookmark Remove') print('DEBUG: no actor in inbox undo bookmark Remove')
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
if debug: if debug:
print('DEBUG: no object in inbox undo bookmark Remove') print('DEBUG: no object in inbox undo bookmark Remove')
return False return False
@ -1182,10 +1163,6 @@ def _receiveUndoBookmark(recentPostsCache: {},
if debug: if debug:
print('DEBUG: no target in inbox undo bookmark Remove') print('DEBUG: no target in inbox undo bookmark Remove')
return False return False
if not isinstance(messageJson['object'], dict):
if debug:
print('DEBUG: inbox Remove bookmark object is not dict')
return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
print('DEBUG: no object type in inbox bookmark Remove') print('DEBUG: no object type in inbox bookmark Remove')
@ -1439,8 +1416,7 @@ def _receiveAnnounce(recentPostsCache: {},
if isinstance(postJsonObject['attributedTo'], str): if isinstance(postJsonObject['attributedTo'], str):
lookupActor = postJsonObject['attributedTo'] lookupActor = postJsonObject['attributedTo']
else: else:
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('attributedTo'): if postJsonObject['object'].get('attributedTo'):
attrib = postJsonObject['object']['attributedTo'] attrib = postJsonObject['object']['attributedTo']
if isinstance(attrib, str): if isinstance(attrib, str):
@ -1497,9 +1473,7 @@ def _receiveUndoAnnounce(recentPostsCache: {},
return False return False
if not messageJson.get('actor'): if not messageJson.get('actor'):
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return False
if not isinstance(messageJson['object'], dict):
return False return False
if not messageJson['object'].get('object'): if not messageJson['object'].get('object'):
return False return False
@ -1548,9 +1522,9 @@ def jsonPostAllowsComments(postJsonObject: {}) -> bool:
if 'commentsEnabled' in postJsonObject: if 'commentsEnabled' in postJsonObject:
return postJsonObject['commentsEnabled'] return postJsonObject['commentsEnabled']
if postJsonObject.get('object'): if postJsonObject.get('object'):
if not isinstance(postJsonObject['object'], dict): if not hasObjectDict(postJsonObject):
return False return False
if 'commentsEnabled' in postJsonObject['object']: elif 'commentsEnabled' in postJsonObject['object']:
return postJsonObject['object']['commentsEnabled'] return postJsonObject['object']['commentsEnabled']
return True return True
@ -1571,9 +1545,7 @@ def populateReplies(baseDir: str, httpPrefix: str, domain: str,
""" """
if not messageJson.get('id'): if not messageJson.get('id'):
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return False
if not isinstance(messageJson['object'], dict):
return False return False
if not messageJson['object'].get('inReplyTo'): if not messageJson['object'].get('inReplyTo'):
return False return False
@ -1666,9 +1638,7 @@ def _validPostContent(baseDir: str, nickname: str, domain: str,
Check for hellthreads Check for hellthreads
Check number of tags is reasonable Check number of tags is reasonable
""" """
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return True
if not isinstance(messageJson['object'], dict):
return True return True
if not messageJson['object'].get('content'): if not messageJson['object'].get('content'):
return True return True
@ -1756,10 +1726,7 @@ def _obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
"""Tries to obtain the actor for the person being replied to """Tries to obtain the actor for the person being replied to
so that their avatar can later be shown so that their avatar can later be shown
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('inReplyTo'): if not postJsonObject['object'].get('inReplyTo'):
@ -1821,9 +1788,7 @@ def _alreadyLiked(baseDir: str, nickname: str, domain: str,
postJsonObject = loadJson(postFilename, 1) postJsonObject = loadJson(postFilename, 1)
if not postJsonObject: if not postJsonObject:
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('likes'): if not postJsonObject['object'].get('likes'):
return False return False
@ -2039,9 +2004,7 @@ def _inboxUpdateCalendar(baseDir: str, handle: str,
""" """
if not postJsonObject.get('actor'): if not postJsonObject.get('actor'):
return return
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('tag'): if not postJsonObject['object'].get('tag'):
return return

View File

@ -7,6 +7,7 @@ __email__ = "bob@freedombone.net"
__status__ = "Production" __status__ = "Production"
__module_group__ = "ActivityPub" __module_group__ = "ActivityPub"
from utils import hasObjectDict
from utils import hasUsersPath from utils import hasUsersPath
from utils import getFullDomain from utils import getFullDomain
from utils import removeIdEnding from utils import removeIdEnding
@ -38,9 +39,7 @@ def likedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool:
def noOfLikes(postJsonObject: {}) -> int: def noOfLikes(postJsonObject: {}) -> int:
"""Returns the number of likes ona given post """Returns the number of likes ona given post
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return 0
if not isinstance(postJsonObject['object'], dict):
return 0 return 0
if not postJsonObject['object'].get('likes'): if not postJsonObject['object'].get('likes'):
return 0 return 0
@ -354,9 +353,7 @@ def outboxUndoLike(recentPostsCache: {},
return return
if not messageJson['type'] == 'Undo': if not messageJson['type'] == 'Undo':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
if debug: if debug:
print('DEBUG: undo like object is not dict') print('DEBUG: undo like object is not dict')
return return

View File

@ -18,6 +18,7 @@ from datetime import timezone
from collections import OrderedDict from collections import OrderedDict
from utils import validPostDate from utils import validPostDate
from categories import setHashtagCategory from categories import setHashtagCategory
from utils import hasObjectDict
from utils import firstParagraphFromString from utils import firstParagraphFromString
from utils import isPublicPost from utils import isPublicPost
from utils import locatePost from utils import locatePost
@ -839,9 +840,7 @@ def _isNewswireBlogPost(postJsonObject: {}) -> bool:
""" """
if not postJsonObject: if not postJsonObject:
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if postJsonObject['object'].get('summary') and \ if postJsonObject['object'].get('summary') and \
postJsonObject['object'].get('url') and \ postJsonObject['object'].get('url') and \
@ -854,9 +853,7 @@ def _isNewswireBlogPost(postJsonObject: {}) -> bool:
def _getHashtagsFromPost(postJsonObject: {}) -> []: def _getHashtagsFromPost(postJsonObject: {}) -> []:
"""Returns a list of any hashtags within a post """Returns a list of any hashtags within a post
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return []
if not isinstance(postJsonObject['object'], dict):
return [] return []
if not postJsonObject['object'].get('tag'): if not postJsonObject['object'].get('tag'):
return [] return []

View File

@ -16,6 +16,7 @@ from posts import outboxMessageCreateWrap
from posts import savePostToBox from posts import savePostToBox
from posts import sendToFollowersThread from posts import sendToFollowersThread
from posts import sendToNamedAddresses from posts import sendToNamedAddresses
from utils import hasObjectDict
from utils import getLocalNetworkAddresses from utils import getLocalNetworkAddresses
from utils import getFullDomain from utils import getFullDomain
from utils import removeIdEnding from utils import removeIdEnding
@ -62,9 +63,7 @@ def _outboxPersonReceiveUpdate(recentPostsCache: {},
print("messageJson['type'] " + messageJson['type']) print("messageJson['type'] " + messageJson['type'])
if messageJson['type'] != 'Update': if messageJson['type'] != 'Update':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
if debug: if debug:
print('DEBUG: c2s actor update object is not dict') print('DEBUG: c2s actor update object is not dict')
return return
@ -199,8 +198,7 @@ def postMessageToOutbox(session, translate: {},
# check that the outgoing post doesn't contain any markup # check that the outgoing post doesn't contain any markup
# which can be used to implement exploits # which can be used to implement exploits
if messageJson.get('object'): if hasObjectDict(messageJson):
if isinstance(messageJson['object'], dict):
if messageJson['object'].get('content'): if messageJson['object'].get('content'):
if dangerousMarkup(messageJson['object']['content'], if dangerousMarkup(messageJson['object']['content'],
allowLocalNetworkAccess): allowLocalNetworkAccess):
@ -335,8 +333,7 @@ def postMessageToOutbox(session, translate: {},
# if this is a blog post or an event then save to its own box # if this is a blog post or an event then save to its own box
if messageJson['type'] == 'Create': if messageJson['type'] == 'Create':
if messageJson.get('object'): if hasObjectDict(messageJson):
if isinstance(messageJson['object'], dict):
if messageJson['object'].get('type'): if messageJson['object'].get('type'):
if messageJson['object']['type'] == 'Article': if messageJson['object']['type'] == 'Article':
outboxName = 'tlblogs' outboxName = 'tlblogs'

View File

@ -32,6 +32,7 @@ from session import postImage
from webfinger import webfingerHandle from webfinger import webfingerHandle
from httpsig import createSignedHeader from httpsig import createSignedHeader
from siteactive import siteIsActive from siteactive import siteIsActive
from utils import hasObjectDict
from utils import rejectPostId from utils import rejectPostId
from utils import removeInvalidChars from utils import removeInvalidChars
from utils import fileLastModified from utils import fileLastModified
@ -361,11 +362,7 @@ def _getPosts(session, outboxUrl: str, maxPosts: int,
if debug: if debug:
print('Not Create type') print('Not Create type')
continue continue
if not item.get('object'): if not hasObjectDict(item):
if debug:
print('No object')
continue
if not isinstance(item['object'], dict):
if debug: if debug:
print('item object is not a dict') print('item object is not a dict')
continue continue
@ -561,9 +558,7 @@ def getPostDomains(session, outboxUrl: str, maxPosts: int,
i += 1 i += 1
if i > maxPosts: if i > maxPosts:
break break
if not item.get('object'): if not hasObjectDict(item):
continue
if not isinstance(item['object'], dict):
continue continue
if item['object'].get('content'): if item['object'].get('content'):
_updateWordFrequency(item['object']['content'], _updateWordFrequency(item['object']['content'],
@ -618,9 +613,7 @@ def _getPostsForBlockedDomains(baseDir: str,
i += 1 i += 1
if i > maxPosts: if i > maxPosts:
break break
if not item.get('object'): if not hasObjectDict(item):
continue
if not isinstance(item['object'], dict):
continue continue
if item['object'].get('inReplyTo'): if item['object'].get('inReplyTo'):
if isinstance(item['object']['inReplyTo'], str): if isinstance(item['object']['inReplyTo'], str):
@ -699,8 +692,7 @@ def savePostToBox(baseDir: str, httpPrefix: str, postId: str,
httpPrefix + '://' + originalDomain + '/users/' + nickname + \ httpPrefix + '://' + originalDomain + '/users/' + nickname + \
'/statuses/' + statusNumber '/statuses/' + statusNumber
postJsonObject['id'] = postId + '/activity' postJsonObject['id'] = postId + '/activity'
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
postJsonObject['object']['id'] = postId postJsonObject['object']['id'] = postId
postJsonObject['object']['atomUri'] = postId postJsonObject['object']['atomUri'] = postId
@ -2391,7 +2383,7 @@ def addToField(activityType: str, postJsonObject: {},
toAddress = toAddress.split('/statuses/')[0] toAddress = toAddress.split('/statuses/')[0]
postJsonObject['to'] = [toAddress] postJsonObject['to'] = [toAddress]
toFieldAdded = True toFieldAdded = True
elif isinstance(postJsonObject['object'], dict): elif hasObjectDict(postJsonObject):
# add a to field to bookmark add or remove # add a to field to bookmark add or remove
if postJsonObject.get('type') and \ if postJsonObject.get('type') and \
postJsonObject.get('actor') and \ postJsonObject.get('actor') and \
@ -2590,9 +2582,7 @@ def _sendingProfileUpdate(postJsonObject: {}) -> bool:
""" """
if postJsonObject['type'] != 'Update': if postJsonObject['type'] != 'Update':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('type'): if not postJsonObject['object'].get('type'):
return False return False
@ -2970,9 +2960,7 @@ def isImageMedia(session, baseDir: str, httpPrefix: str,
postJsonObject = postJsonAnnounce postJsonObject = postJsonAnnounce
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if postJsonObject['object'].get('moderationStatus'): if postJsonObject['object'].get('moderationStatus'):
return False return False
@ -3057,8 +3045,7 @@ def removePostInteractions(postJsonObject: {}, force: bool) -> bool:
Returns False if this is a private post Returns False if this is a private post
""" """
hasObject = False hasObject = False
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
hasObject = True hasObject = True
if hasObject: if hasObject:
postObj = postJsonObject['object'] postObj = postJsonObject['object']
@ -3921,9 +3908,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
recentPostsCache: {}, debug: bool) -> {}: recentPostsCache: {}, debug: bool) -> {}:
"""Download the post referenced by an announce """Download the post referenced by an announce
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return None
if not isinstance(postJsonObject['object'], str):
return None return None
# ignore self-boosts # ignore self-boosts
if postJsonObject['actor'] in postJsonObject['object']: if postJsonObject['actor'] in postJsonObject['object']:

View File

@ -11,6 +11,7 @@ import os
from utils import locatePost from utils import locatePost
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import hasObjectDict
def questionUpdateVotes(baseDir: str, nickname: str, domain: str, def questionUpdateVotes(baseDir: str, nickname: str, domain: str,
@ -18,9 +19,7 @@ def questionUpdateVotes(baseDir: str, nickname: str, domain: str,
""" For a given reply update the votes on a question """ For a given reply update the votes on a question
Returns the question json object if the vote totals were changed Returns the question json object if the vote totals were changed
""" """
if not replyJson.get('object'): if not hasObjectDict(replyJson):
return None
if not isinstance(replyJson['object'], dict):
return None return None
if not replyJson['object'].get('inReplyTo'): if not replyJson['object'].get('inReplyTo'):
return None return None
@ -37,9 +36,7 @@ def questionUpdateVotes(baseDir: str, nickname: str, domain: str,
questionJson = loadJson(questionPostFilename) questionJson = loadJson(questionPostFilename)
if not questionJson: if not questionJson:
return None return None
if not questionJson.get('object'): if not hasObjectDict(questionJson):
return None
if not isinstance(questionJson['object'], dict):
return None return None
if not questionJson['object'].get('type'): if not questionJson['object'].get('type'):
return None return None

View File

@ -10,6 +10,7 @@ __module_group__ = "Calendar"
import os import os
import time import time
import datetime import datetime
from utils import hasObjectDict
from utils import getStatusNumber from utils import getStatusNumber
from utils import loadJson from utils import loadJson
from outbox import postMessageToOutbox from outbox import postMessageToOutbox
@ -77,8 +78,7 @@ def _updatePostSchedule(baseDir: str, handle: str, httpd,
statusNumber, published = getStatusNumber() statusNumber, published = getStatusNumber()
if postJsonObject.get('published'): if postJsonObject.get('published'):
postJsonObject['published'] = published postJsonObject['published'] = published
if postJsonObject.get('object'): if hasObjectDict(postJsonObject):
if isinstance(postJsonObject['object'], dict):
if postJsonObject['object'].get('published'): if postJsonObject['object'].get('published'):
postJsonObject['published'] = published postJsonObject['published'] = published

View File

@ -19,6 +19,7 @@ from utils import validNickname
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import getImageExtensions from utils import getImageExtensions
from utils import hasObjectDict
from media import processMetaData from media import processMetaData
@ -524,9 +525,7 @@ def outboxShareUpload(baseDir: str, httpPrefix: str,
return return
if not messageJson['type'] == 'Add': if not messageJson['type'] == 'Add':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
return return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:
@ -583,9 +582,7 @@ def outboxUndoShareUpload(baseDir: str, httpPrefix: str,
return return
if not messageJson['type'] == 'Remove': if not messageJson['type'] == 'Remove':
return return
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return
if not isinstance(messageJson['object'], dict):
return return
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
if debug: if debug:

View File

@ -21,6 +21,7 @@ from utils import removeHtml
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from utils import isPGPEncrypted from utils import isPGPEncrypted
from utils import hasObjectDict
from content import htmlReplaceQuoteMarks from content import htmlReplaceQuoteMarks
speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!') speakerRemoveChars = ('.\n', '. ', ',', ';', '?', '!')
@ -407,9 +408,7 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str,
NOTE: There currently appears to be no standardized json NOTE: There currently appears to be no standardized json
format for speech synthesis format for speech synthesis
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return
if not isinstance(postJsonObject['object'], dict):
return return
if not postJsonObject['object'].get('content'): if not postJsonObject['object'].get('content'):
return return

View File

@ -1231,9 +1231,7 @@ def _isReplyToBlogPost(baseDir: str, nickname: str, domain: str,
postJsonObject: str): postJsonObject: str):
"""Is the given post a reply to a blog post? """Is the given post a reply to a blog post?
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('inReplyTo'): if not postJsonObject['object'].get('inReplyTo'):
return False return False
@ -1525,9 +1523,7 @@ def isPublicPost(postJsonObject: {}) -> bool:
return False return False
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('to'): if not postJsonObject['object'].get('to'):
return False return False
@ -1675,9 +1671,7 @@ def isEventPost(messageJson: {}) -> bool:
return False return False
if not messageJson.get('actor'): if not messageJson.get('actor'):
return False return False
if not messageJson.get('object'): if not hasObjectDict(messageJson):
return False
if not isinstance(messageJson['object'], dict):
return False return False
if not messageJson['object'].get('type'): if not messageJson['object'].get('type'):
return False return False
@ -1708,9 +1702,7 @@ def isBlogPost(postJsonObject: {}) -> bool:
""" """
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('type'): if not postJsonObject['object'].get('type'):
return False return False
@ -1863,13 +1855,11 @@ def undoLikesCollectionEntry(recentPostsCache: {},
return return
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return return
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
if debug: if debug:
pprint(postJsonObject) pprint(postJsonObject)
print('DEBUG: post ' + objectUrl + ' has no object') print('DEBUG: post ' + objectUrl + ' has no object')
return return
if not isinstance(postJsonObject['object'], dict):
return
if not postJsonObject['object'].get('likes'): if not postJsonObject['object'].get('likes'):
return return
if not isinstance(postJsonObject['object']['likes'], dict): if not isinstance(postJsonObject['object']['likes'], dict):
@ -1918,13 +1908,11 @@ def updateLikesCollection(recentPostsCache: {},
if os.path.isfile(cachedPostFilename): if os.path.isfile(cachedPostFilename):
os.remove(cachedPostFilename) os.remove(cachedPostFilename)
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
if debug: if debug:
pprint(postJsonObject) pprint(postJsonObject)
print('DEBUG: post ' + objectUrl + ' has no object') print('DEBUG: post ' + objectUrl + ' has no object')
return return
if not isinstance(postJsonObject['object'], dict):
return
if not objectUrl.endswith('/likes'): if not objectUrl.endswith('/likes'):
objectUrl = objectUrl + '/likes' objectUrl = objectUrl + '/likes'
if not postJsonObject['object'].get('likes'): if not postJsonObject['object'].get('likes'):
@ -1987,13 +1975,11 @@ def undoAnnounceCollectionEntry(recentPostsCache: {},
return return
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return return
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
if debug: if debug:
pprint(postJsonObject) pprint(postJsonObject)
print('DEBUG: post has no object') print('DEBUG: post has no object')
return return
if not isinstance(postJsonObject['object'], dict):
return
if not postJsonObject['object'].get('shares'): if not postJsonObject['object'].get('shares'):
return return
if not postJsonObject['object']['shares'].get('items'): if not postJsonObject['object']['shares'].get('items'):
@ -2045,13 +2031,11 @@ def updateAnnounceCollection(recentPostsCache: {},
os.remove(cachedPostFilename) os.remove(cachedPostFilename)
removePostFromCache(postJsonObject, recentPostsCache) removePostFromCache(postJsonObject, recentPostsCache)
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
if debug: if debug:
pprint(postJsonObject) pprint(postJsonObject)
print('DEBUG: post ' + postFilename + ' has no object') print('DEBUG: post ' + postFilename + ' has no object')
return return
if not isinstance(postJsonObject['object'], dict):
return
postUrl = removeIdEnding(postJsonObject['id']) + '/shares' postUrl = removeIdEnding(postJsonObject['id']) + '/shares'
if not postJsonObject['object'].get('shares'): if not postJsonObject['object'].get('shares'):
if debug: if debug:
@ -2129,9 +2113,7 @@ def mediaFileMimeType(filename: str) -> str:
def isRecentPost(postJsonObject: {}, maxDays=3) -> bool: def isRecentPost(postJsonObject: {}, maxDays=3) -> bool:
""" Is the given post recent? """ Is the given post recent?
""" """
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if not postJsonObject['object'].get('published'): if not postJsonObject['object'].get('published'):
return False return False
@ -2206,9 +2188,7 @@ def isDM(postJsonObject: {}) -> bool:
""" """
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if postJsonObject['object']['type'] != 'Note' and \ if postJsonObject['object']['type'] != 'Note' and \
postJsonObject['object']['type'] != 'Patch' and \ postJsonObject['object']['type'] != 'Patch' and \
@ -2234,9 +2214,7 @@ def isReply(postJsonObject: {}, actor: str) -> bool:
""" """
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
return False return False
if not postJsonObject.get('object'): if not hasObjectDict(postJsonObject):
return False
if not isinstance(postJsonObject['object'], dict):
return False return False
if postJsonObject['object'].get('moderationStatus'): if postJsonObject['object'].get('moderationStatus'):
return False return False
@ -2456,3 +2434,12 @@ def userAgentDomain(userAgent: str, debug: bool) -> str:
if debug: if debug:
print('User-Agent Domain: ' + agentDomain) print('User-Agent Domain: ' + agentDomain)
return agentDomain return agentDomain
def hasObjectDict(postJsonObject: {}) -> bool:
"""Returns true if the given post has an object dict
"""
if postJsonObject.get('object'):
if isinstance(postJsonObject['object'], dict):
return True
return False

View File

@ -9,6 +9,7 @@ __module_group__ = "Web Interface"
import os import os
from pprint import pprint from pprint import pprint
from utils import hasObjectDict
from utils import getOccupationName from utils import getOccupationName
from utils import getLockedAccount from utils import getLockedAccount
from utils import getFullDomain from utils import getFullDomain
@ -230,7 +231,7 @@ def htmlProfileAfterSearch(cssCache: {},
continue continue
if item['type'] != 'Create': if item['type'] != 'Create':
continue continue
if not item.get('object'): if not hasObjectDict(item):
continue continue
profileStr += \ profileStr += \