mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-04 12:51:36 +00:00
Initial commit of a new experimental modular GAM.
This commit is contained in:
95
src/gam/cmd/chat/__init__.py
Normal file
95
src/gam/cmd/chat/__init__.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""_Chat_Tmp sub-package.
|
||||
|
||||
Re-exports all symbols from sub-modules for backward compatibility."""
|
||||
|
||||
from gam.cmd.chat.setup import ( # noqa: F401
|
||||
CHAT_EMOJI_SHOW_CREATED_BY_CHOICE_MAP,
|
||||
CHAT_SECTION_POSITION,
|
||||
CHAT_TIME_OBJECTS,
|
||||
_chkChatAdminAccess,
|
||||
_cleanChatMessage,
|
||||
_cleanChatSpace,
|
||||
_getChatAdminAccess,
|
||||
_getChatPageMessage,
|
||||
_getValidateEmojiName,
|
||||
_printChatItem,
|
||||
_showChatItem,
|
||||
buildChatServiceObject,
|
||||
createChatEmoji,
|
||||
createUpdateChatSection,
|
||||
deleteChatEmoji,
|
||||
deleteChatSection,
|
||||
doSetupChat,
|
||||
exitIfChatNotConfigured,
|
||||
getChatSectionName,
|
||||
getEmojiName,
|
||||
infoChatEmoji,
|
||||
moveShowChatSectionItem,
|
||||
printShowChatEmojis,
|
||||
printShowChatSectionItems,
|
||||
printShowChatSections,
|
||||
setupChatURL,
|
||||
)
|
||||
from gam.cmd.chat.spaces import ( # noqa: F401
|
||||
CHAT_MEMBER_ROLE_MAP,
|
||||
CHAT_MEMBER_TYPE_MAP,
|
||||
CHAT_ROLE_ENTITY_TYPE_MAP,
|
||||
CHAT_SPACES_ADMIN_ORDERBY_CHOICE_MAP,
|
||||
CHAT_SPACES_FIELDS_CHOICE_MAP,
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS,
|
||||
CHAT_SPACE_PREDEFINED_PERMS_MAP,
|
||||
CHAT_SPACE_ROLE_PERMISSIONS_MAP,
|
||||
CHAT_SPACE_TYPE_MAP,
|
||||
CHAT_UPDATE_SPACE_PERMISSIONS_MAP,
|
||||
CHAT_UPDATE_SPACE_TYPE_MAP,
|
||||
_getChatSpaceListParms,
|
||||
_getChatSpaceSearchParms,
|
||||
createChatSpace,
|
||||
deleteChatSpace,
|
||||
doInfoChatSpace,
|
||||
doPrintShowChatSpaces,
|
||||
getChatSpaceParameters,
|
||||
getSpaceName,
|
||||
infoChatSpace,
|
||||
infoChatSpaceDM,
|
||||
printShowChatSpaces,
|
||||
updateChatSpace,
|
||||
)
|
||||
from gam.cmd.chat.members import ( # noqa: F401
|
||||
CHAT_MEMBERS_FIELDS_CHOICE_MAP,
|
||||
CHAT_MESSAGES_FIELDS_CHOICE_MAP,
|
||||
CHAT_MESSAGES_ORDERBY_CHOICE_MAP,
|
||||
CHAT_MESSAGE_REPLY_OPTION_MAP,
|
||||
CHAT_SEARCHMESSAGES_ORDERBY_CHOICE_MAP,
|
||||
CHAT_SEARCHMESSAGES_VIEW_CHOICE_MAP,
|
||||
CHAT_SYNC_PREVIEW_TITLES,
|
||||
_deleteChatMembers,
|
||||
_getChatMemberEmail,
|
||||
_getChatSenderEmail,
|
||||
_getChatSpaceDisplayName,
|
||||
_getChatSpaceMembers,
|
||||
createChatMember,
|
||||
createChatMessage,
|
||||
deleteChatMessage,
|
||||
deleteUpdateChatMember,
|
||||
doCreateChatMessage,
|
||||
doDeleteChatMessage,
|
||||
doInfoChatEvent,
|
||||
doInfoChatMember,
|
||||
doInfoChatMessage,
|
||||
doPrintShowChatMembers,
|
||||
doUpdateChatMessage,
|
||||
getGroupMemberID,
|
||||
getUserMemberID,
|
||||
infoChatEvent,
|
||||
infoChatMember,
|
||||
infoChatMessage,
|
||||
normalizeUserMember,
|
||||
printShowChatEvents,
|
||||
printShowChatMembers,
|
||||
printShowChatMessages,
|
||||
printShowChatSearchMessages,
|
||||
syncChatMembers,
|
||||
trimChatMessageIfRequired,
|
||||
updateChatMessage,
|
||||
)
|
||||
1434
src/gam/cmd/chat/members.py
Normal file
1434
src/gam/cmd/chat/members.py
Normal file
File diff suppressed because it is too large
Load Diff
658
src/gam/cmd/chat/setup.py
Normal file
658
src/gam/cmd/chat/setup.py
Normal file
@@ -0,0 +1,658 @@
|
||||
"""Chat setup, emoji, and section management.
|
||||
|
||||
Part of the _chat_tmp sub-package."""
|
||||
|
||||
"""GAM Google Chat management."""
|
||||
|
||||
import re
|
||||
import json
|
||||
import sys
|
||||
|
||||
from gamlib import glaction
|
||||
from gamlib import glapi as API
|
||||
from gamlib import glcfg as GC
|
||||
from gamlib import glclargs
|
||||
from gamlib import glentity
|
||||
from gamlib import glgapi as GAPI
|
||||
from gamlib import glglobals as GM
|
||||
from gamlib import glindent
|
||||
from gamlib import glmsgs as Msg
|
||||
|
||||
Act = glaction.GamAction()
|
||||
Ent = glentity.GamEntity()
|
||||
Ind = glindent.GamIndent()
|
||||
Cmd = glclargs.GamCLArgs()
|
||||
|
||||
|
||||
def _getMain():
|
||||
return sys.modules['gam']
|
||||
|
||||
def __getattr__(name):
|
||||
"""Fall back to gam module for any undefined names."""
|
||||
main = _getMain()
|
||||
try:
|
||||
return getattr(main, name)
|
||||
except AttributeError:
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
def buildChatServiceObject(api=API.CHAT, user=None, i=0, count=0, entityTypeList=None, useAdminAccess=False):
|
||||
if user is None:
|
||||
_, chat = _getMain().buildGAPIServiceObject(API.CHAT, user)
|
||||
kvList = [Ent.CHAT_BOT, None]
|
||||
else:
|
||||
user, chat = _getMain().buildGAPIServiceObject(api, user, i, count)
|
||||
if not useAdminAccess:
|
||||
kvList = [Ent.USER, user]
|
||||
else:
|
||||
kvList = [Ent.CHAT_ADMIN, f'{user}(asadmin)']
|
||||
if entityTypeList is not None:
|
||||
kvList.extend(entityTypeList)
|
||||
return user, chat, kvList
|
||||
|
||||
def _getChatPageMessage(entityType, user, i, count, pfilter, useAdminAccess=False):
|
||||
if user is not None:
|
||||
_getMain().printGettingAllEntityItemsForWhom(entityType, user if not useAdminAccess else f'{user}(asadmin)', i, count, pfilter)
|
||||
return _getMain().getPageMessageForWhom()
|
||||
_getMain().printGettingAllAccountEntities(entityType, pfilter)
|
||||
return _getMain().getPageMessage()
|
||||
|
||||
def setupChatURL(chat):
|
||||
return f'https://console.cloud.google.com/apis/api/chat.googleapis.com/hangouts-chat?project={chat._http.credentials.project_id}'
|
||||
|
||||
def exitIfChatNotConfigured(chat, kvList, errMsg, i, count):
|
||||
if (('No bot associated with this project.' in errMsg) or
|
||||
('Invalid project number.' in errMsg) or
|
||||
('Google Chat app not found.' in errMsg)):
|
||||
_getMain().systemErrorExit(_getMain().API_ACCESS_DENIED_RC, Msg.TO_SET_UP_GOOGLE_CHAT.format(setupChatURL(chat), GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id']))
|
||||
_getMain().entityActionFailedWarning(kvList, errMsg, i, count)
|
||||
|
||||
def _getChatAdminAccess(adminAPI, userAPI):
|
||||
if _getMain().checkArgumentPresent(_getMain().ADMIN_ACCESS_OPTIONS) or GC.Values[GC.USE_CHAT_ADMIN_ACCESS]:
|
||||
return (True, adminAPI, {'useAdminAccess': True})
|
||||
return (False, userAPI, {})
|
||||
|
||||
def _chkChatAdminAccess(count):
|
||||
if count != 1:
|
||||
_getMain().usageErrorExit(Msg.CHAT_ADMIN_ACCESS_LIMITED_TO_ONE_USER.format(count))
|
||||
|
||||
def _cleanChatSpace(space):
|
||||
space.pop('type', None)
|
||||
space.pop('threaded', None)
|
||||
|
||||
def _cleanChatMessage(message):
|
||||
message.pop('cards', None)
|
||||
|
||||
CHAT_TIME_OBJECTS = {'createTime', 'deleteTime', 'eventTime', 'lastActiveTime', 'lastUpdateTime'}
|
||||
|
||||
def _showChatItem(citem, entityType, FJQC, i=0, count=0):
|
||||
if entityType == Ent.CHAT_SPACE:
|
||||
_cleanChatSpace(citem)
|
||||
dictObjectsKey = {None: 'displayName'}
|
||||
elif entityType == Ent.CHAT_MESSAGE:
|
||||
_cleanChatMessage(citem)
|
||||
dictObjectsKey = {None: 'text'}
|
||||
else:
|
||||
dictObjectsKey={}
|
||||
if FJQC.formatJSON:
|
||||
_getMain().printLine(json.dumps(_getMain().cleanJSON(citem, timeObjects=CHAT_TIME_OBJECTS), ensure_ascii=False, sort_keys=True))
|
||||
return
|
||||
_getMain().printEntity([entityType, citem['name']], i, count)
|
||||
Ind.Increment()
|
||||
_getMain().showJSON(None, citem, timeObjects=CHAT_TIME_OBJECTS, dictObjectsKey=dictObjectsKey)
|
||||
Ind.Decrement()
|
||||
|
||||
def _printChatItem(user, citem, parent, entityType, csvPF, FJQC, addCSVData=None):
|
||||
if entityType == Ent.CHAT_SPACE:
|
||||
_cleanChatSpace(citem)
|
||||
baserow = {'User': user} if user is not None else {}
|
||||
elif entityType in {Ent.CHAT_SECTION, Ent.CHAT_SECTION_ITEM}:
|
||||
baserow = {'User': user}
|
||||
elif entityType == Ent.CHAT_EMOJI:
|
||||
baserow = {'User': user, 'name': citem['name'], 'emojiName': citem['emojiName']}
|
||||
else:
|
||||
if user is not None:
|
||||
baserow = {'User': user, 'space.name': parent['name'], 'space.displayName': parent['displayName']}
|
||||
else:
|
||||
baserow = {'space.name': parent['name'], 'space.displayName': parent['displayName']}
|
||||
if entityType == Ent.CHAT_MEMBER:
|
||||
if addCSVData:
|
||||
baserow.update(addCSVData)
|
||||
elif entityType == Ent.CHAT_MESSAGE:
|
||||
_cleanChatMessage(citem)
|
||||
row = _getMain().flattenJSON(citem, flattened=baserow.copy(), timeObjects=CHAT_TIME_OBJECTS)
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif csvPF.CheckRowTitles(row):
|
||||
row = baserow.copy()
|
||||
row.update({'name': citem['name'],
|
||||
'JSON': json.dumps(_getMain().cleanJSON(citem, timeObjects=CHAT_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)})
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
|
||||
def _getValidateEmojiName():
|
||||
name = _getMain().getString(Cmd.OB_CHAT_EMOJI_NAME)
|
||||
if re.match(r'^:[0-9a-z_-]+:$', name):
|
||||
return name
|
||||
Cmd.Backup()
|
||||
_getMain().usageErrorExit(Msg.INVALID_EMOJI_NAME.format(name))
|
||||
|
||||
# gam <UserTypeEntity> create chatemoji <ChatEmojiName>
|
||||
# ([drivedir|(sourcefolder <FilePath>)] [filename <FileNamePattern>])
|
||||
# [formatjson]
|
||||
def createChatEmoji(users):
|
||||
FJQC = _getMain().FormatJSONQuoteChar()
|
||||
name = _getValidateEmojiName()
|
||||
body = {'emojiName': name, 'payload': {'filename': '', 'fileContent': ''}}
|
||||
sourceFolder = os.getcwd()
|
||||
filenamePattern = '#email#.jpg'
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'drivedir':
|
||||
sourceFolder = GC.Values[GC.DRIVE_DIR]
|
||||
elif myarg == 'sourcefolder':
|
||||
sourceFolder = _getMain().setFilePath(_getMain().getString(Cmd.OB_FILE_PATH), GC.INPUT_DIR)
|
||||
if not os.path.isdir(sourceFolder):
|
||||
_getMain().entityDoesNotExistExit(Ent.DIRECTORY, sourceFolder)
|
||||
elif myarg == 'filename':
|
||||
filenamePattern = _getMain().getString(Cmd.OB_FILE_NAME_PATTERN)
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_CUSTOM_EMOJIS, user, i, count, [Ent.CHAT_EMOJI, name])
|
||||
if not chat:
|
||||
continue
|
||||
user, userName, _ = _getMain().splitEmailAddressOrUID(user)
|
||||
filename = os.path.join(sourceFolder, _getMain()._substituteForUser(filenamePattern, user, userName))
|
||||
try:
|
||||
with open(filename, 'rb') as f:
|
||||
image_data = f.read()
|
||||
except (OSError, IOError) as e:
|
||||
_getMain().entityActionFailedWarning([Ent.USER, user, Ent.CHAT_EMOJI, filename], str(e), i, count)
|
||||
continue
|
||||
body['payload'] = {'filename': os.path.basename(filename),
|
||||
'fileContent':base64.urlsafe_b64encode(image_data).decode(_getMain().UTF8)}
|
||||
try:
|
||||
emoji = _getMain().callGAPI(chat.customEmojis(), 'create',
|
||||
throwReasons=[GAPI.ALREADY_EXISTS, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
body=body)
|
||||
_showChatItem(emoji, Ent.CHAT_EMOJI, FJQC, i, count)
|
||||
except (GAPI.alreadyExists, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
def getEmojiName(myarg):
|
||||
if myarg == 'emojiname':
|
||||
name = _getValidateEmojiName()
|
||||
return 'customEmojis/'+name
|
||||
_, chatEmoji = Cmd.Previous().split('/', 1)
|
||||
return 'customEmojis/'+chatEmoji
|
||||
|
||||
# gam <UserTypeEntity> delete chatemoji <ChatEmoji>
|
||||
def deleteChatEmoji(users):
|
||||
name = None
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'emojiname':
|
||||
name = getEmojiName(myarg)
|
||||
elif myarg.startswith('customemojis/'):
|
||||
name = getEmojiName(myarg)
|
||||
else:
|
||||
_getMain().unknownArgumentExit()
|
||||
if not name:
|
||||
_getMain().missingArgumentExit('ChatEmoji')
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_CUSTOM_EMOJIS, user, i, count, [Ent.CHAT_EMOJI, name])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
_getMain().callGAPI(chat.customEmojis(), 'delete',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name)
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
# gam <UserTypeEntity> info chatemoji <ChatEmoji>
|
||||
# [formatjson]
|
||||
def infoChatEmoji(users):
|
||||
FJQC = _getMain().FormatJSONQuoteChar()
|
||||
name = None
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'emojiname':
|
||||
name = getEmojiName(myarg)
|
||||
elif myarg.startswith('customemojis/'):
|
||||
name = getEmojiName(myarg)
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if not name:
|
||||
_getMain().missingArgumentExit('ChatEmoji')
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_CUSTOM_EMOJIS, user, i, count, [Ent.CHAT_EMOJI, name])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
emoji = _getMain().callGAPI(chat.customEmojis(), 'get',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name)
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformAction(kvList, i, count)
|
||||
_showChatItem(emoji, Ent.CHAT_EMOJI, FJQC, i, count)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
CHAT_EMOJI_SHOW_CREATED_BY_CHOICE_MAP = {
|
||||
'any': None,
|
||||
'me': 'creator("users/me")',
|
||||
'others': 'NOT creator("users/me")'
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> show chatemojis
|
||||
# [showcreatedby any|me|others]
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print chatemojis [todrive <ToDriveAttribute>*]
|
||||
# [showcreatedby any|me|others]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowChatEmojis(users):
|
||||
csvPF = _getMain().CSVPrintFile(['User', 'name', 'emojiName']) if Act.csvFormat() else None
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
pfilter = CHAT_EMOJI_SHOW_CREATED_BY_CHOICE_MAP['me']
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg =='showcreatedby':
|
||||
pfilter = _getMain().getChoice(CHAT_EMOJI_SHOW_CREATED_BY_CHOICE_MAP, mapChoice=True)
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_CUSTOM_EMOJIS, user, i, count, [Ent.CHAT_EMOJI, None])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
emojis = _getMain().callGAPIpages(chat.customEmojis(), 'list', 'customEmojis',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_EMOJI, user, i, count, pfilter),
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
pageSize=GC.Values[GC.CHAT_MAX_RESULTS], filter=pfilter)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
break
|
||||
if not csvPF:
|
||||
jcount = len(emojis)
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformActionNumItems(kvList, jcount, Ent.CHAT_EMOJI, i, count)
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for emoji in sorted(emojis, key=lambda k: k['emojiName']):
|
||||
j += 1
|
||||
_showChatItem(emoji, Ent.CHAT_EMOJI, FJQC, j, jcount)
|
||||
Ind.Decrement()
|
||||
elif emojis:
|
||||
for emoji in sorted(emojis, key=lambda k: k['emojiName']):
|
||||
_printChatItem(user, emoji, '', Ent.CHAT_EMOJI, csvPF, FJQC)
|
||||
elif GC.Values[GC.CSV_OUTPUT_USERS_AUDIT]:
|
||||
csvPF.WriteRowNoFilter({'User': user})
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Chat Custom Emojis')
|
||||
|
||||
# gam setup chat
|
||||
def doSetupChat():
|
||||
_getMain().checkForExtraneousArguments()
|
||||
_, chat , _ = buildChatServiceObject()
|
||||
_getMain().writeStdout(Msg.TO_SET_UP_GOOGLE_CHAT.format(setupChatURL(chat), GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id']))
|
||||
|
||||
def getChatSectionName():
|
||||
if not Cmd.ArgumentsRemaining():
|
||||
_getMain().missingArgumentExit('<ChatSection>')
|
||||
myarg = Cmd.Current().lower()
|
||||
Cmd.Advance()
|
||||
if myarg == 'section':
|
||||
chatSection = _getMain().getString(Cmd.OB_CHAT_SECTION)
|
||||
if chatSection.startswith('sections/') or chatSection.startswith('users/'):
|
||||
return chatSection
|
||||
return 'sections/'+chatSection
|
||||
if myarg.startswith('sections/') or myarg.startswith('users/'):
|
||||
return Cmd.Previous()
|
||||
return 'sections/'+Cmd.Previous()
|
||||
|
||||
CHAT_SECTION_POSITION = {
|
||||
'start': 'START',
|
||||
'end': 'END'
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> create chatsection
|
||||
# displayname <String>
|
||||
# [formatjson|returnidonly]
|
||||
# gam <UserTypeEntity> update chatsection <ChatSection>
|
||||
# [displayname <String>]
|
||||
# [(sortorder <Integer>)|(position start|end)]
|
||||
# [formatjson]
|
||||
def createUpdateChatSection(users):
|
||||
updateCmd = Act.Get() == Act.UPDATE
|
||||
FJQC = _getMain().FormatJSONQuoteChar()
|
||||
name = None
|
||||
body = {}
|
||||
posbody = {}
|
||||
posloc = None
|
||||
returnIdOnly = False
|
||||
updateMask = set()
|
||||
if updateCmd:
|
||||
name = getChatSectionName()
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'displayname':
|
||||
body['displayName'] = _getMain().getString(Cmd.OB_STRING, minLen=1, maxLen=80)
|
||||
updateMask.add('displayName')
|
||||
elif updateCmd and myarg == 'sortorder':
|
||||
posloc = Cmd.Location()
|
||||
posbody['sortOrder'] = _getMain().getInteger(minVal=1)
|
||||
elif updateCmd and myarg == 'relativeposition':
|
||||
posloc = Cmd.Location()
|
||||
posbody['relativePosition'] = _getMain().getChoice(CHAT_SECTION_POSITION, mapChoice=True)
|
||||
elif not updateCmd and myarg == 'returnidonly':
|
||||
returnIdOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if updateCmd:
|
||||
if not name:
|
||||
_getMain().missingArgumentExit('<ChatSection>')
|
||||
if 'sortOrder' in posbody and 'relativePosition' in posbody:
|
||||
Cmd.SetLocation(posloc-1)
|
||||
_getMain().usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format('sortorder', 'relativeposition'))
|
||||
else:
|
||||
if 'displayName' not in body:
|
||||
_getMain().missingArgumentExit('displayname')
|
||||
body['type'] = 'CUSTOM_SECTION'
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SECTIONS, user, i, count,
|
||||
[Ent.CHAT_SECTION, body.get('displayName', '')])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
if not updateCmd:
|
||||
section = _getMain().callGAPI(chat.users().sections(), 'create',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
parent=f'users/{user}', body=body)
|
||||
if not returnIdOnly:
|
||||
kvList[-1] = section['name']
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
Ind.Increment()
|
||||
_showChatItem(section, Ent.CHAT_SECTION, FJQC)
|
||||
Ind.Decrement()
|
||||
else:
|
||||
_getMain().writeStdout(f'{section["name"]}\n')
|
||||
else:
|
||||
pname = name
|
||||
if not pname.startswith('users/'):
|
||||
pname = f'users/{user}/{name}'
|
||||
kvList[-1] = pname
|
||||
if not body and not posbody:
|
||||
_getMain().entityActionNotPerformedWarning(kvList, Msg.NO_CHANGES, i, count)
|
||||
continue
|
||||
if body:
|
||||
section = _getMain().callGAPI(chat.users().sections(), 'patch',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
name=pname, updateMask=','.join(updateMask), body=body)
|
||||
if posbody:
|
||||
section = _getMain().callGAPI(chat.users().sections(), 'position',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
name=pname, body=posbody)
|
||||
section = section['section']
|
||||
kvList[-1] = section['name']
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
Ind.Increment()
|
||||
_showChatItem(section, Ent.CHAT_SECTION, FJQC)
|
||||
Ind.Decrement()
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
except AttributeError:
|
||||
_getMain().systemErrorExit(_getMain().GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||
|
||||
# gam <UserTypeEntity> delete chatsection <ChatSection>
|
||||
def deleteChatSection(users):
|
||||
name = getChatSectionName()
|
||||
_getMain().checkForExtraneousArguments()
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SECTIONS, user, i, count,
|
||||
[Ent.CHAT_SECTION, name])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
pname = name
|
||||
if not pname.startswith('users/'):
|
||||
pname = f'users/{user}/{name}'
|
||||
kvList[-1] = pname
|
||||
_getMain().callGAPI(chat.users().sections(), 'delete',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
name=pname)
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
except AttributeError:
|
||||
_getMain().systemErrorExit(_getMain().GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||
|
||||
# gam <UserTypeEntity> show chatsections
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print chatsections [todrive <ToDriveAttribute>*]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowChatSections(users):
|
||||
csvPF = _getMain().CSVPrintFile(['User', 'name']) if Act.csvFormat() else None
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SECTIONS, user, i, count)
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
sections = _getMain().callGAPIpages(chat.users().sections(), 'list', 'sections',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_SECTION, user, i, count, None),
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
parent=f'users/{user}', pageSize=GC.Values[GC.CHAT_MAX_RESULTS])
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
except AttributeError:
|
||||
_getMain().systemErrorExit(_getMain().GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||
jcount = len(sections)
|
||||
if jcount == 0:
|
||||
_getMain().setSysExitRC(_getMain().NO_ENTITIES_FOUND_RC)
|
||||
if not csvPF:
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformActionNumItems(kvList, jcount, Ent.CHAT_SECTION, i, count)
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for section in sections:
|
||||
j += 1
|
||||
_showChatItem(section, Ent.CHAT_SECTION, FJQC, j, jcount)
|
||||
Ind.Decrement()
|
||||
else:
|
||||
for section in sections:
|
||||
_printChatItem(user, section, None, Ent.CHAT_SECTION, csvPF, FJQC)
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Chat Sections')
|
||||
|
||||
# gam <UserTypeEntity> move chatsectionitem <ChatSectionItem> to <ChatSection>
|
||||
def moveShowChatSectionItem(users):
|
||||
name = getChatSectionName()
|
||||
if Cmd.PeekArgumentPresent(['to']):
|
||||
Cmd.Advance()
|
||||
target = getChatSectionName()
|
||||
_getMain().checkForExtraneousArguments()
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SECTIONS, user, i, count,
|
||||
[Ent.CHAT_SECTION_ITEM, name])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
pname = name
|
||||
if not pname.startswith('users/'):
|
||||
pname = f'users/{user}/{name}'
|
||||
kvList[-1] = pname
|
||||
ptarget = target
|
||||
if not ptarget.startswith('users/'):
|
||||
ptarget = f'users/{user}/{target}'
|
||||
kvList[-1] = ptarget
|
||||
_getMain().callGAPI(chat.users().sections().items(), 'move',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
name=pname, body={'targetSection': ptarget})
|
||||
_getMain().entityModifierItemValueListActionPerformed(kvList, Act.MODIFIER_TO, [Ent.CHAT_SECTION, ptarget], i, count)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
except AttributeError:
|
||||
_getMain().systemErrorExit(_getMain().GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||
|
||||
# gam <UserTypeEntity> show chatsectionitems <ChatSection>
|
||||
# [space <ChatSpace>]
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print chatsectionitems <ChatSection> [todrive <ToDriveAttribute>*]
|
||||
# [space <ChatSpace>]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowChatSectionItems(users):
|
||||
cd = _getMain().buildGAPIObject(API.DIRECTORY)
|
||||
csvPF = _getMain().CSVPrintFile(['User', 'name', 'space']) if Act.csvFormat() else None
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
name = getChatSectionName()
|
||||
kwargs = {}
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'):
|
||||
kwargs['filter'] = f'space = {getSpaceName(myarg)}'
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SECTIONS, user, i, count)
|
||||
if not chat:
|
||||
continue
|
||||
_, chatsp, _ = buildChatServiceObject(API.CHAT_SPACES, user, i, count)
|
||||
if not chatsp:
|
||||
continue
|
||||
_, chatme, _ = buildChatServiceObject(API.CHAT_MEMBERSHIPS, user, i, count)
|
||||
if not chatme:
|
||||
continue
|
||||
pname = name
|
||||
if not pname.startswith('users/'):
|
||||
pname = f'users/{user}/{name}'
|
||||
kvList[-1] = pname
|
||||
try:
|
||||
sectionItems = _getMain().callGAPIpages(chat.users().sections().items(), 'list', 'sectionItems',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_SECTION_ITEM, user, i, count, None),
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
parent=pname, pageSize=GC.Values[GC.CHAT_MAX_RESULTS], **kwargs)
|
||||
for sectionItem in sectionItems:
|
||||
space = _getMain().callGAPI(chatsp.spaces(), 'get',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
name=sectionItem['space'], fields='displayName,spaceType')
|
||||
sectionItem['spaceDetails'] = {'spaceType': space['spaceType']}
|
||||
if space['spaceType'] == 'DIRECT_MESSAGE':
|
||||
members = _getMain().callGAPIitems(chatme.spaces().members(), 'list', 'memberships',
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
parent=sectionItem['space'], fields='memberships(member)')
|
||||
for member in members:
|
||||
_getChatMemberEmail(cd, member)
|
||||
sectionItem['spaceDetails']['members'] = ' '.join([member['member']['email'] for member in members])
|
||||
elif 'displayName' in space:
|
||||
sectionItem['spaceDetails']['displayName'] = space['displayName']
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
except AttributeError:
|
||||
_getMain().systemErrorExit(_getMain().GOOGLE_API_ERROR_RC, Msg.DEVELOPER_PREVIEW_REQUIRED)
|
||||
jcount = len(sectionItems)
|
||||
if jcount == 0:
|
||||
_getMain().setSysExitRC(_getMain().NO_ENTITIES_FOUND_RC)
|
||||
if not csvPF:
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformActionNumItems(kvList, jcount, Ent.CHAT_SECTION_ITEM, i, count)
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for sectionItem in sectionItems:
|
||||
j += 1
|
||||
_showChatItem(sectionItem, Ent.CHAT_SECTION_ITEM, FJQC, j, jcount)
|
||||
Ind.Decrement()
|
||||
else:
|
||||
for sectionItem in sectionItems:
|
||||
_printChatItem(user, sectionItem, None, Ent.CHAT_SECTION_ITEM, csvPF, FJQC)
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Chat Sections')
|
||||
|
||||
601
src/gam/cmd/chat/spaces.py
Normal file
601
src/gam/cmd/chat/spaces.py
Normal file
@@ -0,0 +1,601 @@
|
||||
"""Chat space CRUD and listing.
|
||||
|
||||
Part of the _chat_tmp sub-package."""
|
||||
|
||||
"""GAM Google Chat management."""
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
from gamlib import glaction
|
||||
from gamlib import glapi as API
|
||||
from gamlib import glcfg as GC
|
||||
from gamlib import glclargs
|
||||
from gamlib import glentity
|
||||
from gamlib import glgapi as GAPI
|
||||
from gamlib import glglobals as GM
|
||||
from gamlib import glindent
|
||||
from gamlib import glmsgs as Msg
|
||||
|
||||
Act = glaction.GamAction()
|
||||
Ent = glentity.GamEntity()
|
||||
Ind = glindent.GamIndent()
|
||||
Cmd = glclargs.GamCLArgs()
|
||||
|
||||
|
||||
def _getMain():
|
||||
return sys.modules['gam']
|
||||
|
||||
def __getattr__(name):
|
||||
"""Fall back to gam module for any undefined names."""
|
||||
main = _getMain()
|
||||
try:
|
||||
return getattr(main, name)
|
||||
except AttributeError:
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
def getSpaceName(myarg):
|
||||
if myarg == 'space':
|
||||
chatSpace = _getMain().getString(Cmd.OB_CHAT_SPACE)
|
||||
if chatSpace.startswith('spaces/'):
|
||||
return chatSpace
|
||||
if not chatSpace.startswith('space/'):
|
||||
return 'spaces/'+chatSpace
|
||||
_, chatSpace = chatSpace.split('/', 1)
|
||||
else: # myarg.startswith('spaces/') or myarg.startswith('space/')
|
||||
_, chatSpace = Cmd.Previous().split('/', 1)
|
||||
return 'spaces/'+chatSpace
|
||||
|
||||
def getChatSpaceParameters(myarg, body, typeChoicesMap, updateMask):
|
||||
if myarg == 'displayname':
|
||||
body['displayName'] = _getMain().getString(Cmd.OB_STRING, minLen=0, maxLen=128)
|
||||
updateMask.add('displayName')
|
||||
elif myarg == 'type':
|
||||
body['spaceType'] = _getMain().getChoice(typeChoicesMap, mapChoice=True)
|
||||
updateMask.add('spaceType')
|
||||
elif myarg == 'description':
|
||||
body.setdefault('spaceDetails', {})
|
||||
body['spaceDetails']['description'] = _getMain().getString(Cmd.OB_STRING, minLen=0, maxLen=150)
|
||||
updateMask.add('spaceDetails')
|
||||
elif myarg in {'guidelines', 'rules'}:
|
||||
body.setdefault('spaceDetails', {})
|
||||
body['spaceDetails']['guidelines'] = _getMain().getString(Cmd.OB_STRING, minLen=0, maxLen=5000)
|
||||
updateMask.add('spaceDetails')
|
||||
elif myarg == 'history':
|
||||
body['spaceHistoryState'] = 'HISTORY_ON' if getBoolean() else 'HISTORY_OFF'
|
||||
updateMask.add('spaceHistoryState')
|
||||
elif myarg in {'audience', 'restricted'}:
|
||||
body['accessSettings']= {'audience': None}
|
||||
if myarg == 'audience':
|
||||
body['accessSettings']['audience'] = _getMain().getString(Cmd.OB_STRING, minLen=1, maxLen=100)
|
||||
updateMask.add('accessSettings.audience')
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
CHAT_MEMBER_ROLE_MAP = {
|
||||
'member': 'ROLE_MEMBER',
|
||||
'manager': 'ROLE_ASSISTANT_MANAGER',
|
||||
'owner': 'ROLE_MANAGER',
|
||||
}
|
||||
|
||||
CHAT_ROLE_ENTITY_TYPE_MAP = {
|
||||
'ROLE_MEMBER': Ent.CHAT_MEMBER_USER,
|
||||
'ROLE_ASSISTANT_MANAGER': Ent.CHAT_MANAGER_USER,
|
||||
'ROLE_MANAGER': Ent.CHAT_OWNER_USER,
|
||||
}
|
||||
|
||||
CHAT_MEMBER_TYPE_MAP = {
|
||||
'bot': 'BOT',
|
||||
'human': 'HUMAN'
|
||||
}
|
||||
|
||||
CHAT_SPACE_TYPE_MAP = {
|
||||
'space': 'SPACE',
|
||||
'groupchat': 'GROUP_CHAT',
|
||||
'directmessage': 'DIRECT_MESSAGE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_PREDEFINED_PERMS_MAP = {
|
||||
'announcement': 'ANNOUNCEMENT_SPACE',
|
||||
'collaboration': 'COLLABORATION_SPACE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS = {
|
||||
'SPACE': {'min': 0, 'max': 20},
|
||||
'GROUP_CHAT': {'min': 2, 'max': 20},
|
||||
'DIRECT_MESSAGE': {'min': 1, 'max': 1},
|
||||
}
|
||||
# gam <UserTypeEntity> create chatspace
|
||||
# [type <ChatSpaceType>] [announcement|collaboration]
|
||||
# [restricted|(audience <String>)]
|
||||
# [externalusersallowed <Boolean>]
|
||||
# [members <UserTypeEntity>]
|
||||
# [displayname <String>]
|
||||
# [description <String>] [guidelines|rules <String>]
|
||||
# [<ChatContent>]
|
||||
# [(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]] (addcsvdata <FieldName> <String>)*) | formatjson | returnidonly]
|
||||
def createChatSpace(users):
|
||||
def _writeSpaceDetails(space, resp=None):
|
||||
baserow = {'User': user, 'name': space['name']}
|
||||
if resp:
|
||||
baserow['message.name'] = resp['name']
|
||||
if addCSVData:
|
||||
baserow.update(addCSVData)
|
||||
row = _getMain().flattenJSON(space, flattened=baserow.copy(), timeObjects=CHAT_TIME_OBJECTS)
|
||||
if not FJQC.formatJSON:
|
||||
csvPF.WriteRowTitles(row)
|
||||
else:
|
||||
row = baserow.copy()
|
||||
row['JSON'] = json.dumps(_getMain().cleanJSON(space, timeObjects=CHAT_TIME_OBJECTS), ensure_ascii=False, sort_keys=True)
|
||||
csvPF.WriteRowNoFilter(row)
|
||||
|
||||
csvPF = None
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
addCSVData = {}
|
||||
body = {'space': {'spaceType': CHAT_SPACE_TYPE_MAP['space'], 'displayName': ''}, 'requestId': str(uuid.uuid4())}
|
||||
members = []
|
||||
tbody = {}
|
||||
returnIdOnly = False
|
||||
updateMask = set()
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if getChatSpaceParameters(myarg, body['space'], CHAT_SPACE_TYPE_MAP, updateMask):
|
||||
pass
|
||||
elif myarg in CHAT_SPACE_PREDEFINED_PERMS_MAP:
|
||||
body['space']['predefinedPermissionSettings'] = CHAT_SPACE_PREDEFINED_PERMS_MAP[myarg]
|
||||
elif myarg == 'externalusersallowed':
|
||||
body['space']['externalUserAllowed'] = _getMain().getBoolean()
|
||||
elif myarg == 'members':
|
||||
_, members = _getMain().getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS)
|
||||
elif myarg == 'returnidonly':
|
||||
returnIdOnly = True
|
||||
elif myarg == 'csv':
|
||||
csvPF = _getMain().CSVPrintFile(['User', 'name'])
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
elif csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif csvPF and myarg == 'addcsvdata':
|
||||
_getMain().getAddCSVData(addCSVData)
|
||||
elif myarg in _getMain().SORF_TEXT_ARGUMENTS:
|
||||
tbody['text'] = _getMain().getStringOrFile(myarg, minLen=0, unescapeCRLF=True)[0]
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg)
|
||||
spaceType = body['space']['spaceType']
|
||||
jcount = len(members)
|
||||
if (jcount < CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['min'] or
|
||||
jcount > CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['max']):
|
||||
_getMain().systemErrorExit(_getMain().USAGE_ERROR_RC,
|
||||
Msg.INVALID_NUMBER_OF_CHAT_SPACE_MEMBERS.format(Ent.Singular(Ent.CHAT_SPACE),
|
||||
spaceType, jcount,
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['min'],
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['max']))
|
||||
mtype = CHAT_MEMBER_TYPE_MAP['human']
|
||||
if members:
|
||||
body['memberships'] = []
|
||||
for member in members:
|
||||
name = _getMain().normalizeEmailAddressOrUID(member)
|
||||
body['memberships'].append({'member': {'name': f'users/{name}', 'type': mtype}})
|
||||
if spaceType == 'SPACE':
|
||||
if not body['space']['displayName']:
|
||||
_getMain().missingArgumentExit('displayname')
|
||||
elif spaceType == 'GROUP_CHAT':
|
||||
body['space'].pop('displayName', None)
|
||||
body['space'].pop('predefinedPermissionSettings', None)
|
||||
else: # DIRECT_MESSAGE
|
||||
body['space'].pop('displayName', None)
|
||||
body['space'].pop('spaceDetails', None)
|
||||
body['space'].pop('predefinedPermissionSettings', None)
|
||||
body['space']['singleUserBotDm'] = False
|
||||
if tbody:
|
||||
trimChatMessageIfRequired(tbody)
|
||||
if csvPF:
|
||||
if tbody:
|
||||
csvPF.AddTitle('message.name')
|
||||
if addCSVData:
|
||||
csvPF.AddTitles(sorted(addCSVData.keys()))
|
||||
if FJQC.formatJSON:
|
||||
csvPF.SetJSONTitles(csvPF.titlesList)
|
||||
csvPF.AddJSONTitle('JSON')
|
||||
csvPF.SetSortAllTitles()
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(API.CHAT_SPACES, user, i, count,
|
||||
[Ent.CHAT_SPACE, body['space'].get('displayName', spaceType)])
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
space = _getMain().callGAPI(chat.spaces(), 'setup',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
body=body)
|
||||
if returnIdOnly:
|
||||
_getMain().writeStdout(f'{space["name"]}\n')
|
||||
elif not csvPF:
|
||||
kvList[-1] = space['name']
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
Ind.Increment()
|
||||
_showChatItem(space, Ent.CHAT_SPACE, FJQC)
|
||||
Ind.Decrement()
|
||||
elif not tbody:
|
||||
_writeSpaceDetails(space, None)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
if tbody:
|
||||
parent = space['name']
|
||||
_, chat, kvList = buildChatServiceObject(API.CHAT_MESSAGES, user, i, count,
|
||||
[Ent.CHAT_SPACE, body['space'].get('displayName', parent)])
|
||||
if not chat:
|
||||
if csvPF:
|
||||
_writeSpaceDetails(space, None)
|
||||
continue
|
||||
try:
|
||||
resp = _getMain().callGAPI(chat.spaces().messages(), 'create',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
|
||||
parent=parent, requestId=str(uuid.uuid4()), body=tbody, fields='name')
|
||||
if returnIdOnly:
|
||||
_getMain().writeStdout(f'{resp["name"]}\n')
|
||||
elif not csvPF:
|
||||
if not FJQC.formatJSON:
|
||||
kvList.extend([Ent.CHAT_MESSAGE, resp['name']])
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
else:
|
||||
_getMain().printLine(json.dumps(_getMain().cleanJSON(resp), ensure_ascii=False, sort_keys=True))
|
||||
else:
|
||||
_writeSpaceDetails(space, resp)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
if csvPF:
|
||||
_writeSpaceDetails(space, None)
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Chat Spaces')
|
||||
|
||||
CHAT_UPDATE_SPACE_TYPE_MAP = {
|
||||
'space': 'SPACE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_ROLE_PERMISSIONS_MAP = {
|
||||
'owners': 'managersAllowed',
|
||||
'managers': 'assistantManagersAllowed',
|
||||
'members': 'membersAllowed',
|
||||
}
|
||||
|
||||
CHAT_UPDATE_SPACE_PERMISSIONS_MAP = {
|
||||
'managemembersandgroups': 'manageMembersAndGroups',
|
||||
'modifyspacedetails': 'modifySpaceDetails',
|
||||
'togglehistory': 'toggleHistory',
|
||||
'useatmentionall': 'useAtMentionAll',
|
||||
'manageapps': 'manageApps',
|
||||
'managewebhooks': 'manageWebhooks',
|
||||
'replymessages': 'replyMessages',
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> update chatspace <ChatSpace>
|
||||
# [restricted|(audience <String>)]|
|
||||
# ([displayname <String>]
|
||||
# [type space]
|
||||
# [description <String>] [guidelines|rules <String>]
|
||||
# [history <Boolean>])
|
||||
# [managemembersandgroups owners|managers|members]
|
||||
# [modifyspacedetails owners|managers|members]
|
||||
# [togglehistory owners|managers|members]
|
||||
# [useatmentionall owners|managers|members]
|
||||
# [manageapps owners|managers|members]
|
||||
# [managewebhooks owners|managers|members]
|
||||
# [replymessages owners|managers|members]
|
||||
# [formatjson]
|
||||
def updateChatSpace(users):
|
||||
FJQC = _getMain().FormatJSONQuoteChar()
|
||||
useAdminAccess, api, kwargsUAA = _getChatAdminAccess(API.CHAT_SPACES_ADMIN, API.CHAT_SPACES)
|
||||
name = None
|
||||
body = {}
|
||||
updateMask = set()
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'):
|
||||
name = getSpaceName(myarg)
|
||||
elif getChatSpaceParameters(myarg, body, CHAT_UPDATE_SPACE_TYPE_MAP, updateMask):
|
||||
pass
|
||||
elif myarg in CHAT_UPDATE_SPACE_PERMISSIONS_MAP:
|
||||
body.setdefault('permissionSettings', {})
|
||||
permissionSetting = CHAT_UPDATE_SPACE_PERMISSIONS_MAP[myarg]
|
||||
role = _getMain().getChoice(CHAT_SPACE_ROLE_PERMISSIONS_MAP, mapChoice=True)
|
||||
body['permissionSettings'][permissionSetting] = {}
|
||||
body['permissionSettings'][permissionSetting][role] = True
|
||||
if role == 'membersAllowed':
|
||||
body['permissionSettings'][permissionSetting]['assistantManagersAllowed'] = True
|
||||
body['permissionSettings'][permissionSetting]['managersAllowed'] = True
|
||||
elif role == 'assistantManagersAllowed':
|
||||
body['permissionSettings'][permissionSetting]['managersAllowed'] = True
|
||||
updateMask.add(f'permissionSettings.{permissionSetting}')
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if not name:
|
||||
_getMain().missingArgumentExit('space')
|
||||
if 'accessSettings.audience' in updateMask:
|
||||
tempMask = updateMask-{'accessSettings.audience'}
|
||||
if tempMask:
|
||||
_getMain().usageErrorExit(Msg.ARE_MUTUALLY_EXCLUSIVE.format('restricted/audience', 'displayname,type,description,guidelines,history'))
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
if useAdminAccess:
|
||||
_chkChatAdminAccess(count)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(api, user, i, count, [Ent.CHAT_SPACE, name], useAdminAccess)
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
space = _getMain().callGAPI(chat.spaces(), 'patch',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name, updateMask=','.join(updateMask), body=body, **kwargsUAA)
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
Ind.Increment()
|
||||
_showChatItem(space, Ent.CHAT_SPACE, FJQC)
|
||||
Ind.Decrement()
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
# gam <UserTypeEntity> delete chatspace <ChatSpace>
|
||||
# gam <UserItem> delete chatspace asadmin <ChatSpace>
|
||||
def deleteChatSpace(users):
|
||||
name = None
|
||||
useAdminAccess, api, kwargsUAA = _getChatAdminAccess(API.CHAT_SPACES_DELETE_ADMIN, API.CHAT_SPACES_DELETE)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/'):
|
||||
name = getSpaceName(myarg)
|
||||
else:
|
||||
_getMain().unknownArgumentExit()
|
||||
if not name:
|
||||
_getMain().missingArgumentExit('space')
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
if useAdminAccess:
|
||||
_chkChatAdminAccess(count)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(api, user, i, count, [Ent.CHAT_SPACE, name], useAdminAccess)
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
_getMain().callGAPI(chat.spaces(), 'delete',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name, **kwargsUAA)
|
||||
_getMain().entityActionPerformed(kvList, i, count)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
CHAT_SPACES_FIELDS_CHOICE_MAP = {
|
||||
"accesssettings": "accessSettings",
|
||||
"admininstalled": "adminInstalled",
|
||||
"createtime": "createTime",
|
||||
"displayname": "displayName",
|
||||
"externaluserallowed": "externalUserAllowed",
|
||||
"importmode": "importMode",
|
||||
"lastactivetime": "lastActiveTime",
|
||||
"membershipcount": "membershipCount",
|
||||
"name": "name",
|
||||
"permissionsettings": "permissionSettings",
|
||||
"singleuserbotdm": "singleUserBotDm",
|
||||
"spacedetails": "spaceDetails",
|
||||
"spacehistorystate": "spaceHistoryState",
|
||||
"spacethreadingstate": "spaceThreadingState",
|
||||
"spacetype": "spaceType",
|
||||
"spaceuri": "spaceUri",
|
||||
"threaded": "spaceThreadingState",
|
||||
"type": "spaceType",
|
||||
}
|
||||
|
||||
# gam [<UserTypeEntity>] info chatspace <ChatSpace>
|
||||
# [fields <ChatSpaceFieldNameList>]
|
||||
# [formatjson]
|
||||
# gam <UserItem> info chatspace asadmin <ChatSpace>
|
||||
# [fields <ChatSpaceFieldNameList>]
|
||||
# [formatjson]
|
||||
def infoChatSpace(users, name=None):
|
||||
FJQC = _getMain().FormatJSONQuoteChar()
|
||||
if name is None:
|
||||
function = 'get'
|
||||
useAdminAccess, api, kwargsUAA = _getChatAdminAccess(API.CHAT_SPACES_ADMIN, API.CHAT_SPACES)
|
||||
else:
|
||||
function = 'findDirectMessage'
|
||||
useAdminAccess = None
|
||||
kwargsUAA = {}
|
||||
api = API.CHAT_SPACES
|
||||
fieldsList = []
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if function == 'get' and (myarg == 'space' or myarg.startswith('spaces/') or myarg.startswith('space/')):
|
||||
name = getSpaceName(myarg)
|
||||
elif _getMain().getFieldsList(myarg, CHAT_SPACES_FIELDS_CHOICE_MAP, fieldsList, initialField='name', onlyFieldsArg=True):
|
||||
pass
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if function == 'get' and not name:
|
||||
_getMain().missingArgumentExit('space')
|
||||
fields = _getMain().getFieldsFromFieldsList(fieldsList)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
if useAdminAccess:
|
||||
_chkChatAdminAccess(count)
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(api, user, i, count, [Ent.CHAT_SPACE, name], useAdminAccess)
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
space = _getMain().callGAPI(chat.spaces(), function,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=name, fields=fields, **kwargsUAA)
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformAction(kvList, i, count)
|
||||
Ind.Increment()
|
||||
_showChatItem(space, Ent.CHAT_SPACE, FJQC)
|
||||
Ind.Decrement()
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
|
||||
def doInfoChatSpace():
|
||||
infoChatSpace([None])
|
||||
|
||||
# gam [<UserTypeEntity>] info chatspacedm <UserItem>
|
||||
# [fields <ChatSpaceFieldNameList>]
|
||||
# [formatjson]
|
||||
def infoChatSpaceDM(users):
|
||||
cd = _getMain().buildGAPIObject(API.DIRECTORY)
|
||||
name = _getMain().convertEmailAddressToUID(_getMain().getEmailAddress(returnUIDprefix='uid:'), cd, 'user')
|
||||
infoChatSpace(users, f'users/{name}')
|
||||
|
||||
def _getChatSpaceListParms(myarg, kwargs):
|
||||
if myarg in {'type', 'types'}:
|
||||
for ctype in _getMain().getString(Cmd.OB_GROUP_ROLE_LIST).lower().replace(',', ' ').split():
|
||||
if ctype in CHAT_SPACE_TYPE_MAP:
|
||||
kwargs.setdefault('filter', '')
|
||||
if kwargs['filter']:
|
||||
kwargs['filter'] += ' OR '
|
||||
kwargs['filter'] += f'spaceType = "{CHAT_SPACE_TYPE_MAP[ctype]}"'
|
||||
else:
|
||||
_getMain().invalidChoiceExit(ctype, CHAT_SPACE_TYPE_MAP, True)
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _getChatSpaceSearchParms(myarg, queries, queryTimes, OBY):
|
||||
if myarg == 'orderby':
|
||||
OBY.GetChoice()
|
||||
elif myarg == 'query':
|
||||
queries[0] += ' AND '+_getMain().getString(Cmd.OB_QUERY)
|
||||
elif myarg.startswith('querytime'):
|
||||
queryTimes[myarg] = _getMain().getTimeOrDeltaFromNow()
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
CHAT_SPACES_ADMIN_ORDERBY_CHOICE_MAP = {
|
||||
'createtime': 'createTime',
|
||||
'lastactivetime': 'lastActiveTime',
|
||||
'membershipcount': 'membershipCount.joined_direct_human_user_count'
|
||||
}
|
||||
|
||||
# gam [<UserTypeEntity>] show chatspaces
|
||||
# [types <ChatSpaceTypeList>]
|
||||
# [fields <ChatSpaceFieldNameList>] [showaccesssettings]
|
||||
# [formatjson]
|
||||
# gam [<UserTypeEntity>] print chatspaces [todrive <ToDriveAttribute>*]
|
||||
# [types <ChatSpaceTypeList>]
|
||||
# [fields <ChatSpaceFieldNameList>] [showaccesssettings]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
# gam <UserItem> show chatspaces asadmin
|
||||
# [query <String>] [querytime<String> <Time>]
|
||||
# [orderby <ChatSpaceAdminOrderByFieldName> [ascending|descending]]
|
||||
# [fields <ChatSpaceFieldNameList>] [showaccesssettings]
|
||||
# [formatjson]
|
||||
# gam <UserItem> print chatspaces asadmin [todrive <ToDriveAttribute>*]
|
||||
# [query <String>] [querytime<String> <Time>]
|
||||
# [orderby <ChatSpaceAdminOrderByFieldName> [ascending|descending]]
|
||||
# [fields <ChatSpaceFieldNameList>] [showaccesssettings]
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowChatSpaces(users):
|
||||
csvPF = _getMain().CSVPrintFile(['User', 'name'] if not isinstance(users, list) else ['name']) if Act.csvFormat() else None
|
||||
FJQC = _getMain().FormatJSONQuoteChar(csvPF)
|
||||
OBY = _getMain().OrderBy(CHAT_SPACES_ADMIN_ORDERBY_CHOICE_MAP)
|
||||
useAdminAccess, api, kwargsCS = _getChatAdminAccess(API.CHAT_SPACES_ADMIN, API.CHAT_SPACES)
|
||||
kwargsSAS = {'useAdminAccess': useAdminAccess}
|
||||
fieldsList = []
|
||||
queries = []
|
||||
queryTimes = {}
|
||||
pfilter = ''
|
||||
showAccessSettings = False
|
||||
if useAdminAccess:
|
||||
function = 'search'
|
||||
queries = ['customer = "customers/my_customer" AND spaceType = "SPACE"']
|
||||
else:
|
||||
function = 'list'
|
||||
while Cmd.ArgumentsRemaining():
|
||||
myarg = _getMain().getArgument()
|
||||
if csvPF and myarg == 'todrive':
|
||||
csvPF.GetTodriveParameters()
|
||||
elif _getMain().getFieldsList(myarg, CHAT_SPACES_FIELDS_CHOICE_MAP, fieldsList, initialField='name', onlyFieldsArg=True):
|
||||
pass
|
||||
elif not useAdminAccess and _getChatSpaceListParms(myarg, kwargsCS):
|
||||
pass
|
||||
elif useAdminAccess and _getChatSpaceSearchParms(myarg, queries, queryTimes, OBY):
|
||||
pass
|
||||
elif myarg == 'showaccesssettings':
|
||||
showAccessSettings = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg, True)
|
||||
if showAccessSettings and fieldsList:
|
||||
fieldsList.extend(['name', 'spaceType'])
|
||||
fields = _getMain().getItemFieldsFromFieldsList('spaces', fieldsList)
|
||||
i, count, users = _getMain().getEntityArgument(users)
|
||||
if useAdminAccess:
|
||||
_chkChatAdminAccess(count)
|
||||
kwargsCS['orderBy'] = OBY.orderBy
|
||||
_getMain().substituteQueryTimes(queries, queryTimes)
|
||||
pfilter = kwargsCS['query'] = queries[0]
|
||||
kwargsCS['useAdminAccess'] = True
|
||||
sortName = 'displayName' if 'displayName' in fieldsList else 'name'
|
||||
else:
|
||||
sortName = 'name'
|
||||
for user in users:
|
||||
i += 1
|
||||
user, chat, kvList = buildChatServiceObject(api, user, i, count, None, useAdminAccess)
|
||||
if not chat:
|
||||
continue
|
||||
try:
|
||||
spaces = _getMain().callGAPIpages(chat.spaces(), function, 'spaces',
|
||||
pageMessage=_getChatPageMessage(Ent.CHAT_SPACE, user, i, count, pfilter, useAdminAccess),
|
||||
bailOnInternalError=True,
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
fields=fields, pageSize=GC.Values[GC.CHAT_MAX_RESULTS], **kwargsCS)
|
||||
if showAccessSettings:
|
||||
for space in spaces:
|
||||
if space['spaceType'] == 'SPACE':
|
||||
try:
|
||||
result = _getMain().callGAPI(chat.spaces(), 'get',
|
||||
throwReasons=[GAPI.NOT_FOUND, GAPI.INVALID_ARGUMENT, GAPI.INTERNAL_ERROR,
|
||||
GAPI.PERMISSION_DENIED, GAPI.FAILED_PRECONDITION],
|
||||
name=space['name'], fields='accessSettings', **kwargsSAS)
|
||||
space.update(result)
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied, GAPI.failedPrecondition):
|
||||
pass
|
||||
except (GAPI.notFound, GAPI.invalidArgument, GAPI.internalError, GAPI.permissionDenied) as e:
|
||||
exitIfChatNotConfigured(chat, kvList, str(e), i, count)
|
||||
continue
|
||||
except GAPI.failedPrecondition:
|
||||
_getMain().userChatServiceNotEnabledWarning(user, i, count)
|
||||
continue
|
||||
jcount = len(spaces)
|
||||
if jcount == 0:
|
||||
_getMain().setSysExitRC(_getMain().NO_ENTITIES_FOUND_RC)
|
||||
if not csvPF:
|
||||
if not FJQC.formatJSON:
|
||||
_getMain().entityPerformActionNumItems(kvList, jcount, Ent.CHAT_SPACE, i, count)
|
||||
Ind.Increment()
|
||||
j = 0
|
||||
for space in sorted(spaces, key=lambda k: k[sortName]):
|
||||
j += 1
|
||||
_showChatItem(space, Ent.CHAT_SPACE, FJQC, j, jcount)
|
||||
Ind.Decrement()
|
||||
else:
|
||||
for space in sorted(spaces, key=lambda k: k[sortName]):
|
||||
_printChatItem(user, space, None, Ent.CHAT_SPACE, csvPF, FJQC)
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Chat Spaces')
|
||||
|
||||
def doPrintShowChatSpaces():
|
||||
printShowChatSpaces([None])
|
||||
|
||||
Reference in New Issue
Block a user