diff --git a/src/gam/__init__.py b/src/gam/__init__.py index d1337ff5..31474788 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -132,19 +132,19 @@ from filelock import FileLock if platform.system() == 'Linux': import distro -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 glgdata as GDATA -from gamlib import glglobals as GM -from gamlib import glindent -from gamlib import glmsgs as Msg -from gamlib import glskus as SKU -from gamlib import gluprop as UProp -from gamlib import glverlibs +from gamlib import action +from gamlib import api as API +from gamlib import settings as GC +from gamlib import clargs +from gamlib import entity +from gamlib import gapi as GAPI +from gamlib import gdata as GDATA +from gamlib import state as GM +from gamlib import indent +from gamlib import msgs as Msg +from gamlib import skus as SKU +from gamlib import uprop as UProp +from gamlib import verlibs import gdata.apps.service import gdata.apps.audit diff --git a/src/gam/cmd/admin.py b/src/gam/cmd/admin.py index 1fc94e9e..754a186a 100644 --- a/src/gam/cmd/admin.py +++ b/src/gam/cmd/admin.py @@ -5,11 +5,11 @@ import json import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import accessErrorExit from gam.util.api import buildGAPIObject, callGAPI, callGAPIitems, callGAPIpages diff --git a/src/gam/cmd/alerts.py b/src/gam/cmd/alerts.py index f27ba14c..6fd190cc 100644 --- a/src/gam/cmd/alerts.py +++ b/src/gam/cmd/alerts.py @@ -5,11 +5,11 @@ import sys from gam.util.args import formatLocalTime -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import _getAdminEmail, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/aliases.py b/src/gam/cmd/aliases.py index 1339a2d0..b3518c2f 100644 --- a/src/gam/cmd/aliases.py +++ b/src/gam/cmd/aliases.py @@ -3,11 +3,11 @@ import re import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages diff --git a/src/gam/cmd/analytics.py b/src/gam/cmd/analytics.py index 60727a14..174021b5 100644 --- a/src/gam/cmd/analytics.py +++ b/src/gam/cmd/analytics.py @@ -2,11 +2,11 @@ import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIServiceObject, callGAPIpages from gam.util.args import getArgument, getBoolean, getInteger, getString diff --git a/src/gam/cmd/audit.py b/src/gam/cmd/audit.py index 77ef6388..d39ed341 100644 --- a/src/gam/cmd/audit.py +++ b/src/gam/cmd/audit.py @@ -5,11 +5,11 @@ Mailbox monitor creation/deletion/listing and the doWhatIs command. import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import callGData, getEmailAuditObject diff --git a/src/gam/cmd/browsers.py b/src/gam/cmd/browsers.py index 9b135aee..f66a2707 100644 --- a/src/gam/cmd/browsers.py +++ b/src/gam/cmd/browsers.py @@ -2,11 +2,11 @@ import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages, yieldGAPIpages diff --git a/src/gam/cmd/caa.py b/src/gam/cmd/caa.py index cc81ad97..9c68dc12 100644 --- a/src/gam/cmd/caa.py +++ b/src/gam/cmd/caa.py @@ -3,11 +3,11 @@ import json import string -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/calendar.py b/src/gam/cmd/calendar.py index 6694ac90..1b0b6b67 100644 --- a/src/gam/cmd/calendar.py +++ b/src/gam/cmd/calendar.py @@ -6,11 +6,11 @@ import json from gam.util.csv_pf import RI_ENTITY, RI_J, RI_JCOUNT, RI_ITEM, FormatJSONQuoteChar import uuid -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit, entityUnknownWarning from gam.util.api import ( @@ -138,7 +138,7 @@ def makeRoleRuleIdBody(role, ruleId): def normalizeCalendarId(calId, user): if not user or calId.lower() != 'primary': - return convertUIDtoEmailAddress(calId, buildGAPIObject(API.DIRECTORY), emailTypes=['user', 'resource']) + return convertUIDtoEmailAddress(calId, emailTypes=['user', 'resource']) return user def checkCalendarExists(cal, calId, i, count, showMessage=False): @@ -1525,7 +1525,7 @@ def _getCalendarMoveEventsOptions(calendarEventEntity=None): elif calendarEventEntity and myarg in {'id', 'eventid'}: calendarEventEntity['list'].append(getString(Cmd.OB_EVENT_ID)) elif calendarEventEntity and myarg == 'destination': - newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM), buildGAPIObject(API.DIRECTORY)) + newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM)) else: unknownArgumentExit() return (parameters, newCalId) @@ -1572,7 +1572,7 @@ def _moveCalendarEvents(origUser, user, origCal, calIds, count, calendarEventEnt def doCalendarsMoveEvents(calIds): calendarEventEntity = getCalendarEventEntity() checkArgumentPresent(['to', 'destination']) - newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM), buildGAPIObject(API.DIRECTORY)) + newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM)) parameters, _ = _getCalendarMoveEventsOptions() if not checkCalendarExists(None, newCalId, 0, 0, True): return diff --git a/src/gam/cmd/chat/members.py b/src/gam/cmd/chat/members.py index 5e77e9e1..6685b7f4 100644 --- a/src/gam/cmd/chat/members.py +++ b/src/gam/cmd/chat/members.py @@ -6,15 +6,11 @@ Part of the _chat_tmp sub-package.""" import uuid -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import _getAdminEmail, buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( AND_OR_CONJUNCTION_MAP, @@ -56,11 +52,7 @@ from gam.util.entity import ( from gam.util.errors import missingArgumentExit, unknownArgumentExit, usageErrorExit from gam.util.output import stderrWarningMsg, writeStdout -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def _getChatMemberEmail(cd, member): if 'member' in member: diff --git a/src/gam/cmd/chat/setup.py b/src/gam/cmd/chat/setup.py index 564351d6..113d182f 100644 --- a/src/gam/cmd/chat/setup.py +++ b/src/gam/cmd/chat/setup.py @@ -10,15 +10,11 @@ import sys import base64 import os -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import ( buildGAPIObject, buildGAPIServiceObject, @@ -64,11 +60,7 @@ from gam.util.output import setSysExitRC, systemErrorExit, writeStdout from gam.constants import ADMIN_ACCESS_OPTIONS, API_ACCESS_DENIED_RC, GOOGLE_API_ERROR_RC, NO_ENTITIES_FOUND_RC from gam.util.tags import _substituteForUser -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def buildChatServiceObject(api=API.CHAT, user=None, i=0, count=0, entityTypeList=None, useAdminAccess=False): if user is None: diff --git a/src/gam/cmd/chat/spaces.py b/src/gam/cmd/chat/spaces.py index 2eaac21e..82ad36cf 100644 --- a/src/gam/cmd/chat/spaces.py +++ b/src/gam/cmd/chat/spaces.py @@ -8,15 +8,11 @@ import json import sys import uuid -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( OrderBy, @@ -59,11 +55,7 @@ from gam.util.errors import ( from gam.util.output import setSysExitRC, systemErrorExit, writeStdout from gam.constants import NO_ENTITIES_FOUND_RC -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def getSpaceName(myarg): if myarg == 'space': diff --git a/src/gam/cmd/chromeapps.py b/src/gam/cmd/chromeapps.py index dd64a21c..ab26a90a 100644 --- a/src/gam/cmd/chromeapps.py +++ b/src/gam/cmd/chromeapps.py @@ -3,11 +3,11 @@ import re import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit from gam.util.api import buildGAPIObject, buildGAPIObjectNoAuthentication, callGAPI, callGAPIpages diff --git a/src/gam/cmd/chromepolicies.py b/src/gam/cmd/chromepolicies.py index 2065a2ff..081ef8bf 100644 --- a/src/gam/cmd/chromepolicies.py +++ b/src/gam/cmd/chromepolicies.py @@ -5,11 +5,11 @@ import json import mimetypes import os -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages diff --git a/src/gam/cmd/cidevices.py b/src/gam/cmd/cidevices.py index c09efa1e..db094ef6 100644 --- a/src/gam/cmd/cidevices.py +++ b/src/gam/cmd/cidevices.py @@ -4,11 +4,11 @@ import re import json import sys -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import ( diff --git a/src/gam/cmd/cigroups/groups.py b/src/gam/cmd/cigroups/groups.py index b0dece13..cb662b86 100644 --- a/src/gam/cmd/cigroups/groups.py +++ b/src/gam/cmd/cigroups/groups.py @@ -8,15 +8,11 @@ import re from gam.util.entity import GROUP_ROLES_MAP -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( @@ -58,21 +54,15 @@ from gam.cmd.groups.groups import doCreateGroup from gam.cmd.groups.groups import GROUP_ACCESS_TYPE_CHOICE_MAP, GROUP_CIGROUP_FIELDS_MAP, GROUP_JSON_SKIP_FIELDS, GROUP_PREVIEW_TITLES, GroupIsAbuseOrPostmaster, UPDATE_GROUP_SUBCMDS, checkReplyToCustom, getGroupAttrValue, getSettingsFromGroup, getSyncOperation, mapGroupEmailForSettings from gam.cmd.groups.groups import doDeleteGroups -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind CIGROUP_DISCUSSION_FORUM_LABEL = 'cloudidentity.googleapis.com/groups.discussion_forum' CIGROUP_DYNAMIC_LABEL = 'cloudidentity.googleapis.com/groups.dynamic' CIGROUP_SECURITY_LABEL = 'cloudidentity.googleapis.com/groups.security' CIGROUP_LOCKED_LABEL = 'cloudidentity.googleapis.com/groups.locked' - NEVER_TIME = '1970-01-01T00:00:00.000Z' - def doCreateCIGroup(): doCreateGroup(ciGroupsAPI=True) diff --git a/src/gam/cmd/cigroups/members.py b/src/gam/cmd/cigroups/members.py index ee21c627..a2ee50be 100644 --- a/src/gam/cmd/cigroups/members.py +++ b/src/gam/cmd/cigroups/members.py @@ -9,22 +9,13 @@ import json from gam.util.args import formatLocalTime -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() - +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg +from gam.var import Act, Cmd, Ent, Ind from gam.cmd.groups.groups import ( MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP, MEMBEROPTION_ISARCHIVED, @@ -107,7 +98,6 @@ from gam.util.orgunits import _getOrgunitsOrgUnitIdPath from gam.util.output import systemErrorExit, writeStdout CIGROUP_DISCUSSION_FORUM_LABEL = 'cloudidentity.googleapis.com/groups.discussion_forum' - UNKNOWN = 'Unknown' def getCIGroupMemberTypes(myarg, typesSet): @@ -759,9 +749,9 @@ def doPrintCIGroups(): if myarg == 'todrive': csvPF.GetTodriveParameters() elif myarg == 'showownedby': - showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user']) + showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user']) elif myarg in {'cimember', 'enterprisemember', 'ciowner'}: - emailAddress = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user', 'group']) + emailAddress = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user', 'group']) memberQuery = f"member_key_id == '{emailAddress}' && '{CIGROUP_DISCUSSION_FORUM_LABEL}' in labels && parent == '{parent}'" entitySelection = None if myarg == 'ciowner': @@ -1218,9 +1208,9 @@ def doPrintCIGroupMembers(): if myarg == 'todrive': csvPF.GetTodriveParameters() elif myarg == 'showownedby': - showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user']) + showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user']) elif myarg in {'cimember', 'enterprisemember', 'ciowner'}: - emailAddress = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user', 'group']) + emailAddress = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user', 'group']) query = f"member_key_id == '{emailAddress}' && '{CIGROUP_DISCUSSION_FORUM_LABEL}' in labels && parent == '{parent}'" entityList = None if myarg == 'ciowner': @@ -1473,9 +1463,9 @@ def doShowCIGroupMembers(): while Cmd.ArgumentsRemaining(): myarg = getArgument() if myarg == 'showownedby': - showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user']) + showOwnedBy = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user']) elif myarg in {'cimember', 'enterprisemember', 'ciowner'}: - emailAddress = convertUIDtoEmailAddress(getEmailAddress(), buildGAPIObject(API.DIRECTORY), emailTypes=['user', 'group']) + emailAddress = convertUIDtoEmailAddress(getEmailAddress(), emailTypes=['user', 'group']) query = f"member_key_id == '{emailAddress}' && '{CIGROUP_DISCUSSION_FORUM_LABEL}' in labels parent == '{parent}'" entityList = None if myarg == 'ciowner': diff --git a/src/gam/cmd/ciuserinvitations.py b/src/gam/cmd/ciuserinvitations.py index dab5aa3a..374f12ce 100644 --- a/src/gam/cmd/ciuserinvitations.py +++ b/src/gam/cmd/ciuserinvitations.py @@ -3,11 +3,11 @@ import re import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages @@ -230,7 +230,7 @@ def checkCIUserIsInvitable(users): i, count, users = getEntityArgument(users) for user in users: i += 1 - user = convertUIDtoEmailAddress(user, buildGAPIObject(API.DIRECTORY)) + user = convertUIDtoEmailAddress(user) name = quotedCIUserInvitatonsEmail(customer, user) try: result = callGAPI(ci.customers().userinvitations(), 'isInvitableUser', diff --git a/src/gam/cmd/cloudstorage.py b/src/gam/cmd/cloudstorage.py index 098b10e3..028b6114 100644 --- a/src/gam/cmd/cloudstorage.py +++ b/src/gam/cmd/cloudstorage.py @@ -9,11 +9,11 @@ import base64 import os import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPIpages, checkGAPIError from gam.util.args import getArgument, getBoolean, getString diff --git a/src/gam/cmd/contacts.py b/src/gam/cmd/contacts.py index 252e5581..1ff09be5 100644 --- a/src/gam/cmd/contacts.py +++ b/src/gam/cmd/contacts.py @@ -5,15 +5,15 @@ import json import gdata.apps.contacts -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import NO_ENTITIES_FOUND_RC -from gamlib import glgdata as GDATA +from gamlib import gdata as GDATA from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import callGData, callGDataPages, getContactsObject, getContactsQuery diff --git a/src/gam/cmd/courses/content.py b/src/gam/cmd/courses/content.py index 12570c6a..e3a63dd1 100644 --- a/src/gam/cmd/courses/content.py +++ b/src/gam/cmd/courses/content.py @@ -8,15 +8,11 @@ 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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( OrderBy, @@ -37,11 +33,7 @@ from gam.util.csv_pf import ( from gam.util.display import entityActionFailedWarning, entityDoesNotHaveItemWarning, getPageMessageForWhom, printGettingAllEntityItemsForWhom from gam.util.entity import getEntityList -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def doPrintCourseAnnouncements(): def _printCourseAnnouncement(course, courseAnnouncement, i, count): diff --git a/src/gam/cmd/courses/courses.py b/src/gam/cmd/courses/courses.py index 38d80e63..43b13b2c 100644 --- a/src/gam/cmd/courses/courses.py +++ b/src/gam/cmd/courses/courses.py @@ -8,15 +8,11 @@ import re import json import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( @@ -71,11 +67,7 @@ from gam.util.fileio import UNKNOWN from gam.util.output import currentCount, formatKeyValueList, writeStdout from gam.constants import OWNER_ACCESS_OPTIONS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def checkCourseExists(croom, courseId, i=0, count=0, entityType=Ent.COURSE): courseId = addCourseIdScope(courseId) diff --git a/src/gam/cmd/courses/guardians.py b/src/gam/cmd/courses/guardians.py index 85a71db2..09e0ee55 100644 --- a/src/gam/cmd/courses/guardians.py +++ b/src/gam/cmd/courses/guardians.py @@ -7,17 +7,13 @@ Part of the _courses_tmp sub-package.""" import re import json -from gamlib import gluprop as UProp +from gamlib import uprop as UProp -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( @@ -64,11 +60,7 @@ from gam.util.output import ( ) from gam.constants import ADMIN_ACCESS_OPTIONS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def studentUnknownWarning(studentId, errMsg, i, count): setSysExitRC(SERVICE_NOT_APPLICABLE_RC) diff --git a/src/gam/cmd/courses/participants.py b/src/gam/cmd/courses/participants.py index ccdcd8b2..c5d92873 100644 --- a/src/gam/cmd/courses/participants.py +++ b/src/gam/cmd/courses/participants.py @@ -9,15 +9,11 @@ import json from gam.util.csv_pf import RI_ENTITY, RI_J, RI_JCOUNT, RI_ITEM -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, callGAPI, checkGAPIError, waitOnFailure from gam.util.args import ( SORF_TEXT_ARGUMENTS, @@ -45,12 +41,7 @@ from gam.util.errors import missingArgumentExit, unknownArgumentExit from gam.util.output import executeBatch, writeStdout from gam.constants import OWNER_ACCESS_OPTIONS from gam.cmd.groups.groups import getSyncOperation - -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def doPrintCourseParticipants(): croom = buildGAPIObject(API.CLASSROOM) @@ -688,10 +679,8 @@ def doCourseSyncParticipants(courseIdList, _): if syncOperation != 'addonly': _batchRemoveItemsFromCourse(courseInfo['croom'], courseId, i, count, list(currentParticipantsSet-syncParticipantsSet), role) - # Dispatch tables and routing (moved from __init__.py) # Additional imports for dispatch -from gam.var import Act, Cmd from gam.constants import CMD_ACTION, CMD_FUNCTION # Course command sub-commands diff --git a/src/gam/cmd/cros.py b/src/gam/cmd/cros.py index a4c58187..c3051950 100644 --- a/src/gam/cmd/cros.py +++ b/src/gam/cmd/cros.py @@ -9,11 +9,11 @@ from gam.util.csv_pf import RI_J, RI_JCOUNT, RI_ITEM import os import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit from gam.util.api import ( diff --git a/src/gam/cmd/customer.py b/src/gam/cmd/customer.py index 6011195e..8383f294 100644 --- a/src/gam/cmd/customer.py +++ b/src/gam/cmd/customer.py @@ -2,11 +2,11 @@ import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import accessErrorExit from gam.util.api import buildGAPIObject, callGAPI, callGAPIitems diff --git a/src/gam/cmd/datatransfer.py b/src/gam/cmd/datatransfer.py index aeae7447..ef420177 100644 --- a/src/gam/cmd/datatransfer.py +++ b/src/gam/cmd/datatransfer.py @@ -5,11 +5,11 @@ import sys from gam.util.args import formatLocalTime import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/delegates.py b/src/gam/cmd/delegates.py index dd6950f6..e608900c 100644 --- a/src/gam/cmd/delegates.py +++ b/src/gam/cmd/delegates.py @@ -1,11 +1,11 @@ """GAM contact delegate management.""" -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import checkForExtraneousArguments, getArgument diff --git a/src/gam/cmd/domains.py b/src/gam/cmd/domains.py index 409440a7..acf23b4d 100644 --- a/src/gam/cmd/domains.py +++ b/src/gam/cmd/domains.py @@ -5,11 +5,11 @@ import sys import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import accessErrorExit from gam.util.api import buildGAPIObject, callGAPI, callGAPIitems diff --git a/src/gam/cmd/drive/activity.py b/src/gam/cmd/drive/activity.py index ae295932..9722c969 100644 --- a/src/gam/cmd/drive/activity.py +++ b/src/gam/cmd/drive/activity.py @@ -10,15 +10,11 @@ import sys from gam.util.args import formatLocalTime -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import ( _getAdminEmail, buildGAPIObject, @@ -65,10 +61,7 @@ from gam.util.errors import invalidChoiceExit, unknownArgumentExit from gam.util.fileio import UNKNOWN, closeFile from gam.util.gdoc import openCSVFileReader -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -98,7 +91,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def printDriveActivity(users): def _getUserInfo(userId): if userId.startswith('people/'): diff --git a/src/gam/cmd/drive/copymove/copymove_move.py b/src/gam/cmd/drive/copymove/copymove_move.py index 69fd0931..ddb7dac9 100644 --- a/src/gam/cmd/drive/copymove/copymove_move.py +++ b/src/gam/cmd/drive/copymove/copymove_move.py @@ -14,15 +14,11 @@ from gam.cmd.drive.core import DFA_SEARCHARGS from gam.cmd.drive.copymove.copymove_util import _checkForDuplicateTargetFile, _checkForExistingShortcut, _copyPermissions, _getCopyFolderNonInheritedPermissions, _getCopyMoveParentInfo, _getCopyMoveTargetInfo, _getUniqueFilename, _identicalSourceTarget, _printStatistics, _targetFilenameExists, _verifyUserIsOrganizer, getCopyMoveOptions, initCopyMoveOptions -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import callGAPI, callGAPIpages from gam.util.args import getArgument, getBoolean from gam.util.display import ( @@ -41,10 +37,7 @@ from gam.util.entity import ( from gam.util.errors import unknownArgumentExit from gam.constants import ANY_NON_TRASHED_WITH_PARENTS, WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -74,7 +67,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - MY_DRIVE = 'My Drive' TEAM_DRIVE = 'Drive' diff --git a/src/gam/cmd/drive/copymove/copymove_util.py b/src/gam/cmd/drive/copymove/copymove_util.py index cb6e6533..f340d8fa 100644 --- a/src/gam/cmd/drive/copymove/copymove_util.py +++ b/src/gam/cmd/drive/copymove/copymove_util.py @@ -13,15 +13,11 @@ import re from gam.cmd.drive.core import DFA_IGNORE_DEFAULT_VISIBILITY, DFA_KEEP_REVISION_FOREVER, DFA_SEARCHARGS import os -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( StartEndTime, @@ -59,10 +55,7 @@ from gam.util.gdoc import openCSVFileReader from gam.util.output import writeStdout from gam.constants import ANY_NON_TRASHED_WITH_PARENTS, WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -92,7 +85,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - MY_DRIVE = 'My Drive' TEAM_DRIVE = 'Drive' diff --git a/src/gam/cmd/drive/core.py b/src/gam/cmd/drive/core.py index e0062952..d17a1726 100644 --- a/src/gam/cmd/drive/core.py +++ b/src/gam/cmd/drive/core.py @@ -13,11 +13,11 @@ import platform import io import os -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages, getHttpObj from gam.util.args import ( LANGUAGE_CODES_MAP, diff --git a/src/gam/cmd/drive/fileinfo.py b/src/gam/cmd/drive/fileinfo.py index 8270ec42..dfd4ec2c 100644 --- a/src/gam/cmd/drive/fileinfo.py +++ b/src/gam/cmd/drive/fileinfo.py @@ -10,21 +10,14 @@ import platform from gam.cmd.drive.core import _getDriveFileNameFromId, _validateUserGetFileIDs, getDriveFileEntity import os -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -54,7 +47,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - from gam.cmd.drive.core import ( MimeTypeCheck, _getSharedDriveNameFromId, _simpleFileIdEntityList, _validateUserGetFileIDs, _validateUserSharedDrive, @@ -109,7 +101,6 @@ from gam.util.errors import invalidChoiceExit, unknownArgumentExit, usageErrorEx from gam.util.output import writeStdout from gam.cmd.groups.members import finalizeInternalDomains - SHARED_DRIVE_MAX_FILES_FOLDERS = 500000 TEAM_DRIVE = 'Drive' MY_DRIVE = 'My Drive' diff --git a/src/gam/cmd/drive/filelist.py b/src/gam/cmd/drive/filelist.py index 8f894241..bc2453ca 100644 --- a/src/gam/cmd/drive/filelist.py +++ b/src/gam/cmd/drive/filelist.py @@ -14,21 +14,14 @@ from gam.cmd.drive.filepaths import _finalizeIncludeLabels, _finalizeIncludePerm from gam.util.csv_pf import DEFAULT_SKIP_OBJECTS -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import NO_ENTITIES_FOUND_RC, TEAM_DRIVE, WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -58,7 +51,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - from gam.cmd.drive.filepaths import ( addFilePathsToInfo, addFilePathsToRow, @@ -84,7 +76,6 @@ from gam.cmd.drive.core import ( initDriveFileEntity, ) - from gam.cmd.drive.filetree import ( CHECK_LOCATION_FIELDS_TITLES, DRIVE_INDEXED_TITLES, @@ -151,7 +142,6 @@ from gam.util.output import ( writeStdout, ) - MY_DRIVE = 'My Drive' NEVER_TIME = '1970-01-01T00:00:00.000Z' diff --git a/src/gam/cmd/drive/filepaths.py b/src/gam/cmd/drive/filepaths.py index 42c4f4c3..5b3a1e56 100644 --- a/src/gam/cmd/drive/filepaths.py +++ b/src/gam/cmd/drive/filepaths.py @@ -13,21 +13,14 @@ from gam.cmd.drive.labels import normalizeDriveLabelID from gam.util.csv_pf import DEFAULT_SKIP_OBJECTS -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import MY_DRIVE, TEAM_DRIVE -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -57,7 +50,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - from gam.cmd.drive.core import DRIVE_LABEL_CHOICE_MAP # cross-module ref from gam.util.api import callGAPI, callGAPIitems, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/drive/files.py b/src/gam/cmd/drive/files.py index 359440ee..80f39fff 100644 --- a/src/gam/cmd/drive/files.py +++ b/src/gam/cmd/drive/files.py @@ -10,15 +10,11 @@ from gam.cmd.drive.core import DFA_IGNORE_DEFAULT_VISIBILITY, DFA_KEEP_REVISION_ from gam.cmd.drive.fileinfo import writeReturnIdLink import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems, callGAPIpages from gam.util.args import ( getAddCSVData, @@ -54,10 +50,7 @@ from gam.util.fileio import UNKNOWN, readFile from gam.util.output import writeStdout from gam.constants import AND_NOT_SHORTCUT, ANY_NON_TRASHED_FOLDER_NAME_WITH_PARENTS, MY_DRIVE, MY_NON_TRASHED_FOLDER_NAME_WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -87,7 +80,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def processFilenameReplacements(name, replacements): for replacement in replacements: name = re.sub(replacement[0], replacement[1], name) diff --git a/src/gam/cmd/drive/filetree.py b/src/gam/cmd/drive/filetree.py index 4c4d24e8..c6200186 100644 --- a/src/gam/cmd/drive/filetree.py +++ b/src/gam/cmd/drive/filetree.py @@ -9,22 +9,15 @@ import re from gam.cmd.drive.core import _getSharedDriveNameFromId, _mapDrive2QueryToDrive3, cleanFileIDsList, escapeDriveFileName, getEscapedDriveFileName, initDriveFileEntity from gam.cmd.drive.revisions import _stripMeInOwners, _stripNotMeInOwners, _updateAnyOwnerQuery -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.entity import QUERY_SHORTCUTS_MAP from gam.constants import MY_DRIVE, TEAM_DRIVE -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -54,7 +47,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - from gam.cmd.drive.core import ( MimeTypeCheck, DRIVE_BY_NAME_CHOICE_MAP, @@ -86,7 +78,6 @@ from gam.util.args import ( from gam.util.display import entityActionFailedWarning, userDriveServiceNotEnabledWarning from gam.util.errors import invalidChoiceExit, unknownArgumentExit, usageErrorExit - def initFileTree(drive, shareddrive, DLP, shareddriveFields, showParent, user, i, count): fileTree = { ORPHANS: {'info': {'id': ORPHANS, 'name': ORPHANS, 'mimeType': MIMETYPE_GA_FOLDER, 'ownedByMe': True, 'parents': []}, @@ -223,7 +214,6 @@ def buildFileTree(feed, drive): fileTree[parentId]['children'].append(fileId) return fileTree - def _validateACLOwnerType(location, body): if body.get('role', '') == 'owner' and body['type'] != 'user': Cmd.SetLocation(location) diff --git a/src/gam/cmd/drive/labels.py b/src/gam/cmd/drive/labels.py index 6bcb7487..64ef7dc7 100644 --- a/src/gam/cmd/drive/labels.py +++ b/src/gam/cmd/drive/labels.py @@ -9,15 +9,11 @@ import json from gam.cmd.drive.core import _validateUserGetFileIDs, getDriveFileEntity -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import _getAdminEmail, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( BCP47_LANGUAGE_CODES_MAP, @@ -61,10 +57,7 @@ from gam.util.entity import ( from gam.util.errors import missingArgumentExit, unknownArgumentExit, usageErrorExit from gam.constants import ADMIN_ACCESS_OPTIONS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -94,7 +87,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def _getDisplayDriveLabelsParameters(myarg, parameters): if myarg in DRIVELABELS_PROJECTION_CHOICE_MAP: parameters['view'] = DRIVELABELS_PROJECTION_CHOICE_MAP[myarg] diff --git a/src/gam/cmd/drive/looker.py b/src/gam/cmd/drive/looker.py index 52bd7f5e..f06f1b96 100644 --- a/src/gam/cmd/drive/looker.py +++ b/src/gam/cmd/drive/looker.py @@ -8,15 +8,11 @@ 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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( OrderBy, @@ -44,10 +40,7 @@ from gam.util.display import ( ) from gam.util.entity import getEntityArgument, getUserObjectEntity -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -77,7 +70,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - LOOKERSTUDIO_ASSETTYPE_CHOICE_MAP = { 'report': ['REPORT'], 'datasource': ['DATA_SOURCE'], diff --git a/src/gam/cmd/drive/permissions.py b/src/gam/cmd/drive/permissions.py index 0edfb645..f50762c3 100644 --- a/src/gam/cmd/drive/permissions.py +++ b/src/gam/cmd/drive/permissions.py @@ -13,15 +13,11 @@ from gam.cmd.drive.filetree import _validateACLAttributes, _validateACLOwnerType from gam.util.csv_pf import RI_ENTITY, RI_I, RI_COUNT, RI_J, RI_JCOUNT, RI_ITEM -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import ( _getAdminEmail, buildGAPIServiceObject, @@ -88,10 +84,7 @@ from gam.util.fileio import UNKNOWN from gam.util.output import executeBatch from gam.constants import ADMIN_ACCESS_OPTIONS, WITH_PARENTS -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -121,7 +114,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def printEmptyDriveFolders(users): def _checkChildDriveFolderContents(drive, fileEntry, user, i, count, pathList): query = WITH_PARENTS.format(fileEntry ['id']) diff --git a/src/gam/cmd/drive/revisions.py b/src/gam/cmd/drive/revisions.py index af7a0f83..f3ae2a34 100644 --- a/src/gam/cmd/drive/revisions.py +++ b/src/gam/cmd/drive/revisions.py @@ -8,15 +8,11 @@ import re from gam.cmd.drive.core import _getDriveFileNameFromId, _validateUserGetFileIDs, getDriveFileEntity -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import callGAPI, callGAPIpages from gam.util.args import ( OrderBy, @@ -51,10 +47,7 @@ from gam.util.errors import missingArgumentExit, unknownArgumentExit from gam.util.output import _stripControlCharsFromName, setSysExitRC from gam.constants import AND_ME_IN_OWNERS, AND_NOT_ME_IN_OWNERS, NO_ENTITIES_FOUND_RC -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -84,7 +77,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def getRevisionsEntity(): revisionsEntity = {'list': [], 'dict': None, 'count': None, 'time': None, 'range': None} startEndTime = StartEndTime() diff --git a/src/gam/cmd/drive/shareddrives.py b/src/gam/cmd/drive/shareddrives.py index e5f45f3b..d068d8bf 100644 --- a/src/gam/cmd/drive/shareddrives.py +++ b/src/gam/cmd/drive/shareddrives.py @@ -19,15 +19,11 @@ import time from gam.cmd.drive.core import getSharedDriveEntity, _validateUserSharedDrive -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import ( _getAdminEmail, _getValueFromOAuth, @@ -96,10 +92,7 @@ from gam.util.output import setSysExitRC, systemErrorExit, writeStderr, writeStd from gam.constants import ADMIN_ACCESS_OPTIONS, GOOGLE_API_ERROR_RC, NO_ENTITIES_FOUND_RC from gam.cmd.orgunits import getOrgUnitIdToPathMap -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -129,7 +122,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def doPrintShowOwnership(): rep = buildGAPIObject(API.REPORTS) customerId = GC.Values[GC.CUSTOMER_ID] diff --git a/src/gam/cmd/drive/transfer/fileops.py b/src/gam/cmd/drive/transfer/fileops.py index b76cd01e..616d0402 100644 --- a/src/gam/cmd/drive/transfer/fileops.py +++ b/src/gam/cmd/drive/transfer/fileops.py @@ -18,15 +18,11 @@ from gam.cmd.drive.core import DFA_PARENTID, DFA_PARENTQUERY, _validateUserGetFi import os import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems, callGAPIpages from gam.util.args import ( OrderBy, @@ -76,10 +72,7 @@ from gam.util.output import setSysExitRC, writeStderr from gam.constants import MY_NON_TRASHED_FOLDER_NAME from gam.util.tags import _substituteForUser -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -109,7 +102,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - UNKNOWN = 'Unknown' ORPHANS_COLLECTED_RC = 30 diff --git a/src/gam/cmd/drive/transfer/ownership.py b/src/gam/cmd/drive/transfer/ownership.py index 0923aceb..abca77b2 100644 --- a/src/gam/cmd/drive/transfer/ownership.py +++ b/src/gam/cmd/drive/transfer/ownership.py @@ -11,15 +11,11 @@ Part of the transfer sub-package.""" import re 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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( OrderBy, @@ -63,10 +59,7 @@ from gam.util.output import formatKeyValueList, printWarningMessage, systemError from gam.constants import MY_DRIVE, MY_NON_TRASHED_FOLDER_NAME, MY_NON_TRASHED_FOLDER_NAME_WITH_PARENTS, NON_TRASHED, TARGET_DRIVE_SPACE_ERROR_RC, WITH_PARENTS from gam.util.tags import _substituteForUser -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind APPLICATION_VND_GOOGLE_APPS = 'application/vnd.google-apps.' MIMETYPE_GA_DOCUMENT = f'{APPLICATION_VND_GOOGLE_APPS}document' @@ -96,7 +89,6 @@ ORPHANS = 'Orphans' SHARED_WITHME = 'SharedWithMe' SHARED_DRIVES = 'SharedDrives' - def transferDrive(users): def _getOwnerUser(childEntryInfo): diff --git a/src/gam/cmd/gmail/cse.py b/src/gam/cmd/gmail/cse.py index e653adc4..21841361 100644 --- a/src/gam/cmd/gmail/cse.py +++ b/src/gam/cmd/gmail/cse.py @@ -9,15 +9,11 @@ import json import sys import os -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( UTF8, @@ -48,11 +44,7 @@ from gam.util.errors import entityDoesNotExistExit, missingArgumentExit, usageEr from gam.util.fileio import readFile, setFilePath from gam.util.output import writeStdout -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def _showCSEItem(result, entityType, keyField, timeObjects, i, count, FJQC): if FJQC.formatJSON: diff --git a/src/gam/cmd/gmail/delegates.py b/src/gam/cmd/gmail/delegates.py index 27d27bf2..41e77dc5 100644 --- a/src/gam/cmd/gmail/delegates.py +++ b/src/gam/cmd/gmail/delegates.py @@ -6,15 +6,11 @@ Part of the _gmail_monolith sub-package.""" import re -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI from gam.util.args import checkArgumentPresent, checkForExtraneousArguments, getArgument from gam.util.csv_pf import CSVPrintFile @@ -34,11 +30,7 @@ from gam.util.output import writeStdout from gam.cmd.users.manage import getNotifyArguments from gam.cmd.delegates import _getDelegateName -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind UTF8 = 'utf-8' diff --git a/src/gam/cmd/gmail/filters.py b/src/gam/cmd/gmail/filters.py index bd3eb2c6..f4bbdbf2 100644 --- a/src/gam/cmd/gmail/filters.py +++ b/src/gam/cmd/gmail/filters.py @@ -10,15 +10,11 @@ import sys from gam.cmd.gmail.labels import _getLabelId, _getLabelName, _getLabelSet, _getUserGmailLabels, buildLabelPath -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems from gam.util.args import ( ONE_KILO_10_BYTES, @@ -49,11 +45,7 @@ from gam.util.entity import _validateUserGetObjectList, getEntityArgument, getUs from gam.util.errors import missingChoiceExit, unknownArgumentExit, usageErrorExit from gam.util.output import ERROR -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind ONE_KILO_10_BYTES = 1000 ONE_MEGA_10_BYTES = 1000 * 1000 diff --git a/src/gam/cmd/gmail/forms.py b/src/gam/cmd/gmail/forms.py index 53cae51b..1bfb6568 100644 --- a/src/gam/cmd/gmail/forms.py +++ b/src/gam/cmd/gmail/forms.py @@ -7,15 +7,11 @@ Part of the _gmail_monolith sub-package.""" import re import json -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( getAddCSVData, @@ -47,11 +43,7 @@ from gam.util.output import writeStdout from gam.cmd.drive.core import _getDriveFileParentInfo, getDriveFileParentAttribute, initDriveFileAttributes from gam.cmd.drive.core import _validateUserGetFileIDs, getDriveFileEntity -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind MIMETYPE_GA_FORM = 'application/vnd.google-apps.form' diff --git a/src/gam/cmd/gmail/labels.py b/src/gam/cmd/gmail/labels.py index e1affd4a..6bb45790 100644 --- a/src/gam/cmd/gmail/labels.py +++ b/src/gam/cmd/gmail/labels.py @@ -8,15 +8,11 @@ import re from gam.util.csv_pf import RI_ENTITY, RI_J, RI_JCOUNT, RI_ITEM -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages, checkGAPIError from gam.util.args import ( LABEL_BACKGROUND_COLORS, @@ -52,11 +48,7 @@ from gam.util.errors import missingArgumentExit, unknownArgumentExit, usageError from gam.util.output import executeBatch, setSysExitRC from gam.constants import NO_ENTITIES_FOUND_RC -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def _getUserGmailLabels(gmail, user, i, count, fields): try: diff --git a/src/gam/cmd/gmail/messages.py b/src/gam/cmd/gmail/messages.py index 07f56d1c..21701960 100644 --- a/src/gam/cmd/gmail/messages.py +++ b/src/gam/cmd/gmail/messages.py @@ -18,15 +18,11 @@ import base64 import os import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import ( _getAdminEmail, buildGAPIObject, @@ -104,11 +100,7 @@ from gam.util.tags import ( ) from gam.cmd.drive.core import _getDriveFileParentInfo, getDriveFileParentAttribute, initDriveFileAttributes -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind from email.header import decode_header from email import message_from_string diff --git a/src/gam/cmd/gmail/profile.py b/src/gam/cmd/gmail/profile.py index 6a62271b..b888893b 100644 --- a/src/gam/cmd/gmail/profile.py +++ b/src/gam/cmd/gmail/profile.py @@ -10,15 +10,11 @@ import sys import uuid import base64 -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import getArgument, getInteger from gam.util.csv_pf import CSVPrintFile, getTodriveOnly @@ -32,11 +28,7 @@ from gam.util.display import ( from gam.util.entity import getEntityArgument from gam.util.errors import unknownArgumentExit -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def watchGmail(users): maxMessages = 100 diff --git a/src/gam/cmd/gmail/settings.py b/src/gam/cmd/gmail/settings.py index 97049c00..df6408a0 100644 --- a/src/gam/cmd/gmail/settings.py +++ b/src/gam/cmd/gmail/settings.py @@ -8,15 +8,11 @@ import re from gam.cmd.gmail.messages import forwardMessagesThreads -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems from gam.util.args import ( LANGUAGE_CODES_MAP, @@ -54,11 +50,7 @@ from gam.util.tags import ( _processTagReplacements, ) -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def _showForward(user, i, count, result): if 'enabled' in result: diff --git a/src/gam/cmd/gmail/signature.py b/src/gam/cmd/gmail/signature.py index 64400a02..772ace77 100644 --- a/src/gam/cmd/gmail/signature.py +++ b/src/gam/cmd/gmail/signature.py @@ -8,15 +8,11 @@ import re from gam.cmd.gmail.settings import _processSendAs, _processSignature, getSendAsAttributes -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI from gam.util.args import ( FALSE_VALUES, @@ -48,11 +44,7 @@ from gam.util.tags import ( _processTagReplacements, ) -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def setSignature(users): tagReplacements = _initTagReplacements() diff --git a/src/gam/cmd/gmail/smime.py b/src/gam/cmd/gmail/smime.py index 999ab465..7aa58744 100644 --- a/src/gam/cmd/gmail/smime.py +++ b/src/gam/cmd/gmail/smime.py @@ -9,15 +9,11 @@ import re from gam.util.args import formatLocalTimestamp import base64 -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems from gam.util.args import UTF8, getArgument, getEmailAddress, getString from gam.util.csv_pf import CSVPrintFile, flattenJSON @@ -40,11 +36,7 @@ from gam.util.fileio import readFile, setFilePath from gam.util.output import setSysExitRC from gam.constants import NO_ENTITIES_FOUND_RC -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def createSmime(users): sendAsEmailBase = None diff --git a/src/gam/cmd/groups/groups.py b/src/gam/cmd/groups/groups.py index affde270..456955c2 100644 --- a/src/gam/cmd/groups/groups.py +++ b/src/gam/cmd/groups/groups.py @@ -11,15 +11,11 @@ from gam.util.csv_pf import RI_ENTITY, RI_ROLE, RI_I, RI_COUNT, RI_J, RI_JCOUNT, from gam.util.entity import GROUP_ROLES_MAP import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages, checkGAPIError from gam.util.args import ( @@ -79,11 +75,7 @@ from gam.constants import GROUP_ALIAS_ATTRIBUTES, GROUP_ASSIST_CONTENT_ATTRIBUTE from gam.constants import GROUP_FIELDS_WITH_CRS_NLS from gam.cmd.ciuserinvitations import _getIsInvitableUser -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind WARNING_PREFIX = 'WARNING: ' diff --git a/src/gam/cmd/groups/members.py b/src/gam/cmd/groups/members.py index c34d50c4..67823157 100644 --- a/src/gam/cmd/groups/members.py +++ b/src/gam/cmd/groups/members.py @@ -15,22 +15,14 @@ from gam.util.csv_pf import RI_ENTITY, RI_ROLE, RI_COUNT from gam.util.entity import GROUP_ROLES_MAP -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import ONE_KILO_BYTES, ONE_MEGA_BYTES -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind from gam.cmd.groups.groups import ALL_GROUP_MEMBER_TYPES, MEMBEROPTION_DISPLAYMATCH, MEMBEROPTION_GETDELIVERYSETTINGS, MEMBEROPTION_INCLUDEDERIVEDMEMBERSHIP, MEMBEROPTION_ISARCHIVED, MEMBEROPTION_ISSUSPENDED, MEMBEROPTION_MATCHPATTERN, MEMBEROPTION_MEMBERNAMES, MEMBEROPTION_NODUPLICATES, MEMBEROPTION_RECURSIVE, getGroupMemberTypes, GroupIsAbuseOrPostmaster, mapGroupEmailForSettings from gam.util.access import entityUnknownWarning @@ -127,7 +119,6 @@ from gam.util.domain_filters import ( from gam.util.schema_utils import _initSchemaParms, _getSchemaNameList from gam.util.output import executeBatch, writeStderr, writeStdout - def initMemberOptions(): return [False, False, False, False, None, None, False, None, True] diff --git a/src/gam/cmd/licenses.py b/src/gam/cmd/licenses.py index 058e040f..c2c9d538 100644 --- a/src/gam/cmd/licenses.py +++ b/src/gam/cmd/licenses.py @@ -1,14 +1,14 @@ """GAM license management.""" -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg -from gamlib import glskus as SKU +from gamlib import skus as SKU from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPIpages from gam.util.args import getArgument, getGoogleProductList, getGoogleSKUList, getInteger diff --git a/src/gam/cmd/meet.py b/src/gam/cmd/meet.py index 5c6dde55..e07256e8 100644 --- a/src/gam/cmd/meet.py +++ b/src/gam/cmd/meet.py @@ -2,11 +2,11 @@ import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/mobile.py b/src/gam/cmd/mobile.py index c88c6083..c7a475df 100644 --- a/src/gam/cmd/mobile.py +++ b/src/gam/cmd/mobile.py @@ -2,11 +2,11 @@ import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages, yieldGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/notes.py b/src/gam/cmd/notes.py index 1439db99..20e59761 100644 --- a/src/gam/cmd/notes.py +++ b/src/gam/cmd/notes.py @@ -6,11 +6,11 @@ import json import googleapiclient.http import os -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/oauth.py b/src/gam/cmd/oauth.py index 68aeb974..2855e32d 100644 --- a/src/gam/cmd/oauth.py +++ b/src/gam/cmd/oauth.py @@ -23,11 +23,11 @@ import google_auth_oauthlib.flow from filelock import FileLock from urllib.parse import urlparse, parse_qs, urlencode -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import ( buildGAPIObject, diff --git a/src/gam/cmd/orgunits.py b/src/gam/cmd/orgunits.py index 8a3f2f84..16cadcdf 100644 --- a/src/gam/cmd/orgunits.py +++ b/src/gam/cmd/orgunits.py @@ -5,11 +5,11 @@ import json from gam.util.csv_pf import RI_I, RI_J, RI_JCOUNT, RI_ITEM import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit from gam.util.api import ( diff --git a/src/gam/cmd/people.py b/src/gam/cmd/people.py index 64d93e62..97aa8690 100644 --- a/src/gam/cmd/people.py +++ b/src/gam/cmd/people.py @@ -48,11 +48,11 @@ import time import google.auth import google.auth.exceptions -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.cmd.contacts import ( diff --git a/src/gam/cmd/printers.py b/src/gam/cmd/printers.py index f2ade9f5..a5aee38f 100644 --- a/src/gam/cmd/printers.py +++ b/src/gam/cmd/printers.py @@ -3,11 +3,11 @@ import re import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages diff --git a/src/gam/cmd/project.py b/src/gam/cmd/project.py index b75d62e9..aba4223d 100644 --- a/src/gam/cmd/project.py +++ b/src/gam/cmd/project.py @@ -22,11 +22,11 @@ from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.x509.oid import NameOID -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import ( _getAdminEmail, @@ -1218,7 +1218,7 @@ def checkServiceAccount(users): for user in users: i += 1 allScopesPass = True - user = convertUIDtoEmailAddress(user, buildGAPIObject(API.DIRECTORY)) + user = convertUIDtoEmailAddress(user) printKeyValueListWithCount([Msg.DOMAIN_WIDE_DELEGATION_AUTHENTICATION, '', Ent.Singular(Ent.USER), user, Ent.Choose(Ent.SCOPE, jcount), jcount], diff --git a/src/gam/cmd/reports.py b/src/gam/cmd/reports.py index bd06d86d..dc3211a3 100644 --- a/src/gam/cmd/reports.py +++ b/src/gam/cmd/reports.py @@ -5,11 +5,11 @@ import arrow import datetime import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import accessErrorExit, entityUnknownWarning from gam.util.api import _getAdminEmail, buildGAPIObject, callGAPI, callGAPIpages diff --git a/src/gam/cmd/reseller.py b/src/gam/cmd/reseller.py index 338ae23a..fd0eeeea 100644 --- a/src/gam/cmd/reseller.py +++ b/src/gam/cmd/reseller.py @@ -5,12 +5,12 @@ import sys import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg -from gamlib import glskus as SKU +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import skus as SKU from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/resources.py b/src/gam/cmd/resources.py index 7569cf56..3f2c4c7f 100644 --- a/src/gam/cmd/resources.py +++ b/src/gam/cmd/resources.py @@ -3,11 +3,11 @@ import json import uuid -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit, entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages diff --git a/src/gam/cmd/schemas.py b/src/gam/cmd/schemas.py index 4e0eb77f..63454e94 100644 --- a/src/gam/cmd/schemas.py +++ b/src/gam/cmd/schemas.py @@ -1,11 +1,11 @@ """GAM user schema management.""" -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit from gam.util.api import buildGAPIObject, callGAPI diff --git a/src/gam/cmd/send_email.py b/src/gam/cmd/send_email.py index f185d38b..058266d7 100644 --- a/src/gam/cmd/send_email.py +++ b/src/gam/cmd/send_email.py @@ -4,11 +4,11 @@ import time import re -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import entityUnknownWarning from gam.util.api import ( diff --git a/src/gam/cmd/sites.py b/src/gam/cmd/sites.py index e7fdfed9..0ba07400 100644 --- a/src/gam/cmd/sites.py +++ b/src/gam/cmd/sites.py @@ -3,11 +3,11 @@ import json import sys -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import ( buildGAPIObject, diff --git a/src/gam/cmd/sso.py b/src/gam/cmd/sso.py index 445be5ee..25247ff5 100644 --- a/src/gam/cmd/sso.py +++ b/src/gam/cmd/sso.py @@ -3,11 +3,11 @@ import re import json -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/tasks.py b/src/gam/cmd/tasks.py index fe468d50..a79d1497 100644 --- a/src/gam/cmd/tasks.py +++ b/src/gam/cmd/tasks.py @@ -3,11 +3,11 @@ import json import sys -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIpages from gam.util.args import ( diff --git a/src/gam/cmd/userop/licenses.py b/src/gam/cmd/userop/licenses.py index a92903ed..ff1cf321 100644 --- a/src/gam/cmd/userop/licenses.py +++ b/src/gam/cmd/userop/licenses.py @@ -11,16 +11,12 @@ from gam.cmd.userop.usergroups import LICENSE_PREVIEW_TITLES from gam.cmd.userop.usergroups import LICENSE_PRODUCT_SKUIDS -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 -from gamlib import glskus as SKU +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import skus as SKU from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI from gam.util.args import ( @@ -36,11 +32,7 @@ from gam.util.display import entityActionFailedWarning, entityActionPerformed, e from gam.util.entity import getEntityArgument, getItemsToModify from gam.util.errors import invalidChoiceExit, missingArgumentExit, unknownArgumentExit, usageErrorExit -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def getLicenseParameters(operation): lic = buildGAPIObject(API.LICENSING) diff --git a/src/gam/cmd/userop/photos.py b/src/gam/cmd/userop/photos.py index 932b06f5..da6643ff 100644 --- a/src/gam/cmd/userop/photos.py +++ b/src/gam/cmd/userop/photos.py @@ -13,15 +13,11 @@ import os import google.auth import google.auth.exceptions -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, buildGAPIServiceObject, callGAPI, getHttpObj from gam.util.args import ( @@ -48,11 +44,7 @@ from gam.util.output import writeStdout from gam.util.tags import _substituteForUser from gam.cmd.drive.core import _validateUserGetFileIDs, getDriveFileEntity -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind from tempfile import TemporaryFile diff --git a/src/gam/cmd/userop/sheets.py b/src/gam/cmd/userop/sheets.py index a38f7328..6768e348 100644 --- a/src/gam/cmd/userop/sheets.py +++ b/src/gam/cmd/userop/sheets.py @@ -7,15 +7,11 @@ Part of the _userop_tmp sub-package.""" import re import json -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIServiceObject, callGAPI, callGAPIitems from gam.util.args import getArgument, getBoolean, getJSON, getString from gam.util.csv_pf import ( @@ -46,11 +42,7 @@ from gam.cmd.drive.core import _getDriveFileParentInfo, getDriveFileParentAttrib from gam.cmd.drive.core import _validateUserGetFileIDs from gam.cmd.drive.core import getDriveFileEntity -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind ERROR_PREFIX = 'ERROR: ' diff --git a/src/gam/cmd/userop/tokens.py b/src/gam/cmd/userop/tokens.py index aff005c3..26f87934 100644 --- a/src/gam/cmd/userop/tokens.py +++ b/src/gam/cmd/userop/tokens.py @@ -8,15 +8,11 @@ import re from gam.cmd.userop.sheets import commonClientIds -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import ClientAPIAccessDeniedExit, entityUnknownWarning from gam.util.api import _getAdminEmail, buildGAPIObject, callGAPI, callGAPIitems from gam.util.args import ( @@ -46,11 +42,7 @@ from gam.util.errors import unknownArgumentExit from gam.cmd.project import getGCPOrgId from gam.cmd.gmail.settings import _imapDefaults, _popDefaults, _setImap, _setPop -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def deleteTokens(users): cd = buildGAPIObject(API.DIRECTORY) diff --git a/src/gam/cmd/userop/usergroups.py b/src/gam/cmd/userop/usergroups.py index 6a9cc8da..7b7332a4 100644 --- a/src/gam/cmd/userop/usergroups.py +++ b/src/gam/cmd/userop/usergroups.py @@ -18,15 +18,11 @@ from gam.cmd.drive.looker import ( LOOKERSTUDIO_VIEW_PERMISSION_ROLE_CHOICE_MAP, ) -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( @@ -66,11 +62,7 @@ from gam.cmd.drive.looker import _getLookerStudioAssets, _showLookerStudioPermis from gam.util.group_parents import addJsonGroupParents, getGroupParents, printGroupParents, showGroupParents -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind def processLookerStudioPermissions(users): action = Act.Get() diff --git a/src/gam/cmd/users/display.py b/src/gam/cmd/users/display.py index b3137005..fc8d1197 100644 --- a/src/gam/cmd/users/display.py +++ b/src/gam/cmd/users/display.py @@ -28,29 +28,20 @@ from gam.cmd.users.manage import ( USER_TIME_OBJECTS, ) -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() +from gam.var import Act, Cmd, Ent, Ind - -from gamlib import glskus as SKU -from gamlib import gluprop as UProp +from gamlib import skus as SKU +from gamlib import uprop as UProp from gam.util.html import dehtml from gam.cmd.groups.members import INFO_GROUP_OPTIONS from gam.util.display import invalidQuery, invalidUserSchema - from gam.cmd.users.manage import ( # cross-module refs USER_ADDRESSES_PROPERTY_PRINT_ORDER, USER_ARRAY_PROPERTY_PRINT_ORDER, diff --git a/src/gam/cmd/users/manage.py b/src/gam/cmd/users/manage.py index 168dff89..0fa5aafa 100644 --- a/src/gam/cmd/users/manage.py +++ b/src/gam/cmd/users/manage.py @@ -11,16 +11,16 @@ from gam.util.args import DEFAULT_CHOICE from gam.util.entity import GROUP_ROLES_MAP -from gamlib import gluprop as UProp +from gamlib import uprop as UProp import base64 import time -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg -from gamlib import glskus as SKU +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import skus as SKU from gam.util.access import accessErrorExit, duplicateAliasGroupUserWarning, entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages, checkGAPIError from gam.util.args import ( diff --git a/src/gam/cmd/userservices.py b/src/gam/cmd/userservices.py index f3375171..c5ee20e4 100644 --- a/src/gam/cmd/userservices.py +++ b/src/gam/cmd/userservices.py @@ -19,11 +19,11 @@ from gam.cmd.calendar import ( EVENT_TYPE_WORKINGLOCATION, ) -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind from gam.util.access import checkEntityAFDNEorAccessErrorExit, entityUnknownWarning from gam.util.api import ( @@ -1142,7 +1142,7 @@ def printShowCalendarACLs(users): j = 0 for calId in calIds: j += 1 - calId = convertUIDtoEmailAddress(calId, buildGAPIObject(API.DIRECTORY)) + calId = convertUIDtoEmailAddress(calId) _printShowCalendarACLs(cal, user, Ent.CALENDAR, calId, j, jcount, csvPF, FJQC, noSelfOwner, addCSVData) Ind.Decrement() if csvPF: @@ -1269,7 +1269,7 @@ def moveCalendarEvents(users): calendarEntity = getUserCalendarEntity() calendarEventEntity = getCalendarEventEntity() checkArgumentPresent(['to', 'destination']) - newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM), buildGAPIObject(API.DIRECTORY)) + newCalId = convertUIDtoEmailAddress(getString(Cmd.OB_CALENDAR_ITEM)) parameters, _ = _getCalendarMoveEventsOptions() if not checkCalendarExists(None, newCalId, 0, 0, True): return diff --git a/src/gam/cmd/vault/holds.py b/src/gam/cmd/vault/holds.py index fe643663..a390759d 100644 --- a/src/gam/cmd/vault/holds.py +++ b/src/gam/cmd/vault/holds.py @@ -18,23 +18,14 @@ from gam.cmd.vault.matters import ( ) import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import NO_ENTITIES_FOUND_RC, PROJECTION_CHOICE_MAP -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - - +from gam.var import Act, Cmd, Ent, Ind from gam.cmd.vault.matters import ( VAULT_CORPUS_ARGUMENT_MAP, diff --git a/src/gam/cmd/vault/matters.py b/src/gam/cmd/vault/matters.py index 675675dd..518503a9 100644 --- a/src/gam/cmd/vault/matters.py +++ b/src/gam/cmd/vault/matters.py @@ -11,15 +11,11 @@ import base64 import os import time -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 +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.api import buildGAPIObject, callGAPI, callGAPIpages from gam.util.args import ( UID_PATTERN, @@ -82,15 +78,10 @@ from gam.constants import DATA_NOT_AVALIABLE_RC, NO_ENTITIES_FOUND_RC from gam.cmd.cloudstorage import _copyStorageObjects from gam.cmd.cloudstorage import _getCloudStorageObject -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() -Cmd = glclargs.GamCLArgs() - +from gam.var import Act, Cmd, Ent, Ind WARNING_PREFIX = 'WARNING: ' - def formatVaultNameId(vaultName, vaultId): return f'{vaultName}({vaultId})' @@ -442,7 +433,6 @@ def _buildVaultQuery(myarg, query, corpusArgumentMap): else: query.update(jsonData) - def _validateVaultQuery(body, corpusArgumentMap): if 'corpus' not in body['query']: missingArgumentExit(f'corpus {formatChoiceList(corpusArgumentMap)}') diff --git a/src/gam/constants.py b/src/gam/constants.py index 2af8c62e..5532f927 100644 --- a/src/gam/constants.py +++ b/src/gam/constants.py @@ -9,7 +9,7 @@ import re import string import sys -from gamlib import glcfg as GC +from gamlib import settings as GC # Version and author (canonical source: gam/__init__.py) from gam import __author__, __version__, __license__ diff --git a/src/gam/gamlib/action.py b/src/gam/gamlib/action.py new file mode 100644 index 00000000..3d9108ae --- /dev/null +++ b/src/gam/gamlib/action.py @@ -0,0 +1,322 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM action processing + +""" + +class GamAction(): + +# Keys into NAMES; arbitrary values but must be unique + ACCEPT = 'acpt' + ADD = 'add ' + ADD_PREVIEW = 'addp' + APPEND = 'apnd' + APPROVE = 'aprv' + ARCHIVE = 'arch' + BACKUP = 'back' + BLOCK = 'blok' + CANCEL = 'canc' + CANCEL_WIPE = 'canw' + CHECK = 'chek' + CLAIM = 'clai' + CLAIM_OWNERSHIP = 'clow' + CLEAR = 'clea' + CLOSE = 'clos' + COLLECT = 'coll' + COMMENT = 'comm' + COPY = 'copy' + COPY_MERGE = 'copm' + CREATE = 'crea' + CREATE_PREVIEW = 'crep' + CREATE_SHORTCUT = 'crsc' + DEDUP = 'dedu' + DELETE = 'dele' + DELETE_EMPTY = 'delm' + DELETE_PREVIEW = 'delp' + DELETE_SHORTCUT = 'desc' + DEPROVISION = 'depr' + DISABLE = 'disa' + DOWNLOAD = 'down' + DRAFT = 'draf' + EMPTY = 'empt' + ENABLE = 'enbl' + END = 'end ' + EXISTS = 'exis' + EXPORT = 'expo' + EXTRACT = 'extr' + GET_COMMAND_RESULT = 'gtcr' + FETCH = 'fetc' + FORWARD = 'forw' + HIDE = 'hide' + IMPORT = 'impo' + INFO = 'info' + INITIALIZE = 'init' + INSERT = 'insr' + INVALIDATE = 'inva' + ISSUE_COMMAND = 'isco' + LIST = 'list' + LOOKUP = 'look' + MERGE = 'merg' + MODIFY = 'modi' + MOVE = 'move' + MOVE_MERGE = 'movm' + NOACTION = 'noac' + NOACTION_PREVIEW = 'noap' + OBLITERATE = 'obli' + PERFORM = 'perf' + PRE_PROVISIONED_DISABLE ='ppdi' + PRE_PROVISIONED_REENABLE ='ppre' + PRINT = 'prin' + PROCESS = 'proc' + PROCESS_PREVIEW = 'prop' + PURGE = 'purg' + RECREATE = 'recr' + REENABLE = 'reen' + REFRESH = 'refr' + RELABEL = 'rela' + REMOVE = 'remo' + REMOVE_PREVIEW = 'remp' + RENAME = 'rena' + REOPEN = 'reop' + REPLACE = 'repl' + REPLACE_DOMAIN = 'repd' + REPORT = 'repo' + RESET_YUBIKEY_PIV = 'rpiv' + RESPOND = 'resp' + RESTORE = 'rest' + RESUBMIT = 'res' + RETAIN = 'reta' + RETRIEVE_DATA = 'retd' + REVOKE = 'revo' + SAVE = 'save' + SEND = 'send' + SENDEMAIL = 'snem' + SENDREPLY = 'sner' + SET = 'set ' + SETUP = 'setu' + SHARE = 'shar' + SHOW = 'show' + SIGNOUT = 'siou' + SKIP = 'skip' + SPAM = 'spam' + SUBMIT = 'subm' + SUSPEND = 'susp' + SYNC = 'sync' + TRANSFER = 'tran' + TRANSFER_OWNERSHIP = 'trow' + TRASH = 'tras' + TURNOFF2SV = 'to2s' + UNDELETE = 'unde' + UNHIDE = 'unhi' + UNSUSPEND = 'unsu' + UNTRASH = 'untr' + UPDATE = 'upda' + UPDATE_MOVE = 'upmo' + UPDATE_OWNER = 'updo' + UPDATE_PREVIEW = 'updp' + UPLOAD = 'uplo' + UNZIP = 'unzi' + USE = 'use ' + VERIFY = 'vrfy' + VERIFYITEMEXISTS = 'vexi' + WAITFORMAILBOX = 'wamb' + WATCH = 'watc' + WIPE = 'wipe' + WIPE_PREVIEW = 'wipp' + # Usage: + # ACTION_NAMES[1] n Items - Delete 10 Users + # Item xxx ACTION_NAMES[0] - User xxx Deleted + # These values can be translated into other languages + _NAMES = { + ACCEPT: ['Accepted', 'Accept'], + ADD: ['Added', 'Add'], + ADD_PREVIEW: ['Added (Preview)', 'Add (Preview)'], + APPEND: ['Appended', 'Append'], + APPROVE: ['Approved', 'Approve'], + ARCHIVE: ['Archived', 'Archive'], + BACKUP: ['Backed up', 'Backup'], + BLOCK: ['Blocked', 'Block'], + CANCEL: ['Cancelled', 'Cancel'], + CANCEL_WIPE: ['Wipe Cancelled', 'Cancel Wipe'], + CHECK: ['Checked', 'Check'], + CLAIM: ['Claimed', 'Claim'], + CLAIM_OWNERSHIP: ['Ownership Claimed', 'Claim Ownership'], + CLEAR: ['Cleared', 'Clear'], + CLOSE: ['Closed', 'Close'], + COLLECT: ['Collected', 'Collect'], + COMMENT: ['Commented', 'Comment'], + COPY: ['Copied', 'Copy'], + COPY_MERGE: ['Copied(Merge)', 'Copy(Merge)'], + CREATE: ['Created', 'Create'], + CREATE_PREVIEW: ['Created (Preview)', 'Create (Preview)'], + CREATE_SHORTCUT: ['Created Shortcut', 'Create Shortcut'], + DEDUP: ['Duplicates Deleted', 'Delete Duplicates'], + DELETE: ['Deleted', 'Delete'], + DELETE_EMPTY: ['Deleted', 'Delete Empty'], + DELETE_PREVIEW: ['Deleted (Preview)', 'Delete (Preview)'], + DELETE_SHORTCUT: ['Deleted Shortcut', 'Delete Shortcut'], + DEPROVISION: ['Deprovisioned', 'Deprovision'], + DISABLE: ['Disabled', 'Disable'], + DOWNLOAD: ['Downloaded', 'Download'], + DRAFT: ['Drafted', 'Draft'], + EMPTY: ['Emptied', 'Empty'], + ENABLE: ['Enabled', 'Enable'], + END: ['Ended', 'End'], + EXISTS: ['Exists', 'Exists'], + EXPORT: ['Exported', 'Export'], + EXTRACT: ['Extracted', 'Extract'], + FORWARD: ['Forwarded', 'Forward'], + GET_COMMAND_RESULT: ['Got Command Result', 'Get Command Result'], + HIDE: ['Hidden', 'Hide'], + IMPORT: ['Imported', 'Import'], + INFO: ['Shown', 'Show Info'], + INITIALIZE: ['Initialized', 'Initialize'], + INSERT: ['Inserted', 'Insert'], + INVALIDATE: ['Invalidated', 'Invalidate'], + ISSUE_COMMAND: ['Command Issued', 'Issue Command'], + LIST: ['Listed', 'List'], + LOOKUP: ['Lookedup', 'Lookup'], + MERGE: ['Merged', 'Merge'], + MODIFY: ['Modified', 'Modify'], + MOVE: ['Moved', 'Move'], + MOVE_MERGE: ['Moved(Merge)', 'Move(Merge)'], + NOACTION: ['No Action', 'No Action'], + NOACTION_PREVIEW: ['No Action (Preview)', 'No Action (Preview)'], + OBLITERATE: ['Obliterated', 'Obliterate'], + PERFORM: ['Action Performed', 'Perform Action'], + PRE_PROVISIONED_DISABLE: ['PreProvisioned Disabled', 'PreProvisioned Disable'], + PRE_PROVISIONED_REENABLE: ['PreProvisioned Reenabled', 'PreProvisioned Reenable'], + PRINT: ['Printed', 'Print'], + PROCESS: ['Processed', 'Process'], + PROCESS_PREVIEW: ['Processed (Preview)', 'Process (Preview)'], + PURGE: ['Purged', 'Purge'], + RECREATE: ['Recreated', 'Recreate'], + REENABLE: ['Reenabled', 'Reenable'], + REFRESH: ['Refreshed', 'Refresh'], + RELABEL: ['Relabeled', 'Relabel'], + REMOVE: ['Removed', 'Remove'], + REMOVE_PREVIEW: ['Removed (Preview)', 'Remove (Preview)'], + RENAME: ['Renamed', 'Rename'], + REOPEN: ['Reopened', 'Reopen'], + REPLACE: ['Replaced', 'Replace'], + REPLACE_DOMAIN: ['Domain Replaced', 'Replace Domain'], + REPORT: ['Reported', 'Report'], + RESET_YUBIKEY_PIV: ['Yubikey PIV Reset', 'Reset Yubikey PIV'], + RESPOND: ['Responded', 'Respond'], + RESTORE: ['Restored', 'Restore'], + RESUBMIT: ['Resubmitted', 'Resubmit'], + RETAIN: ['Retained', 'Retain'], + RETRIEVE_DATA: ['Data Retrieved', 'Retrieve Data'], + REVOKE: ['Revoked', 'Revoke'], + SAVE: ['Saved', 'Save'], + SEND: ['Sent', 'Send'], + SENDEMAIL: ['Email Sent', 'Send Email'], + SENDREPLY: ['Reply Sent', 'Send Reply'], + SET: ['Set', 'Set'], + SETUP: ['Set Up', 'Set Up'], + SHARE: ['Shared', 'Share'], + SHOW: ['Shown', 'Show'], + SIGNOUT: ['Signed Out', 'Signout'], + SKIP: ['Skipped', 'Skip'], + SPAM: ['Marked as Spam', 'Mark as Spam'], + SUBMIT: ['Submitted', 'Submit'], + SUSPEND: ['Suspended', 'Suspend'], + SYNC: ['Synced', 'Sync'], + TRANSFER: ['Transferred', 'Transfer'], + TRANSFER_OWNERSHIP: ['Ownership Transferred', 'Transfer Ownership'], + TRASH: ['Trashed', 'Trash'], + TURNOFF2SV: ['2-Step Verification Turned Off', 'Turn Off 2-Step Verification'], + UNDELETE: ['Undeleted', 'Undelete'], + UNHIDE: ['Unhidden', 'Unhide'], + UNSUSPEND: ['Unsuspended', 'Unsuspend'], + UNTRASH: ['Untrashed', 'Untrash'], + UNZIP: ['Unzipped', 'Unzip'], + UPDATE: ['Updated', 'Update'], + UPDATE_MOVE: ['Updated/Moved', 'Update/Move'], + UPDATE_OWNER: ['Updated to Owner', 'Update to Owner'], + UPDATE_PREVIEW: ['Updated (Preview)', 'Update (Preview)'], + UPLOAD: ['Uploaded', 'Upload'], + USE: ['Used', 'Use'], + VERIFY: ['Verified', 'Verify'], + VERIFYITEMEXISTS: ['Verified Item Exists', 'Verify Item Exists'], + WAITFORMAILBOX: ['Mailbox is Setup', 'Check Mailbox is Setup'], + WATCH: ['Watched', 'Watch'], + WIPE: ['Wiped', 'Wipe'], + WIPE_PREVIEW: ['Wiped (Preview)', 'Wipe (Preview)'], + } + # + MODIFIER_CONTENTS_WITH = 'contents with' + MODIFIER_FOR = 'for' + MODIFIER_FROM = 'from' + MODIFIER_IN = 'in' + MODIFIER_INTO = 'into' + MODIFIER_PREVIOUSLY_IN = 'previously in' + MODIFIER_TO = 'to' + MODIFIER_WITH_COTEACHER_OWNER = 'with co-teacher as owner' + MODIFIER_WITH_NEW_TEACHER_OWNER = 'with new teacher as owner' + MODIFIER_WITH_CURRENT_OWNER = 'with current owner' + MODIFIER_WITH = 'with' + MODIFIER_WITH_CONTENT_FROM = 'with content from' + PREFIX_NOT = 'Not' + PREVIEW = 'Preview' + SUCCESS = 'Success' + SUFFIX_FAILED = 'Failed' + + # Shared state across all instances (class-level) + _action = None + + @property + def action(self): + return GamAction._action + @action.setter + def action(self, value): + GamAction._action = value + + def __init__(self): + pass # state is shared at class level + + def Set(self, action): + GamAction._action = action + + def Get(self): + return GamAction._action + + def ToPerform(self): + return self._NAMES[GamAction._action][1] + + def Performed(self): + return self._NAMES[GamAction._action][0] + + def Failed(self): + return f'{self._NAMES[GamAction._action][1]} {self.SUFFIX_FAILED}' + + def NotPerformed(self): + actionWords = self._NAMES[GamAction._action][0].split(' ') + if len(actionWords) != 2: + return f'{self.PREFIX_NOT} {self._NAMES[GamAction._action][0]}' + return f'{actionWords[0]} {self.PREFIX_NOT} {actionWords[1]}' + + def PerformedName(self, action): + return self._NAMES[action][0] + + def ToPerformName(self, action): + return self._NAMES[action][1] + + def csvFormat(self): + return GamAction._action == self.PRINT diff --git a/src/gam/gamlib/api.py b/src/gam/gamlib/api.py new file mode 100644 index 00000000..a60fe71f --- /dev/null +++ b/src/gam/gamlib/api.py @@ -0,0 +1,849 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Google API resources + +""" +# APIs +ACCESSCONTEXTMANAGER = 'accesscontextmanager' +ALERTCENTER = 'alertcenter' +ANALYTICS_ADMIN = 'analyticsadmin' +CALENDAR = 'calendar' +BUSINESSACCOUNTMANAGEMENT = 'mybusinessaccountmanagement' +CBCM = 'cbcm' +CHAT = 'chat' +CHAT_CUSTOM_EMOJIS = 'chatcustomemojis' +CHAT_EVENTS = 'chatevents' +CHAT_MEMBERSHIPS = 'chatmemberships' +CHAT_MEMBERSHIPS_ADMIN = 'chatmembershipsadmin' +CHAT_MESSAGES = 'chatmessages' +CHAT_SECTIONS = 'chatsections' +CHAT_SPACES = 'chatspaces' +CHAT_SPACES_ADMIN = 'chatspacesadmin' +CHAT_SPACES_DELETE = 'chatspacesdelete' +CHAT_SPACES_DELETE_ADMIN = 'chatspacesdeleteadmin' +CHROMEMANAGEMENT = 'chromemanagement' +CHROMEMANAGEMENT_APPDETAILS = 'chromemanagementappdetails' +CHROMEMANAGEMENT_CHROMEPROFILES = 'chromemanagementchromeprofiles' +CHROMEMANAGEMENT_TELEMETRY = 'chromemanagementtelemetry' +CHROMEPOLICY = 'chromepolicy' +CHROMEVERSIONHISTORY = 'versionhistory' +CLASSROOM = 'classroom' +CLOUDCHANNEL = 'cloudchannel' +CLOUDIDENTITY_DEVICES = 'cloudidentitydevices' +CLOUDIDENTITY_GROUPS = 'cloudidentitygroups' +CLOUDIDENTITY_INBOUND_SSO = 'cloudidentityinboundsso' +CLOUDIDENTITY_ORGUNITS = 'cloudidentityorgunits' +CLOUDIDENTITY_ORGUNITS_BETA = 'cloudidentityorgunitsbeta' +CLOUDIDENTITY_POLICY = 'cloudidentitypolicy' +CLOUDIDENTITY_USERINVITATIONS = 'cloudidentityuserinvitations' +CLOUDRESOURCEMANAGER = 'cloudresourcemanager' +CLOUDRESOURCEMANAGERV1 = 'cloudresourcemanagerv1' +CONTACTS = 'contacts' +CONTACTDELEGATION = 'contactdelegation' +DATATRANSFER = 'datatransfer' +DIRECTORY = 'directory' +DOCS = 'docs' +DRIVE2 = 'drive2' +DRIVE3 = 'drive3' +DRIVETD = 'drivetd' +DRIVEACTIVITY = 'driveactivity' +DRIVELABELS = 'drivelabels' +DRIVELABELS_ADMIN = 'drivelabelsadmin' +DRIVELABELS_USER = 'drivelabelsuser' +EMAIL_AUDIT = 'email-audit' +FORMS = 'forms' +GMAIL = 'gmail' +GROUPSMIGRATION = 'groupsmigration' +GROUPSSETTINGS = 'groupssettings' +IAM = 'iam' +IAM_CREDENTIALS = 'iamcredentials' +KEEP = 'keep' +LICENSING = 'licensing' +LOOKERSTUDIO = 'datastudio' +MEET_SPACES = 'meet' +MEET_READONLY = 'meetreadonly' +OAUTH2 = 'oauth2' +ORGPOLICY = 'orgpolicy' +PEOPLE = 'people' +PEOPLE_DIRECTORY = 'peopledirectory' +PEOPLE_OTHERCONTACTS = 'peopleothercontacts' +PRINTERS = 'printers' +PUBSUB = 'pubsub' +REPORTS = 'reports' +RESELLER = 'reseller' +SEARCHCONSOLE = 'searchconsole' +SERVICEACCOUNTLOOKUP = 'serviceaccountlookup' +SERVICEMANAGEMENT = 'servicemanagement' +SERVICEUSAGE = 'serviceusage' +SHEETS = 'sheets' +SHEETSTD = 'sheetstd' +SITEVERIFICATION = 'siteVerification' +STORAGE = 'storage' +STORAGEREAD = 'storageread' +STORAGEWRITE = 'storagewrite' +TAGMANAGER = 'tagmanager' +TAGMANAGER_USERS = 'tagmanagerusers' +TASKS = 'tasks' +VAULT = 'vault' +YOUTUBE = 'youtube' +# +CHROMEVERSIONHISTORY_URL = 'https://versionhistory.googleapis.com/v1/chrome/platforms' +DRIVE_SCOPE = 'https://www.googleapis.com/auth/drive' +DRIVE_FILE_SCOPE = 'https://www.googleapis.com/auth/drive.file' +DRIVE_READONLY_SCOPE = 'https://www.googleapis.com/auth/drive.readonly' +GMAIL_SEND_SCOPE = 'https://www.googleapis.com/auth/gmail.send' +GOOGLE_AUTH_PROVIDER_X509_CERT_URL = 'https://www.googleapis.com/oauth2/v1/certs' +GOOGLE_OAUTH2_ENDPOINT = 'https://accounts.google.com/o/oauth2/v2/auth' +GOOGLE_OAUTH2_TOKEN_ENDPOINT = 'https://oauth2.googleapis.com/token' +CLOUD_PLATFORM_SCOPE = 'https://www.googleapis.com/auth/cloud-platform' +IAM_SCOPE = 'https://www.googleapis.com/auth/iam' +PEOPLE_SCOPE = 'https://www.googleapis.com/auth/contacts' +STORAGE_READONLY_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only' +STORAGE_READWRITE_SCOPE = 'https://www.googleapis.com/auth/devstorage.read_write' +USERINFO_EMAIL_SCOPE = 'https://www.googleapis.com/auth/userinfo.email' # email +USERINFO_PROFILE_SCOPE = 'https://www.googleapis.com/auth/userinfo.profile' # profile +REQUIRED_SCOPES = [USERINFO_EMAIL_SCOPE, USERINFO_PROFILE_SCOPE] +REQUIRED_SCOPES_SET = set(REQUIRED_SCOPES) +NUM_CLIENT_SCOPES_ERROR_LIMIT = 48 +# +JWT_APIS = { + ACCESSCONTEXTMANAGER: [CLOUD_PLATFORM_SCOPE], + CHAT: ['https://www.googleapis.com/auth/chat.bot'], + CLOUDRESOURCEMANAGER: [CLOUD_PLATFORM_SCOPE], + IAM: [IAM_SCOPE], + ORGPOLICY: [CLOUD_PLATFORM_SCOPE], + } +# +SCOPELESS_APIS = { + CHROMEVERSIONHISTORY, + OAUTH2, + SERVICEACCOUNTLOOKUP, + } +# + +# Scopes not in the discovery doc that are still valid for the API. +EXTRA_SCOPES = { + CLOUDRESOURCEMANAGER: ['https://www.googleapis.com/auth/cloudplatformfolders', + 'https://www.googleapis.com/auth/cloudplatformfolders.readonly', + 'https://www.googleapis.com/auth/cloudplatformprojects', + 'https://www.googleapis.com/auth/cloudplatformprojects.readonly', + 'https://www.googleapis.com/auth/cloudplatformorganizations', + 'https://www.googleapis.com/auth/cloudplatformorganizations.readonly', + ], + VAULT: ['https://www.googleapis.com/auth/ediscovery', 'https://www.googleapis.com/auth/ediscovery.readonly'], +} +EXTRA_SCOPES[CLOUDRESOURCEMANAGERV1] = EXTRA_SCOPES[CLOUDRESOURCEMANAGER] + +APIS_NEEDING_ACCESS_TOKEN = { + CBCM: ['https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'] + } +# +DEPRECATED_SCOPES = { + 'https://www.googleapis.com/auth/cloud-identity', + 'https://www.googleapis.com/auth/cloud-platform', + 'https://www.googleapis.com/auth/iam', + } +# +REFRESH_PERM_ERRORS = [ + 'invalid_grant: reauth related error (rapt_required)', # no way to reauth today + 'invalid_grant: Token has been expired or revoked', + ] + +OAUTH2_TOKEN_ERRORS = [ + 'access_denied', + 'access_denied: Requested client not authorized', + 'access_denied: Account restricted', + 'internal_failure: Backend Error', + 'internal_failure: None', + 'invalid_account: Forbidden', + 'invalid_grant', + 'invalid_grant: Bad Request', + 'invalid_grant: Invalid email or User ID', + 'invalid_grant: Not a valid email', + 'invalid_grant: Invalid JWT: No valid verifier found for issuer', + 'invalid_grant: reauth related error (invalid_rapt)', + 'invalid_grant: The account has been deleted', + 'invalid_request: Invalid impersonation prn email address' + ] +OAUTH2_UNAUTHORIZED_ERRORS = [ + 'unauthorized_client: Client is unauthorized to retrieve access tokens using this method', + 'unauthorized_client: Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested', + 'unauthorized_client: Unauthorized client or scope in request', + ] + +PROJECT_APIS = [ + 'accesscontextmanager.googleapis.com', + 'admin.googleapis.com', + 'alertcenter.googleapis.com', + 'analyticsadmin.googleapis.com', +# 'audit.googleapis.com', + 'mybusinessaccountmanagement.googleapis.com', + 'calendar-json.googleapis.com', + 'chat.googleapis.com', + 'chromemanagement.googleapis.com', + 'chromepolicy.googleapis.com', + 'classroom.googleapis.com', + 'cloudchannel.googleapis.com', + 'cloudidentity.googleapis.com', + 'cloudresourcemanager.googleapis.com', + 'contacts.googleapis.com', + 'datastudio.googleapis.com', + 'docs.googleapis.com', + 'drive.googleapis.com', + 'driveactivity.googleapis.com', + 'drivelabels.googleapis.com', + 'forms.googleapis.com', + 'gmail.googleapis.com', + 'groupsmigration.googleapis.com', + 'groupssettings.googleapis.com', + 'iam.googleapis.com', + 'keep.googleapis.com', + 'licensing.googleapis.com', + 'meet.googleapis.com', + 'people.googleapis.com', + 'pubsub.googleapis.com', + 'reseller.googleapis.com', + 'searchconsole.googleapis.com', + 'sheets.googleapis.com', + 'siteverification.googleapis.com', + 'storage-api.googleapis.com', + 'tagmanager.googleapis.com', + 'tasks.googleapis.com', + 'vault.googleapis.com', + 'youtube.googleapis.com', + ] + +_INFO = { + ACCESSCONTEXTMANAGER: {'name': 'Access Context Manager API', 'version': 'v1', 'v2discovery': True}, + ALERTCENTER: {'name': 'AlertCenter API', 'version': 'v1beta1', 'v2discovery': True}, + ANALYTICS_ADMIN: {'name': 'Analytics Admin API', 'version': 'v1beta', 'v2discovery': True}, + BUSINESSACCOUNTMANAGEMENT: {'name': 'Business Account Management API', 'version': 'v1', 'v2discovery': True}, + CALENDAR: {'name': 'Calendar API', 'version': 'v3', 'v2discovery': True, 'mappedAPI': 'calendar-json'}, + CBCM: {'name': 'Chrome Browser Cloud Management API', 'version': 'v1.1beta1', 'v2discovery': True, 'localjson': True}, + CHAT: {'name': 'Chat API', 'version': 'v1', 'v2discovery': True}, + CHAT_CUSTOM_EMOJIS: {'name': 'Chat API - Custom Emojis', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_EVENTS: {'name': 'Chat API - Events', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_MEMBERSHIPS: {'name': 'Chat API - Memberships', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_MEMBERSHIPS_ADMIN: {'name': 'Chat API - Memberships Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_MESSAGES: {'name': 'Chat API - Messages', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_SECTIONS: {'name': 'Chat API - User Sections', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_SPACES: {'name': 'Chat API - Spaces', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_SPACES_ADMIN: {'name': 'Chat API - Spaces Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_SPACES_DELETE: {'name': 'Chat API - Spaces Delete', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CHAT_SPACES_DELETE_ADMIN: {'name': 'Chat API - Spaces Delete Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT}, + CLASSROOM: {'name': 'Classroom API', 'version': 'v1', 'v2discovery': True}, + CHROMEMANAGEMENT: {'name': 'Chrome Management API', 'version': 'v1', 'v2discovery': True}, + CHROMEMANAGEMENT_APPDETAILS: {'name': 'Chrome Management API - AppDetails', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT}, + CHROMEMANAGEMENT_TELEMETRY: {'name': 'Chrome Management API - Telemetry', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT}, + CHROMEPOLICY: {'name': 'Chrome Policy API', 'version': 'v1', 'v2discovery': True}, + CHROMEVERSIONHISTORY: {'name': 'Chrome Version History API', 'version': 'v1', 'v2discovery': True}, + CLOUDCHANNEL: {'name': 'Cloud Channel API', 'version': 'v1', 'v2discovery': True}, + CLOUDIDENTITY_DEVICES: {'name': 'Cloud Identity API - Devices', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_GROUPS: {'name': 'Cloud Identity API - Groups', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_INBOUND_SSO: {'name': 'Cloud Identity API - Inbound SSO Settings', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_ORGUNITS: {'name': 'Cloud Identity API - OrgUnits', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_ORGUNITS_BETA: {'name': 'Cloud Identity API - OrgUnits Beta', 'version': 'v1beta1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_POLICY: {'name': 'Cloud Identity API - Policy', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDIDENTITY_USERINVITATIONS: {'name': 'Cloud Identity API - User Invitations', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudidentity'}, + CLOUDRESOURCEMANAGER: {'name': 'Resource Manager API v3', 'version': 'v3', 'v2discovery': True}, + CLOUDRESOURCEMANAGERV1: {'name': 'Resource Manager API v1', 'version': 'v1', 'v2discovery': True, 'mappedAPI': 'cloudresourcemanager'}, + CONTACTS: {'name': 'Contacts API', 'version': 'v3', 'v2discovery': False}, + CONTACTDELEGATION: {'name': 'Contact Delegation API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, + DATATRANSFER: {'name': 'Data Transfer API', 'version': 'datatransfer_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, + DIRECTORY: {'name': 'Directory API', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, + DOCS: {'name': 'Docs API', 'version': 'v1', 'v2discovery': True}, + DRIVE2: {'name': 'Drive API v2', 'version': 'v2', 'v2discovery': False, 'mappedAPI': 'drive'}, + DRIVE3: {'name': 'Drive API v3', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'}, + DRIVETD: {'name': 'Drive API v3 - write todrive data', 'version': 'v3', 'v2discovery': False, 'mappedAPI': 'drive'}, + DRIVEACTIVITY: {'name': 'Drive Activity API v2', 'version': 'v2', 'v2discovery': True}, + DRIVELABELS_ADMIN: {'name': 'Drive Labels API - Admin', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS}, + DRIVELABELS_USER: {'name': 'Drive Labels API - User', 'version': 'v2', 'v2discovery': True, 'mappedAPI': DRIVELABELS}, + EMAIL_AUDIT: {'name': 'Email Audit API', 'version': 'v1', 'v2discovery': False}, + FORMS: {'name': 'Forms API', 'version': 'v1', 'v2discovery': True}, + GMAIL: {'name': 'Gmail API', 'version': 'v1', 'v2discovery': True}, + GROUPSMIGRATION: {'name': 'Groups Migration API', 'version': 'v1', 'v2discovery': True}, + GROUPSSETTINGS: {'name': 'Groups Settings API', 'version': 'v1', 'v2discovery': True}, + IAM: {'name': 'Identity and Access Management API', 'version': 'v1', 'v2discovery': True}, + IAM_CREDENTIALS: {'name': 'Identity and Access Management Credentials API', 'version': 'v1', 'v2discovery': True}, + KEEP: {'name': 'Keep API', 'version': 'v1', 'v2discovery': True}, + LICENSING: {'name': 'License Manager API', 'version': 'v1', 'v2discovery': True}, + LOOKERSTUDIO: {'name': 'Looker Studio API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, + MEET_SPACES: {'name': 'Meet API - Manage/Display Meeting Spaces', 'version': 'v2', 'v2discovery': True}, + MEET_READONLY: {'name': 'Meet API - Read Meeting Spaces metadata', 'version': 'v2', 'v2discovery': True, 'mappedAPI': MEET_SPACES}, + OAUTH2: {'name': 'OAuth2 API', 'version': 'v2', 'v2discovery': False}, + ORGPOLICY: {'name': 'Organization Policy API', 'version': 'v2', 'v2discovery': True}, + PEOPLE: {'name': 'People API', 'version': 'v1', 'v2discovery': True}, + PEOPLE_DIRECTORY: {'name': 'People Directory API', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE}, + PEOPLE_OTHERCONTACTS: {'name': 'People API - Other Contacts', 'version': 'v1', 'v2discovery': True, 'mappedAPI': PEOPLE}, + PRINTERS: {'name': 'Directory API - Printers', 'version': 'directory_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, + PUBSUB: {'name': 'Pub / Sub API', 'version': 'v1', 'v2discovery': True}, + REPORTS: {'name': 'Reports API', 'version': 'reports_v1', 'v2discovery': True, 'mappedAPI': 'admin'}, + RESELLER: {'name': 'Reseller API', 'version': 'v1', 'v2discovery': True}, + SEARCHCONSOLE: {'name': 'Search Console API', 'version': 'v1', 'v2discovery': True}, + SERVICEACCOUNTLOOKUP: {'name': 'Service Account Lookup pseudo-API', 'version': 'v1', 'v2discovery': True, 'localjson': True}, + SERVICEMANAGEMENT: {'name': 'Service Management API', 'version': 'v1', 'v2discovery': True}, + SERVICEUSAGE: {'name': 'Service Usage API', 'version': 'v1', 'v2discovery': True}, + SHEETS: {'name': 'Sheets API', 'version': 'v4', 'v2discovery': True}, + SHEETSTD: {'name': 'Sheets API - write todrive data', 'version': 'v4', 'v2discovery': True, 'mappedAPI': SHEETS}, + SITEVERIFICATION: {'name': 'Site Verification API', 'version': 'v1', 'v2discovery': True}, + STORAGE: {'name': 'Cloud Storage API', 'version': 'v1', 'v2discovery': True}, + STORAGEREAD: {'name': 'Cloud Storage API - Read', 'version': 'v1', 'v2discovery': True, 'mappedAPI': STORAGE}, + STORAGEWRITE: {'name': 'Cloud Storage API - Write', 'version': 'v1', 'v2discovery': True, 'mappedAPI': STORAGE}, + TAGMANAGER: {'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags', 'version': 'v2', 'v2discovery': True}, + TAGMANAGER_USERS: {'name': 'Tag Manager API - Users', 'version': 'v2', 'v2discovery': True, 'mappedAPI': TAGMANAGER}, + TASKS: {'name': 'Tasks API', 'version': 'v1', 'v2discovery': True}, + VAULT: {'name': 'Vault API', 'version': 'v1', 'v2discovery': True}, + YOUTUBE: {'name': 'Youtube API', 'version': 'v3', 'v2discovery': True}, + } + +READONLY = ['readonly',] + +_CLIENT_SCOPES = [ + {'name': 'Calendar API', + 'api': CALENDAR, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/calendar'}, + {'name': 'Chrome Browser Cloud Management API', + 'api': CBCM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromebrowsers'}, + {'name': 'Chrome Management API - readonly', + 'api': CHROMEMANAGEMENT, + 'scope': 'https://www.googleapis.com/auth/chrome.management.reports.readonly'}, + {'name': 'Chrome Management API - AppDetails readonly', + 'api': CHROMEMANAGEMENT_APPDETAILS, + 'scope': 'https://www.googleapis.com/auth/chrome.management.appdetails.readonly'}, + {'name': 'Chrome Management API - Profiles', + 'api': CHROMEMANAGEMENT_CHROMEPROFILES, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chrome.management.profiles'}, + {'name': 'Chrome Management API - Telemetry readonly', + 'api': CHROMEMANAGEMENT_TELEMETRY, + 'scope': 'https://www.googleapis.com/auth/chrome.management.telemetry.readonly'}, + {'name': 'Chrome Policy API', + 'api': CHROMEPOLICY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chrome.management.policy'}, + {'name': 'Chrome Printer Management API', + 'api': PRINTERS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.chrome.printers'}, + {'name': 'Chrome Version History API', + 'api': CHROMEVERSIONHISTORY, + 'scope': ''}, + {'name': 'Classroom API - Courses', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.courses'}, + {'name': 'Classroom API - Course Announcements', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.announcements'}, + {'name': 'Classroom API - Course Topics', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.topics'}, + {'name': 'Classroom API - Course Work/Materials', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.courseworkmaterials'}, + {'name': 'Classroom API - Course Work/Submissions', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'}, + {'name': 'Classroom API - Student Guardians', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.guardianlinks.students'}, + {'name': 'Classroom API - Profile Emails', + 'api': CLASSROOM, + 'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'}, + {'name': 'Classroom API - Profile Photos', + 'api': CLASSROOM, + 'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'}, + {'name': 'Classroom API - Rosters', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.rosters'}, + {'name': 'Cloud Channel API', + 'api': CLOUDCHANNEL, + 'subscopes': READONLY, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/apps.order'}, + {'name': 'Cloud Identity API - Groups', + 'api': CLOUDIDENTITY_GROUPS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.groups'}, + {'name': 'Cloud Identity API - Inbound SSO Settings', + 'api': CLOUDIDENTITY_INBOUND_SSO, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.inboundsso'}, + {'name': 'Cloud Identity API - OrgUnits Beta', + 'api': CLOUDIDENTITY_ORGUNITS_BETA, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.orgunits'}, + {'name': 'Cloud Identity API - Policy', + 'api': CLOUDIDENTITY_POLICY, + 'subscopes': READONLY, + 'roByDefault': True, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'}, + {'name': 'Cloud Identity API - User Invitations', + 'api': CLOUDIDENTITY_USERINVITATIONS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.userinvitations'}, + {'name': 'Cloud Storage API (Read Only, Vault/Takeout Download, Cloud Storage)', + 'api': STORAGEREAD, + 'offByDefault': True, + 'scope': STORAGE_READONLY_SCOPE}, + {'name': 'Cloud Storage API (Read/Write, Vault/Takeout Copy/Download, Cloud Storage)', + 'api': STORAGEWRITE, + 'offByDefault': True, + 'scope': STORAGE_READWRITE_SCOPE}, + {'name': 'Contacts API - Domain Shared Contacts', + 'api': CONTACTS, + 'scope': 'https://www.google.com/m8/feeds'}, + {'name': 'Contact Delegation API', + 'api': CONTACTDELEGATION, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.contact.delegation'}, + {'name': 'Data Transfer API', + 'api': DATATRANSFER, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.datatransfer'}, + {'name': 'Directory API - Chrome OS Devices', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.device.chromeos'}, + {'name': 'Directory API - Customers', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.customer'}, + {'name': 'Directory API - Domains', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.domain'}, + {'name': 'Directory API - Groups', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.group'}, + {'name': 'Directory API - Mobile Devices Directory', + 'api': DIRECTORY, + 'subscopes': ['readonly', 'actiononly'], + 'scope': 'https://www.googleapis.com/auth/admin.directory.device.mobile'}, + {'name': 'Directory API - Organizational Units', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.orgunit'}, + {'name': 'Directory API - Resource Calendars', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.resource.calendar'}, + {'name': 'Directory API - Roles', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.rolemanagement'}, + {'name': 'Directory API - User Schemas', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.userschema'}, + {'name': 'Directory API - User Security', + 'api': DIRECTORY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.user.security'}, + {'name': 'Directory API - Users', + 'api': DIRECTORY, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/admin.directory.user'}, + {'name': 'Email Audit API', + 'api': EMAIL_AUDIT, + 'offByDefault': True, + 'scope': 'https://apps-apis.google.com/a/feeds/compliance/audit/'}, + {'name': 'Groups Migration API', + 'api': GROUPSMIGRATION, + 'scope': 'https://www.googleapis.com/auth/apps.groups.migration'}, + {'name': 'Groups Settings API', + 'api': GROUPSSETTINGS, + 'scope': 'https://www.googleapis.com/auth/apps.groups.settings'}, + {'name': 'License Manager API', + 'api': LICENSING, + 'scope': 'https://www.googleapis.com/auth/apps.licensing'}, + {'name': 'People Directory API - readonly', + 'api': PEOPLE_DIRECTORY, + 'scope': 'https://www.googleapis.com/auth/directory.readonly'}, + {'name': 'People API', + 'api': PEOPLE, + 'subscopes': READONLY, + 'scope': PEOPLE_SCOPE}, + {'name': 'Pub / Sub API', + 'api': PUBSUB, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/pubsub'}, + {'name': 'Reports API - Audit Reports readonly', + 'api': REPORTS, + 'scope': 'https://www.googleapis.com/auth/admin.reports.audit.readonly'}, + {'name': 'Reports API - Usage Reports readonly', + 'api': REPORTS, + 'scope': 'https://www.googleapis.com/auth/admin.reports.usage.readonly'}, + {'name': 'Reseller API', + 'api': RESELLER, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/apps.order'}, + {'name': 'Resource Manager API - Organizations readonly', + 'api': CLOUDRESOURCEMANAGER, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/cloudplatformorganizations.readonly'}, + {'name': 'Resource Manager API - Projects readonly', + 'api': CLOUDRESOURCEMANAGER, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/cloudplatformprojects.readonly'}, + {'name': 'Service Account Lookup pseudo-API', + 'api': SERVICEACCOUNTLOOKUP, + 'scope': ''}, + {'name': 'Site Verification API', + 'api': SITEVERIFICATION, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/siteverification'}, + {'name': 'Vault API', + 'api': VAULT, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/ediscovery'}, + ] + +_COMMANDDATA_CLIENT_SCOPES = [ + {'name': 'Drive API - commanddata_clientaccess', + 'api': DRIVE3, + 'scope': DRIVE_READONLY_SCOPE}, + {'name': 'Sheets API - commanddata_clientaccess readonly', + 'api': SHEETS, + 'scope': 'https://www.googleapis.com/auth/spreadsheets.readonly'}, + ] + +_TODRIVE_CLIENT_SCOPES = [ + {'name': 'Drive API - todrive_clientaccess', + 'api': DRIVE3, + 'scope': DRIVE_SCOPE}, + {'name': 'Drive File API - todrive_clientaccess', + 'api': DRIVE3, + 'scope': DRIVE_FILE_SCOPE}, + {'name': 'Gmail API - todrive_clientaccess', + 'api': GMAIL, + 'scope': GMAIL_SEND_SCOPE}, + {'name': 'Sheets API - todrive_clientaccess', + 'api': SHEETS, + 'scope': 'https://www.googleapis.com/auth/spreadsheets'}, + ] + +OAUTH2SA_SCOPES = 'us_scopes' + +_SVCACCT_SCOPES = [ + {'name': 'AlertCenter API', + 'api': ALERTCENTER, + 'scope': 'https://www.googleapis.com/auth/apps.alerts'}, + {'name': 'Analytics Admin API - readonly', + 'api': ANALYTICS_ADMIN, + 'scope': 'https://www.googleapis.com/auth/analytics.readonly'}, + {'name': 'Business Account Management API', + 'api': BUSINESSACCOUNTMANAGEMENT, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/business.manage'}, + {'name': 'Calendar API', + 'api': CALENDAR, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/calendar'}, + {'name': 'Chat API - Custom Emojis', + 'api': CHAT_CUSTOM_EMOJIS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.customemojis'}, + {'name': 'Chat API - Memberships', + 'api': CHAT_MEMBERSHIPS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.memberships'}, + {'name': 'Chat API - Memberships Admin', + 'api': CHAT_MEMBERSHIPS_ADMIN, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.admin.memberships'}, + {'name': 'Chat API - Messages', + 'api': CHAT_MESSAGES, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.messages'}, + {'name': 'Chat API - User Sections', + 'api': CHAT_SECTIONS, + 'offByDefault': True, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.users.sections'}, + {'name': 'Chat API - Spaces', + 'api': CHAT_SPACES, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.spaces'}, + {'name': 'Chat API - Spaces Admin', + 'api': CHAT_SPACES_ADMIN, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/chat.admin.spaces'}, + {'name': 'Chat API - Spaces Delete', + 'api': CHAT_SPACES_DELETE, + 'scope': 'https://www.googleapis.com/auth/chat.delete'}, + {'name': 'Chat API - Spaces Delete Admin', + 'api': CHAT_SPACES_DELETE_ADMIN, + 'scope': 'https://www.googleapis.com/auth/chat.admin.delete'}, + {'name': 'Classroom API - Course Announcements', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.announcements'}, + {'name': 'Classroom API - Course Topics', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.topics'}, + {'name': 'Classroom API - Course Work/Materials', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.courseworkmaterials'}, + {'name': 'Classroom API - Course Work/Submissions', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.coursework.students'}, + {'name': 'Classroom API - Profile Emails', + 'api': CLASSROOM, + 'scope': 'https://www.googleapis.com/auth/classroom.profile.emails'}, + {'name': 'Classroom API - Profile Photos', + 'api': CLASSROOM, + 'scope': 'https://www.googleapis.com/auth/classroom.profile.photos'}, + {'name': 'Classroom API - Rosters', + 'api': CLASSROOM, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/classroom.rosters'}, + {'name': 'Cloud Identity Devices API', + 'api': CLOUDIDENTITY_DEVICES, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/cloud-identity.devices'}, +# {'name': 'Cloud Identity API - Policy', +# 'api': CLOUDIDENTITY_POLICY, +# 'subscopes': READONLY, +# 'roByDefault': True, +# 'scope': 'https://www.googleapis.com/auth/cloud-identity.policies'}, +# {'name': 'Cloud Identity User Invitations API', +# 'api': CLOUDIDENTITY_USERINVITATIONS, +# 'subscopes': READONLY, +# 'scope': 'https://www.googleapis.com/auth/cloud-identity'}, +# {'name': 'Contacts API - Users', +# 'api': CONTACTS, +# 'scope': 'https://www.google.com/m8/feeds'}, + {'name': 'Drive API', + 'api': DRIVE3, + 'subscopes': READONLY, + 'scope': DRIVE_SCOPE}, + {'name': 'Drive Activity API v2 - must pair with Drive API', + 'api': DRIVEACTIVITY, + 'scope': [DRIVE_READONLY_SCOPE, + 'https://www.googleapis.com/auth/drive.activity']}, + {'name': 'Drive Labels API - Admin', + 'api': DRIVELABELS_ADMIN, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/drive.admin.labels'}, + {'name': 'Drive Labels API - User', + 'api': DRIVELABELS_USER, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/drive.labels'}, + {'name': 'Docs API', + 'api': DOCS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/documents'}, + {'name': 'Forms API - must pair with Drive API', + 'api': FORMS, + 'scope': [DRIVE_READONLY_SCOPE, + 'https://www.googleapis.com/auth/forms.body', + 'https://www.googleapis.com/auth/forms.responses.readonly']}, + {'name': 'Gmail API - Full Access (Labels, Messages)', + 'api': GMAIL, + 'scope': 'https://mail.google.com/'}, + {'name': 'Gmail API - Full Access (Labels, Messages) except delete message', + 'api': GMAIL, + 'scope': 'https://www.googleapis.com/auth/gmail.modify'}, + {'name': 'Gmail API - Basic Settings (Filters, IMAP, Language, POP, Vacation) - read/write, Sharing Settings (Delegates, Forwarding, SendAs) - read', + 'api': GMAIL, + 'scope': 'https://www.googleapis.com/auth/gmail.settings.basic'}, + {'name': 'Gmail API - Sharing Settings (Delegates, Forwarding, SendAs) - write', + 'api': GMAIL, + 'scope': 'https://www.googleapis.com/auth/gmail.settings.sharing'}, +# {'name': 'Identity and Access Management API', +# 'api': IAM, +# 'offByDefault': True, +# 'scope': CLOUD_PLATFORM_SCOPE}, + {'name': 'Keep API', + 'api': KEEP, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/keep'}, + {'name': 'Looker Studio API', + 'api': LOOKERSTUDIO, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/datastudio'}, + {'name': 'Meet API - Manage/Display Meeting Spaces', + 'api': MEET_SPACES, + 'scope': ['https://www.googleapis.com/auth/meetings.space.created', + 'https://www.googleapis.com/auth/meetings.space.settings']}, + {'name': 'Meet API - Read Meeting Spaces metadata readonly', + 'api': MEET_READONLY, + 'scope': 'https://www.googleapis.com/auth/meetings.space.readonly'}, + {'name': 'OAuth2 API', + 'api': OAUTH2, + 'scope': USERINFO_PROFILE_SCOPE}, + {'name': 'People API', + 'api': PEOPLE, + 'subscopes': READONLY, + 'scope': PEOPLE_SCOPE}, + {'name': 'People Directory API - readonly', + 'api': PEOPLE_DIRECTORY, + 'scope': 'https://www.googleapis.com/auth/directory.readonly'}, + {'name': 'People API - Other Contacts - readonly', + 'api': PEOPLE_OTHERCONTACTS, + 'scope': 'https://www.googleapis.com/auth/contacts.other.readonly'}, + {'name': 'Search Console API - readonly', + 'api': SEARCHCONSOLE, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/webmasters.readonly'}, + {'name': 'Sheets API', + 'api': SHEETS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/spreadsheets'}, + {'name': 'Site Verification API', + 'api': SITEVERIFICATION, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/siteverification'}, + {'name': 'Tag Manager API - Accounts, Containers, Workspaces, Tags - readonly', + 'api': TAGMANAGER, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/tagmanager.readonly'}, + {'name': 'Tag Manager API - Users', + 'api': TAGMANAGER_USERS, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/tagmanager.manage.users'}, + {'name': 'Tasks API', + 'api': TASKS, + 'subscopes': READONLY, + 'scope': 'https://www.googleapis.com/auth/tasks'}, + {'name': 'Youtube API - readonly', + 'api': YOUTUBE, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/youtube.readonly'}, + ] + +_SVCACCT_SPECIAL_SCOPES = [ + {'name': 'Drive API - write todrive data - has access to all Drive', + 'api': DRIVETD, + 'offByDefault': True, + 'scope': DRIVE_SCOPE}, + {'name': 'Gmail API - Full Access - readonly', + 'api': GMAIL, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/gmail.readonly'}, + {'name': 'Gmail API - Send Messages - including todrive', + 'api': GMAIL, + 'offByDefault': True, + 'scope': GMAIL_SEND_SCOPE}, + {'name': 'Sheets API - write todrive data - has access to all Sheets', + 'api': SHEETSTD, + 'offByDefault': True, + 'scope': 'https://www.googleapis.com/auth/spreadsheets'}, + ] + +_USER_SVCACCT_ONLY_SCOPES = [ + {'name': 'Groups Migration API', + 'api': GROUPSMIGRATION, + 'scope': 'https://www.googleapis.com/auth/apps.groups.migration'}, + ] + +def getAPIName(api): + return _INFO[api]['name'] + +def getVersion(api): + version = _INFO[api]['version'] + v2discovery = _INFO[api]['v2discovery'] + api = _INFO[api].get('mappedAPI', api) + return (api, version, v2discovery) + +def getAPIsList(): + apisList = set() + for api, value in _INFO.items(): + apisList.add(value.get('mappedAPI', api)) + return apisList + +def getClientScopesSet(api): + return {scope['scope'] for scope in _CLIENT_SCOPES if scope['api'] == api} + +def getClientScopesList(commanddataClientAccess, todriveClientAccess): + caScopes = _CLIENT_SCOPES[:] + if commanddataClientAccess: + caScopes.extend(_COMMANDDATA_CLIENT_SCOPES) + if todriveClientAccess: + caScopes.extend(_TODRIVE_CLIENT_SCOPES) + return sorted(caScopes, key=lambda k: k['name']) + +def getClientScopesURLs(commanddataClientAccess, todriveClientAccess): + caScopes = _CLIENT_SCOPES[:] + if commanddataClientAccess: + caScopes.extend(_COMMANDDATA_CLIENT_SCOPES) + if todriveClientAccess: + caScopes.extend(_TODRIVE_CLIENT_SCOPES) + return sorted({scope['scope'] for scope in _CLIENT_SCOPES}) + +def getSvcAcctScopeAPI(uscope): + for scope in _SVCACCT_SCOPES: + if uscope == scope['scope'] or (uscope.endswith('.readonly') and 'readonly' in scope.get('subscopes', [])): + return scope['api'] + return None + +def getSvcAcctScopes(userServiceAccountAccessOnly, svcAcctSpecialScopes): + saScopes = [scope['scope'] for scope in _SVCACCT_SCOPES] + if userServiceAccountAccessOnly: + saScopes.extend([scope['scope'] for scope in _USER_SVCACCT_ONLY_SCOPES]) + if svcAcctSpecialScopes: + saScopes.extend([scope['scope'] for scope in _SVCACCT_SPECIAL_SCOPES]) + return saScopes + +def getSvcAcctScopesList(userServiceAccountAccessOnly, svcAcctSpecialScopes): + saScopes = _SVCACCT_SCOPES[:] + if userServiceAccountAccessOnly: + saScopes.extend(_USER_SVCACCT_ONLY_SCOPES) + if svcAcctSpecialScopes: + saScopes.extend(_SVCACCT_SPECIAL_SCOPES) + return sorted(saScopes, key=lambda k: k['name']) + +def hasLocalJSON(api): + return _INFO[api].get('localjson', False) + +def findAPIforScope(scopesList): + def checkScopeMatch(scope, cscope): + if cscope['scope'] == scope: + requiredAPIs.append(cscope['name']) + return True + if 'readonly' in cscope.get('subscopes', []) and cscope['scope']+'.readonly' == scope: + requiredAPIs.append(cscope['name']+' (supports readonly)') + return True + return False + + requiredAPIs = [] + for scope in scopesList: + for cscope in _CLIENT_SCOPES: + if checkScopeMatch(scope, cscope): + break + else: + for cscope in _SVCACCT_SCOPES: + if checkScopeMatch(scope, cscope): + break + if not requiredAPIs: + requiredAPIs = scopesList + return ' or '.join(requiredAPIs) diff --git a/src/gam/gamlib/clargs.py b/src/gam/gamlib/clargs.py new file mode 100644 index 00000000..ade9420f --- /dev/null +++ b/src/gam/gamlib/clargs.py @@ -0,0 +1,1681 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM command line argument processing + +""" + +class GamCLArgs(): + +# GAM entity types as specified on the command line + ENTITY_BROWSER = 'ids' + ENTITY_BROWSER_OU = 'browserou' + ENTITY_BROWSER_OUS = 'browserous' + ENTITY_BROWSER_QUERIES = 'browserqueies' + ENTITY_BROWSER_QUERY = 'browserquery' + ENTITY_CIGROUP = 'cigroup' + ENTITY_CIGROUPS = 'cigroups' + ENTITY_CIGROUP_USERS = 'cigroup_users' + ENTITY_COURSEPARTICIPANTS = 'courseparticipants' + ENTITY_CROS = 'cros' + ENTITY_CROS_QUERIES = 'crosqueries' + ENTITY_CROS_QUERY = 'crosquery' + ENTITY_CROS_OU = 'cros_ou' + ENTITY_CROS_OU_AND_CHILDREN = 'cros_ou_and_children' + ENTITY_CROS_OUS = 'cros_ous' + ENTITY_CROS_OUS_AND_CHILDREN = 'cros_ous_and_children' + ENTITY_CROS_OU_QUERY = 'cros_ou_query' + ENTITY_CROS_OU_AND_CHILDREN_QUERY = 'cros_ou_and_children_query' + ENTITY_CROS_OUS_QUERY = 'cros_ous_query' + ENTITY_CROS_OUS_AND_CHILDREN_QUERY = 'cros_ous_and_children_query' + ENTITY_CROS_OU_QUERIES = 'cros_ou_queries' + ENTITY_CROS_OU_AND_CHILDREN_QUERIES = 'cros_ou_and_children_queries' + ENTITY_CROS_OUS_QUERIES = 'cros_ous_queries' + ENTITY_CROS_OUS_AND_CHILDREN_QUERIES = 'cros_ous_and_children_queries' + ENTITY_CROS_SN = 'cros_sn' + ENTITY_DOMAINS = 'domains' + ENTITY_DOMAINS_NA = 'domains_na' + ENTITY_DOMAINS_ARCH = 'domains_arch' + ENTITY_DOMAINS_NS = 'domains_ns' + ENTITY_DOMAINS_SUSP = 'domains_susp' + ENTITY_DOMAINS_NS_SUSP = 'domains_ns_susp' + ENTITY_DOMAINS_NA_NS = 'domains_na_ns' + ENTITY_GROUP = 'group' + ENTITY_GROUP_INDE = 'group_inde' + ENTITY_GROUP_NA = 'group_na' + ENTITY_GROUP_ARCH = 'group_arch' + ENTITY_GROUP_NS = 'group_ns' + ENTITY_GROUP_SUSP = 'group_susp' + ENTITY_GROUP_NS_SUSP = 'group_ns_susp' + ENTITY_GROUP_NA_NS = 'group_na_ns' + ENTITY_GROUPS = 'groups' + ENTITY_GROUPS_INDE = 'groups_inde' + ENTITY_GROUPS_NA = 'groups_na' + ENTITY_GROUPS_ARCH = 'groups_arch' + ENTITY_GROUPS_NS = 'groups_ns' + ENTITY_GROUPS_SUSP = 'groups_susp' + ENTITY_GROUPS_NS_SUSP = 'groups_ns_susp' + ENTITY_GROUPS_NA_NS = 'groups_na_ns' + ENTITY_GROUP_USERS = 'group_users' + ENTITY_GROUP_USERS_NA = 'group_users_na' + ENTITY_GROUP_USERS_ARCH = 'group_users_arch' + ENTITY_GROUP_USERS_NS = 'group_users_ns' + ENTITY_GROUP_USERS_SUSP = 'group_users_susp' + ENTITY_GROUP_USERS_NS_SUSP = 'group_users_ns_susp' + ENTITY_GROUP_USERS_NA_NS = 'group_users_na_ns' + ENTITY_GROUP_USERS_SELECT = 'group_users_select' + ENTITY_LICENSES = 'licenses' + ENTITY_OAUTHUSER = 'oauthuser' + ENTITY_OU = 'ou' + ENTITY_OU_NA = 'ou_na' + ENTITY_OU_ARCH = 'ou_arch' + ENTITY_OU_NS = 'ou_ns' + ENTITY_OU_SUSP = 'ou_susp' + ENTITY_OU_NS_SUSP = 'ou_ns_susp' + ENTITY_OU_NA_NS = 'ou_na_ns' + ENTITY_OU_AND_CHILDREN = 'ou_and_children' + ENTITY_OU_AND_CHILDREN_NA = 'ou_and_children_na' + ENTITY_OU_AND_CHILDREN_ARCH = 'ou_and_children_arch' + ENTITY_OU_AND_CHILDREN_NS = 'ou_and_children_ns' + ENTITY_OU_AND_CHILDREN_SUSP = 'ou_and_children_susp' + ENTITY_OU_AND_CHILDREN_NS_SUSP = 'ou_and_children_ns_susp' + ENTITY_OU_AND_CHILDREN_NA_NS = 'ou_and_children_na_ns' + ENTITY_OUS = 'ous' + ENTITY_OUS_NA = 'ous_na' + ENTITY_OUS_ARCH = 'ous_arch' + ENTITY_OUS_NS = 'ous_ns' + ENTITY_OUS_SUSP = 'ous_susp' + ENTITY_OUS_NS_SUSP = 'ous_ns_susp' + ENTITY_OUS_NA_NS = 'ous_na_ns' + ENTITY_OUS_AND_CHILDREN = 'ous_and_children' + ENTITY_OUS_AND_CHILDREN_NA = 'ous_and_children_na' + ENTITY_OUS_AND_CHILDREN_ARCH = 'ous_and_children_arch' + ENTITY_OUS_AND_CHILDREN_NS = 'ous_and_children_ns' + ENTITY_OUS_AND_CHILDREN_SUSP = 'ous_and_children_susp' + ENTITY_OUS_AND_CHILDREN_NS_SUSP = 'ous_and_children_ns_susp' + ENTITY_OUS_AND_CHILDREN_NA_NS = 'ous_and_children_na_ns' + ENTITY_QUERIES = 'queries' + ENTITY_QUERY = 'query' + ENTITY_STUDENTS = 'students' + ENTITY_TEACHERS = 'teachers' + ENTITY_USER = 'user' + ENTITY_USERS = 'users' + ENTITY_USERS_NA = 'users_na' + ENTITY_USERS_ARCH = 'users_arch' + ENTITY_USERS_NS = 'users_ns' + ENTITY_USERS_SUSP = 'users_susp' + ENTITY_USERS_NS_SUSP = 'users_ns_susp' + ENTITY_USERS_NA_NS = 'users_na_ns' + ENTITY_USERS_ARCH_OR_SUSP = 'users_arch_or_susp' + ENTITY_USERS_AND_GUESTS = 'users_and_guests' + ENTITY_USERS_AND_GUESTS_NS = 'users_and_guests_ns' + ENTITY_USERS_AND_GUESTS_SUSP = 'users_and_guests_susp' + ENTITY_USERS_AND_GUESTS_NS_SUSP = 'users_and_guests_ns_susp' + ENTITY_GUESTS = 'guests' + ENTITY_GUESTS_NS = 'guests_ns' + ENTITY_GUESTS_SUSP = 'guests_susp' + ENTITY_GUESTS_NS_SUSP = 'guests_ns_susp' +# + BROWSER_ENTITIES = [ + ENTITY_BROWSER, + ENTITY_BROWSER_QUERIES, + ENTITY_BROWSER_QUERY, + ENTITY_BROWSER_OU, + ENTITY_BROWSER_OUS, + ] + CROS_ENTITIES = [ + ENTITY_CROS, + ENTITY_CROS_QUERIES, + ENTITY_CROS_QUERY, + ENTITY_CROS_OU, + ENTITY_CROS_OU_AND_CHILDREN, + ENTITY_CROS_OUS, + ENTITY_CROS_OUS_AND_CHILDREN, + ENTITY_CROS_OU_QUERY, + ENTITY_CROS_OU_AND_CHILDREN_QUERY, + ENTITY_CROS_OUS_QUERY, + ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + ENTITY_CROS_OU_QUERIES, + ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + ENTITY_CROS_OUS_QUERIES, + ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + ENTITY_CROS_SN, + ] + USER_ENTITIES = [ + ENTITY_CIGROUP, + ENTITY_CIGROUPS, + ENTITY_CIGROUP_USERS, + ENTITY_COURSEPARTICIPANTS, + ENTITY_DOMAINS, + ENTITY_DOMAINS_NA, + ENTITY_DOMAINS_ARCH, + ENTITY_DOMAINS_NS, + ENTITY_DOMAINS_SUSP, + ENTITY_DOMAINS_NS_SUSP, + ENTITY_DOMAINS_NA_NS, + ENTITY_GROUP, + ENTITY_GROUP_INDE, + ENTITY_GROUP_NA, + ENTITY_GROUP_ARCH, + ENTITY_GROUP_NS, + ENTITY_GROUP_SUSP, + ENTITY_GROUP_NS_SUSP, + ENTITY_GROUP_NA_NS, + ENTITY_GROUPS, + ENTITY_GROUPS_INDE, + ENTITY_GROUPS_NA, + ENTITY_GROUPS_ARCH, + ENTITY_GROUPS_NS, + ENTITY_GROUPS_SUSP, + ENTITY_GROUPS_NS_SUSP, + ENTITY_GROUPS_NA_NS, + ENTITY_GROUP_USERS, + ENTITY_GROUP_USERS_NA, + ENTITY_GROUP_USERS_ARCH, + ENTITY_GROUP_USERS_NS, + ENTITY_GROUP_USERS_SUSP, + ENTITY_GROUP_USERS_NS_SUSP, + ENTITY_GROUP_USERS_NA_NS, + ENTITY_GROUP_USERS_SELECT, + ENTITY_LICENSES, + ENTITY_OAUTHUSER, + ENTITY_OU, + ENTITY_OU_NA, + ENTITY_OU_ARCH, + ENTITY_OU_NS, + ENTITY_OU_SUSP, + ENTITY_OU_NS_SUSP, + ENTITY_OU_NA_NS, + ENTITY_OU_AND_CHILDREN, + ENTITY_OU_AND_CHILDREN_NA, + ENTITY_OU_AND_CHILDREN_ARCH, + ENTITY_OU_AND_CHILDREN_NS, + ENTITY_OU_AND_CHILDREN_SUSP, + ENTITY_OU_AND_CHILDREN_NS_SUSP, + ENTITY_OU_AND_CHILDREN_NA_NS, + ENTITY_OUS, + ENTITY_OUS_NA, + ENTITY_OUS_ARCH, + ENTITY_OUS_NS, + ENTITY_OUS_SUSP, + ENTITY_OUS_NS_SUSP, + ENTITY_OUS_NA_NS, + ENTITY_OUS_AND_CHILDREN, + ENTITY_OUS_AND_CHILDREN_NA, + ENTITY_OUS_AND_CHILDREN_ARCH, + ENTITY_OUS_AND_CHILDREN_NS, + ENTITY_OUS_AND_CHILDREN_SUSP, + ENTITY_OUS_AND_CHILDREN_NS_SUSP, + ENTITY_OUS_AND_CHILDREN_NA_NS, + ENTITY_QUERIES, + ENTITY_QUERY, + ENTITY_STUDENTS, + ENTITY_TEACHERS, + ENTITY_USER, + ENTITY_USERS, + ] +# Aliases for CL entity types + ENTITY_ALIAS_MAP = { + 'browsers': ENTITY_BROWSER, + 'browserorg': ENTITY_BROWSER_OU, + 'browserorgs': ENTITY_BROWSER_OUS, + 'crosorg': ENTITY_CROS_OU, + 'crosorg_and_child': ENTITY_CROS_OU_AND_CHILDREN, + 'crosorg_and_children': ENTITY_CROS_OU_AND_CHILDREN, + 'crosorgs': ENTITY_CROS_OUS, + 'crosorgs_and_child': ENTITY_CROS_OUS_AND_CHILDREN, + 'crosorgs_and_children': ENTITY_CROS_OUS_AND_CHILDREN, + 'crosou_and_child': ENTITY_CROS_OU_AND_CHILDREN, + 'crosou_and_childen': ENTITY_CROS_OU_AND_CHILDREN, + 'crosous_and_child': ENTITY_CROS_OUS_AND_CHILDREN, + 'crosous_and_children': ENTITY_CROS_OUS_AND_CHILDREN, + 'cros_org': ENTITY_CROS_OU, + 'cros_org_and_child': ENTITY_CROS_OU_AND_CHILDREN, + 'cros_org_and_children': ENTITY_CROS_OU_AND_CHILDREN, + 'cros_orgs': ENTITY_CROS_OUS, + 'cros_orgs_and_child': ENTITY_CROS_OUS_AND_CHILDREN, + 'cros_orgs_and_children': ENTITY_CROS_OUS_AND_CHILDREN, + 'cros_ou_and_child': ENTITY_CROS_OU_AND_CHILDREN, + 'cros_ou_and_childen': ENTITY_CROS_OU_AND_CHILDREN, + 'cros_ous_and_child': ENTITY_CROS_OUS_AND_CHILDREN, + 'cros_ous_and_children': ENTITY_CROS_OUS_AND_CHILDREN, + 'crosorg_query': ENTITY_CROS_OU_QUERY, + 'crosorg_and_child_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'crosorg_and_children_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'crosorgs_query': ENTITY_CROS_OUS_QUERY, + 'crosorgs_and_child_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'crosorgs_and_children_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'crosou_and_child_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'crosou_and_childen_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'crosous_and_child_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'crosous_and_children_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'cros_org_query': ENTITY_CROS_OU_QUERY, + 'cros_org_and_child_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'cros_org_and_children_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'cros_orgs_query': ENTITY_CROS_OUS_QUERY, + 'cros_orgs_and_child_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'cros_orgs_and_children_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'cros_ou_and_child_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'cros_ou_and_childen_query': ENTITY_CROS_OU_AND_CHILDREN_QUERY, + 'cros_ous_and_child_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'cros_ous_and_children_query': ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + 'crosorg_queries': ENTITY_CROS_OU_QUERIES, + 'crosorg_and_child_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'crosorg_and_children_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'crosorgs_queries': ENTITY_CROS_OUS_QUERIES, + 'crosorgs_and_child_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'crosorgs_and_children_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'crosou_and_child_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'crosou_and_childen_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'crosous_and_child_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'crosous_and_children_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'cros_org_queries': ENTITY_CROS_OU_QUERIES, + 'cros_org_and_child_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'cros_org_and_children_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'cros_orgs_queries': ENTITY_CROS_OUS_QUERIES, + 'cros_orgs_and_child_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'cros_orgs_and_children_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'cros_ou_and_child_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'cros_ou_and_childen_queries': ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + 'cros_ous_and_child_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'cros_ous_and_children_queries': ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + 'license': ENTITY_LICENSES, + 'licence': ENTITY_LICENSES, + 'licences': ENTITY_LICENSES, + 'org': ENTITY_OU, + 'org_na': ENTITY_OU_NA, + 'org_arch': ENTITY_OU_ARCH, + 'org_ns': ENTITY_OU_NS, + 'org_susp': ENTITY_OU_SUSP, + 'org_ns_susp': ENTITY_OU_NS_SUSP, + 'org_na_ns': ENTITY_OU_NA_NS, + 'org_and_child': ENTITY_OU_AND_CHILDREN, + 'org_and_child_na': ENTITY_OU_AND_CHILDREN_NA, + 'org_and_child_arch': ENTITY_OU_AND_CHILDREN_ARCH, + 'org_and_child_ns': ENTITY_OU_AND_CHILDREN_NS, + 'org_and_child_susp': ENTITY_OU_AND_CHILDREN_SUSP, + 'org_and_child_ns_susp': ENTITY_OU_AND_CHILDREN_NS_SUSP, + 'org_and_child_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS, + 'org_and_children': ENTITY_OU_AND_CHILDREN, + 'org_and_children_na': ENTITY_OU_AND_CHILDREN_NA, + 'org_and_children_arch': ENTITY_OU_AND_CHILDREN_ARCH, + 'org_and_children_ns': ENTITY_OU_AND_CHILDREN_NS, + 'org_and_children_susp': ENTITY_OU_AND_CHILDREN_SUSP, + 'org_and_children_ns_susp': ENTITY_OU_AND_CHILDREN_NS_SUSP, + 'org_and_children_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS, + 'orgs': ENTITY_OUS, + 'orgs_na': ENTITY_OUS_NA, + 'orgs_arch': ENTITY_OUS_ARCH, + 'orgs_ns': ENTITY_OUS_NS, + 'orgs_susp': ENTITY_OUS_SUSP, + 'orgs_ns_susp': ENTITY_OUS_NS_SUSP, + 'orgs_na_ns': ENTITY_OUS_NA_NS, + 'orgs_and_child': ENTITY_OUS_AND_CHILDREN, + 'orgs_and_child_na': ENTITY_OUS_AND_CHILDREN_NA, + 'orgs_and_child_arch': ENTITY_OUS_AND_CHILDREN_ARCH, + 'orgs_and_child_ns': ENTITY_OUS_AND_CHILDREN_NS, + 'orgs_and_child_susp': ENTITY_OUS_AND_CHILDREN_SUSP, + 'orgs_and_child_ns_susp': ENTITY_OUS_AND_CHILDREN_NS_SUSP, + 'orgs_and_child_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS, + 'orgs_and_children': ENTITY_OUS_AND_CHILDREN, + 'orgs_and_children_na': ENTITY_OUS_AND_CHILDREN_NA, + 'orgs_and_children_arch': ENTITY_OUS_AND_CHILDREN_ARCH, + 'orgs_and_children_ns': ENTITY_OUS_AND_CHILDREN_NS, + 'orgs_and_children_susp': ENTITY_OUS_AND_CHILDREN_SUSP, + 'orgs_and_children_ns_susp': ENTITY_OUS_AND_CHILDREN_NS_SUSP, + 'orgs_and_children_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS, + 'ou_and_child': ENTITY_OU_AND_CHILDREN, + 'ou_and_child_na': ENTITY_OU_AND_CHILDREN_NA, + 'ou_and_child_arch': ENTITY_OU_AND_CHILDREN_ARCH, + 'ou_and_child_ns': ENTITY_OU_AND_CHILDREN_NS, + 'ou_and_child_susp': ENTITY_OU_AND_CHILDREN_SUSP, + 'ou_and_child_ns_susp': ENTITY_OU_AND_CHILDREN_NS_SUSP, + 'ou_and_child_na_ns': ENTITY_OU_AND_CHILDREN_NA_NS, + 'ous_and_child': ENTITY_OUS_AND_CHILDREN, + 'ous_and_child_na': ENTITY_OUS_AND_CHILDREN_NA, + 'ous_and_child_arch': ENTITY_OUS_AND_CHILDREN_ARCH, + 'ous_and_child_ns': ENTITY_OUS_AND_CHILDREN_NS, + 'ous_and_child_susp': ENTITY_OUS_AND_CHILDREN_SUSP, + 'ous_and_child_ns_susp': ENTITY_OUS_AND_CHILDREN_NS_SUSP, + 'ous_and_child_na_ns': ENTITY_OUS_AND_CHILDREN_NA_NS, + } +# CL entity source selectors + ENTITY_SELECTOR_ALL = 'all' + ENTITY_SELECTOR_CSV = 'csv' + ENTITY_SELECTOR_CSVDATAFILE = 'csvdatafile' + ENTITY_SELECTOR_CSVFILE = 'csvfile' + ENTITY_SELECTOR_FILE = 'file' + ENTITY_SELECTOR_DATAFILE = 'datafile' + ENTITY_SELECTOR_CROSCSV = 'croscsv' + ENTITY_SELECTOR_CROSCSV_SN = 'croscsv_sn' + ENTITY_SELECTOR_CROSCSVFILE = 'croscsvfile' + ENTITY_SELECTOR_CROSCSVFILE_SN = 'croscsvfile_sn' + ENTITY_SELECTOR_CROSFILE = 'crosfile' + ENTITY_SELECTOR_CROSFILE_SN = 'crosfile_sn' + ENTITY_SELECTOR_CSVKMD = 'csvkmd' + ENTITY_SELECTOR_CSVSUBKEY = 'csvsubkey' + ENTITY_SELECTOR_CSVDATA = 'csvdata' + ENTITY_SELECTOR_CROSCSVDATA = 'croscsvdata' +# + SERVICE_ACCOUNT_ONLY_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CSVDATAFILE, + ENTITY_SELECTOR_CSVKMD, + ENTITY_SELECTOR_CSVSUBKEY, + ENTITY_SELECTOR_DATAFILE, + ] + ENTITY_LIST_SELECTORS = [ + ENTITY_SELECTOR_CSVKMD, + ENTITY_SELECTOR_CSVSUBKEY, + ENTITY_SELECTOR_CSV, + ENTITY_SELECTOR_CSVFILE, + ENTITY_SELECTOR_FILE, + ENTITY_SELECTOR_CSVDATA, + ] + BASE_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_ALL, + ENTITY_SELECTOR_CSVDATAFILE, + ENTITY_SELECTOR_CSVKMD, + ENTITY_SELECTOR_CSVSUBKEY, + ENTITY_SELECTOR_DATAFILE, + ] + BROWSER_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CSV, + ENTITY_SELECTOR_CSVFILE, + ENTITY_SELECTOR_FILE, + ] + CROS_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CROSCSV, + ENTITY_SELECTOR_CROSCSV_SN, + ENTITY_SELECTOR_CROSCSVFILE, + ENTITY_SELECTOR_CROSCSVFILE_SN, + ENTITY_SELECTOR_CROSFILE, + ENTITY_SELECTOR_CROSFILE_SN, + ] + USER_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CSV, + ENTITY_SELECTOR_CSVFILE, + ENTITY_SELECTOR_FILE, + ] + CROS_CSVDATA_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CROSCSVDATA, + ] + USER_CSVDATA_ENTITY_SELECTORS = [ + ENTITY_SELECTOR_CSVDATA, + ] +# Allowed values for CL source selector all + CROS_ENTITY_SELECTOR_ALL_SUBTYPES = [ + ENTITY_CROS, + ] + USER_ENTITY_SELECTOR_ALL_SUBTYPES = [ + ENTITY_USERS, + ENTITY_USERS_NA, + ENTITY_USERS_ARCH, + ENTITY_USERS_NS, + ENTITY_USERS_SUSP, + ENTITY_USERS_NS_SUSP, + ENTITY_USERS_ARCH_OR_SUSP, + ENTITY_USERS_NA_NS, + ENTITY_USERS_AND_GUESTS, + ENTITY_USERS_AND_GUESTS_NS, + ENTITY_USERS_AND_GUESTS_SUSP, + ENTITY_USERS_AND_GUESTS_NS_SUSP, + ENTITY_GUESTS, + ENTITY_GUESTS_NS, + ENTITY_GUESTS_SUSP, + ENTITY_GUESTS_NS_SUSP, + ] +# + ENTITY_ALL_CROS = ENTITY_SELECTOR_ALL+' '+ENTITY_CROS + ENTITY_ALL_USERS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS + ENTITY_ALL_USERS_NA = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NA + ENTITY_ALL_USERS_ARCH = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_ARCH + ENTITY_ALL_USERS_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NS + ENTITY_ALL_USERS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_SUSP + ENTITY_ALL_USERS_NS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NS_SUSP + ENTITY_ALL_USERS_NA_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_NA_NS + ENTITY_ALL_USERS_ARCH_OR_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_ARCH_OR_SUSP + ENTITY_ALL_USERS_AND_GUESTS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_AND_GUESTS + ENTITY_ALL_USERS_AND_GUESTS_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_AND_GUESTS_NS + ENTITY_ALL_USERS_AND_GUESTS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_AND_GUESTS_SUSP + ENTITY_ALL_USERS_AND_GUESTS_NS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_USERS_AND_GUESTS_NS_SUSP + ENTITY_ALL_GUESTS = ENTITY_SELECTOR_ALL+' '+ENTITY_GUESTS + ENTITY_ALL_GUESTS_NS = ENTITY_SELECTOR_ALL+' '+ENTITY_GUESTS_NS + ENTITY_ALL_GUESTS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_GUESTS_SUSP + ENTITY_ALL_GUESTS_NS_SUSP = ENTITY_SELECTOR_ALL+' '+ENTITY_GUESTS_NS_SUSP +# + ALL_USER_ENTITY_TYPES = { + ENTITY_ALL_USERS, + ENTITY_ALL_USERS_NA, + ENTITY_ALL_USERS_ARCH, + ENTITY_ALL_USERS_NS, + ENTITY_ALL_USERS_SUSP, + ENTITY_ALL_USERS_NS_SUSP, + ENTITY_ALL_USERS_NA_NS, + ENTITY_ALL_USERS_AND_GUESTS, + ENTITY_ALL_USERS_AND_GUESTS_NS, + ENTITY_ALL_USERS_AND_GUESTS_SUSP, + ENTITY_ALL_USERS_AND_GUESTS_NS_SUSP, + ENTITY_ALL_GUESTS, + ENTITY_ALL_GUESTS_NS, + ENTITY_ALL_GUESTS_SUSP, + ENTITY_ALL_GUESTS_NS_SUSP, + } + DOMAIN_ENTITY_TYPES = { + ENTITY_DOMAINS, + ENTITY_DOMAINS_NA, + ENTITY_DOMAINS_ARCH, + ENTITY_DOMAINS_NS, + ENTITY_DOMAINS_SUSP, + ENTITY_DOMAINS_NS_SUSP, + ENTITY_DOMAINS_NA_NS, + } + GROUP_ENTITY_TYPES = { + ENTITY_GROUP, + ENTITY_GROUP_NA, + ENTITY_GROUP_ARCH, + ENTITY_GROUP_NS, + ENTITY_GROUP_SUSP, + ENTITY_GROUP_NS_SUSP, + ENTITY_GROUP_NA_NS, + ENTITY_GROUP_INDE, + } + GROUPS_ENTITY_TYPES = { + ENTITY_GROUPS, + ENTITY_GROUPS_NA, + ENTITY_GROUPS_ARCH, + ENTITY_GROUPS_NS, + ENTITY_GROUPS_SUSP, + ENTITY_GROUPS_NS_SUSP, + ENTITY_GROUPS_NA_NS, + ENTITY_GROUPS_INDE, + } + GROUP_USERS_ENTITY_TYPES = { + ENTITY_GROUP_USERS, + ENTITY_GROUP_USERS_NA, + ENTITY_GROUP_USERS_ARCH, + ENTITY_GROUP_USERS_NS, + ENTITY_GROUP_USERS_SUSP, + ENTITY_GROUP_USERS_NS_SUSP, + ENTITY_GROUP_USERS_NA_NS, + ENTITY_GROUP_USERS_SELECT, + } + OU_ENTITY_TYPES = { + ENTITY_OU, + ENTITY_OU_AND_CHILDREN, + ENTITY_OU_NA, + ENTITY_OU_AND_CHILDREN_NA, + ENTITY_OU_ARCH, + ENTITY_OU_AND_CHILDREN_ARCH, + ENTITY_OU_NS, + ENTITY_OU_AND_CHILDREN_NS, + ENTITY_OU_SUSP, + ENTITY_OU_AND_CHILDREN_SUSP, + ENTITY_OU_NS_SUSP, + ENTITY_OU_AND_CHILDREN_NS_SUSP, + ENTITY_OU_NA_NS, + ENTITY_OU_AND_CHILDREN_NA_NS, + } + OUS_ENTITY_TYPES = { + ENTITY_OUS, + ENTITY_OUS_AND_CHILDREN, + ENTITY_OUS_NA, + ENTITY_OUS_AND_CHILDREN_NA, + ENTITY_OUS_ARCH, + ENTITY_OUS_AND_CHILDREN_ARCH, + ENTITY_OUS_NS, + ENTITY_OUS_AND_CHILDREN_NS, + ENTITY_OUS_SUSP, + ENTITY_OUS_AND_CHILDREN_SUSP, + ENTITY_OUS_NS_SUSP, + ENTITY_OUS_AND_CHILDREN_NS_SUSP, + ENTITY_OUS_NA_NS, + ENTITY_OUS_AND_CHILDREN_NA_NS, + } + OU_DIRECT_ENTITY_TYPES = { + ENTITY_OU, + ENTITY_OUS, + ENTITY_OU_NA, + ENTITY_OUS_NA, + ENTITY_OU_ARCH, + ENTITY_OUS_ARCH, + ENTITY_OU_NS, + ENTITY_OUS_NS, + ENTITY_OU_SUSP, + ENTITY_OUS_SUSP, + ENTITY_OU_NS_SUSP, + ENTITY_OUS_NS_SUSP, + ENTITY_OU_NA_NS, + ENTITY_OUS_NA_NS, + } + CROS_OU_ENTITY_TYPES = { + ENTITY_CROS_OU, + ENTITY_CROS_OU_AND_CHILDREN, + ENTITY_CROS_OU_QUERY, + ENTITY_CROS_OU_AND_CHILDREN_QUERY, + ENTITY_CROS_OU_QUERIES, + ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + } + CROS_OUS_ENTITY_TYPES = { + ENTITY_CROS_OUS, + ENTITY_CROS_OUS_AND_CHILDREN, + ENTITY_CROS_OUS_QUERY, + ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + ENTITY_CROS_OUS_QUERIES, + ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + } + CROS_OU_CHILDREN_ENTITY_TYPES = { + ENTITY_CROS_OU_AND_CHILDREN, + ENTITY_CROS_OU_AND_CHILDREN_QUERY, + ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + ENTITY_CROS_OUS_AND_CHILDREN, + ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + } + CROS_OU_QUERY_ENTITY_TYPES = { + ENTITY_CROS_OU_QUERY, + ENTITY_CROS_OU_AND_CHILDREN_QUERY, + ENTITY_CROS_OUS_QUERY, + ENTITY_CROS_OUS_AND_CHILDREN_QUERY, + } + CROS_OU_QUERIES_ENTITY_TYPES = { + ENTITY_CROS_OU_QUERIES, + ENTITY_CROS_OU_AND_CHILDREN_QUERIES, + ENTITY_CROS_OUS_QUERIES, + ENTITY_CROS_OUS_AND_CHILDREN_QUERIES, + } +# + ALL_USERS_QUERY_MAP = { + ENTITY_ALL_USERS: 'isSuspended=False isGuest=False', + ENTITY_ALL_USERS_NA: 'isArchived=False isGuest=False', + ENTITY_ALL_USERS_ARCH: 'isArchived=True isGuest=False', + ENTITY_ALL_USERS_NS: 'isSuspended=False isGuest=False', + ENTITY_ALL_USERS_SUSP: 'isSuspended=True isGuest=False', + ENTITY_ALL_USERS_NA_NS: 'isArchived=False isSuspended=False isGuest=False', + ENTITY_ALL_USERS_NS_SUSP: 'isGuest=False', + ENTITY_ALL_USERS_AND_GUESTS: 'isSuspended=False', + ENTITY_ALL_USERS_AND_GUESTS_NS: 'isSuspended=False', + ENTITY_ALL_USERS_AND_GUESTS_SUSP: 'isSuspended=True', + ENTITY_ALL_USERS_AND_GUESTS_NS_SUSP: None, + ENTITY_ALL_GUESTS: 'isSuspended=False isGuest=True', + ENTITY_ALL_GUESTS_NS: 'isSuspended=False isGuest=True', + ENTITY_ALL_GUESTS_SUSP: 'isSuspended=True isGuest=True', + ENTITY_ALL_GUESTS_NS_SUSP: 'isGuest=True', + } + DOMAINS_QUERY_MAP = { + ENTITY_DOMAINS: None, + ENTITY_DOMAINS_NA: 'isArchived=False', + ENTITY_DOMAINS_ARCH: 'isArchived=True', + ENTITY_DOMAINS_NS: 'isSuspended=False', + ENTITY_DOMAINS_SUSP: 'isSuspended=True', + ENTITY_DOMAINS_NS_SUSP: None, + ENTITY_DOMAINS_NA_NS: 'isArchived=False isSuspended=False', + } + GROUPS_QUERY_MAP = { #(isArchived, isSuspended) + ENTITY_GROUP_NA: (False, None), + ENTITY_GROUPS_NA: (False, None), + ENTITY_GROUP_ARCH: (True, None), + ENTITY_GROUPS_ARCH: (True, None), + ENTITY_GROUP_NS: (None, False), + ENTITY_GROUPS_NS: (None, False), + ENTITY_GROUP_SUSP: (None, True), + ENTITY_GROUPS_SUSP: (None, True), + ENTITY_GROUP_NS_SUSP: (None, None), + ENTITY_GROUPS_NS_SUSP: (None, None), + ENTITY_GROUP_NA_NS: (False, False), + ENTITY_GROUPS_NA_NS: (False, False), + } + GROUP_USERS_QUERY_MAP = { #(isArchived, isSuspended) + ENTITY_GROUP_USERS_NA: (False, None), + ENTITY_GROUP_USERS_ARCH: (True, None), + ENTITY_GROUP_USERS_NS: (None, False), + ENTITY_GROUP_USERS_SUSP: (None, True), + ENTITY_GROUP_USERS_NS_SUSP: (None, None), + ENTITY_GROUP_USERS_NA_NS: (False, False), + } + OU_QUERY_MAP = { #(isArchived, isSuspended) + ENTITY_OU_NA: (False, None), + ENTITY_OUS_NA: (False, None), + ENTITY_OU_AND_CHILDREN_NA: (False, None), + ENTITY_OUS_AND_CHILDREN_NA: (False, None), + ENTITY_OU_ARCH: (True, None), + ENTITY_OUS_ARCH: (True, None), + ENTITY_OU_AND_CHILDREN_ARCH: (True, None), + ENTITY_OUS_AND_CHILDREN_ARCH: (True, None), + ENTITY_OU_NS: (None, False), + ENTITY_OUS_NS: (None, False), + ENTITY_OU_AND_CHILDREN_NS: (None, False), + ENTITY_OUS_AND_CHILDREN_NS: (None, False), + ENTITY_OU_SUSP: (None, True), + ENTITY_OUS_SUSP: (None, True), + ENTITY_OU_AND_CHILDREN_SUSP: (None, True), + ENTITY_OUS_AND_CHILDREN_SUSP: (None, True), + ENTITY_OU_NS_SUSP: (None, None), + ENTITY_OUS_NS_SUSP: (None, None), + ENTITY_OU_AND_CHILDREN_NS_SUSP: (None, None), + ENTITY_OUS_AND_CHILDREN_NS_SUSP: (None, None), + ENTITY_OU_NA_NS: (False, False), + ENTITY_OUS_NA_NS: (False, False), + ENTITY_OU_AND_CHILDREN_NA_NS: (False, False), + ENTITY_OUS_AND_CHILDREN_NA_NS: (False, False), + } +# + ENTITY_SELECTOR_ALL_SUBTYPES_MAP = { + ENTITY_CROS: ENTITY_ALL_CROS, + ENTITY_USERS: ENTITY_ALL_USERS, + ENTITY_USERS_NA: ENTITY_ALL_USERS_NA, + ENTITY_USERS_ARCH: ENTITY_ALL_USERS_ARCH, + ENTITY_USERS_NS: ENTITY_ALL_USERS_NS, + ENTITY_USERS_SUSP: ENTITY_ALL_USERS_SUSP, + ENTITY_USERS_NA_NS: ENTITY_ALL_USERS_NA_NS, + ENTITY_USERS_ARCH_OR_SUSP: ENTITY_ALL_USERS_ARCH_OR_SUSP, + ENTITY_USERS_NS_SUSP: ENTITY_ALL_USERS_NS_SUSP, + ENTITY_USERS_AND_GUESTS: ENTITY_ALL_USERS_AND_GUESTS, + ENTITY_USERS_AND_GUESTS_NS: ENTITY_ALL_USERS_AND_GUESTS_NS, + ENTITY_USERS_AND_GUESTS_SUSP: ENTITY_ALL_USERS_AND_GUESTS_SUSP, + ENTITY_USERS_AND_GUESTS_NS_SUSP: ENTITY_ALL_USERS_AND_GUESTS_NS_SUSP, + ENTITY_GUESTS: ENTITY_ALL_GUESTS, + ENTITY_GUESTS_NS: ENTITY_ALL_GUESTS_NS, + ENTITY_GUESTS_SUSP: ENTITY_ALL_GUESTS_SUSP, + ENTITY_GUESTS_NS_SUSP: ENTITY_ALL_GUESTS_NS_SUSP, + } +# Allowed values for CL source selector datafile, csvkmd + CROS_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES = [ + ENTITY_CROS, + ENTITY_CROS_OUS, + ENTITY_CROS_OUS_AND_CHILDREN, + ENTITY_CROS_SN, + ] + USER_ENTITY_SELECTOR_DATAFILE_CSVKMD_SUBTYPES = [ + ENTITY_USERS, + ENTITY_CIGROUPS, + ENTITY_CIGROUP_USERS, + ENTITY_DOMAINS, + ENTITY_DOMAINS_NA, + ENTITY_DOMAINS_ARCH, + ENTITY_DOMAINS_NS, + ENTITY_DOMAINS_SUSP, + ENTITY_DOMAINS_NS_SUSP, + ENTITY_DOMAINS_NA_NS, + ENTITY_GROUPS, + ENTITY_GROUPS_INDE, + ENTITY_GROUPS_NA, + ENTITY_GROUPS_ARCH, + ENTITY_GROUPS_NS, + ENTITY_GROUPS_SUSP, + ENTITY_GROUPS_NS_SUSP, + ENTITY_GROUPS_NA_NS, + ENTITY_GROUP_USERS, + ENTITY_GROUP_USERS_NA, + ENTITY_GROUP_USERS_ARCH, + ENTITY_GROUP_USERS_NS, + ENTITY_GROUP_USERS_SUSP, + ENTITY_GROUP_USERS_NS_SUSP, + ENTITY_GROUP_USERS_NA_NS, + ENTITY_GROUP_USERS_SELECT, + ENTITY_OUS, + ENTITY_OUS_NA, + ENTITY_OUS_ARCH, + ENTITY_OUS_NS, + ENTITY_OUS_SUSP, + ENTITY_OUS_NS_SUSP, + ENTITY_OUS_NA_NS, + ENTITY_OUS_AND_CHILDREN, + ENTITY_OUS_AND_CHILDREN_NA, + ENTITY_OUS_AND_CHILDREN_ARCH, + ENTITY_OUS_AND_CHILDREN_NS, + ENTITY_OUS_AND_CHILDREN_SUSP, + ENTITY_OUS_AND_CHILDREN_NS_SUSP, + ENTITY_OUS_AND_CHILDREN_NA_NS, + ENTITY_COURSEPARTICIPANTS, + ENTITY_STUDENTS, + ENTITY_TEACHERS, + ] +# Batch file commands + EXECUTE_CMD = 'execute' + GAM_CMD = 'gam' + COMMIT_BATCH_CMD = 'commit-batch' + PRINT_CMD = 'print' + DATETIME_CMD = 'datetime' + SET_CMD = 'set' + CLEAR_CMD = 'clear' + SLEEP_CMD = 'sleep' +# Command line batch/csv/loop/tbatch keywords + BATCH_CMD = 'batch' + CSV_CMD = 'csv' + CSVTEST_CMD = 'csvtest' + LOOP_CMD = 'loop' + TBATCH_CMD = 'tbatch' +# Command line select/showsections/selectfilter/selectoutputfilter/selectinputfilter/config/redirect arguments + SELECT_CMD = 'select' + SHOWSECTIONS_CMD = 'showsections' + SELECTFILTER_CMD = 'selectfilter' + SELECTOUTPUTFILTER_CMD = 'selectoutputfilter' + SELECTINPUTFILTER_CMD = 'selectinputfilter' + CONFIG_CMD = 'config' + MULTIPROCESSEXIT_CMD = 'multiprocessexit' + REDIRECT_CMD = 'redirect' + GAM_META_COMMANDS = [SELECT_CMD, SHOWSECTIONS_CMD, SELECTFILTER_CMD, SELECTOUTPUTFILTER_CMD, SELECTINPUTFILTER_CMD, + CONFIG_CMD, MULTIPROCESSEXIT_CMD, REDIRECT_CMD] +# Command line arguments + ARG_3LO = '3lo' + ARG_ACL = 'acl' + ARG_ACLS = 'acls' + ARG_ADDRESSES = 'addresses' + ARG_ADMIN = 'admin' + ARG_ADMINS = 'admins' + ARG_ADMINROLE = 'adminrole' + ARG_ADMINROLES = 'adminroles' + ARG_ALERT = 'alert' + ARG_ALERTS = 'alerts' + ARG_ALERTFEEDBACK = 'alertfeedback' + ARG_ALERTFEEDBACKS = 'alertfeedbacks' + ARG_ALERTSFEEDBACK = 'alertsfeedback' + ARG_ALERTSETTINGS = 'alertsettings' + ARG_ALIAS = 'alias' + ARG_ALIASES = 'aliases' + ARG_ALIASDOMAIN = 'aliasdomain' + ARG_ALIASDOMAINS = 'aliasdomains' + ARG_ANALYTICACCOUNT = 'analyticaccount' + ARG_ANALYTICACCOUNTS = 'analyticaccounts' + ARG_ANALYTICACCOUNTSUMMARY = 'analyticaccountsummary' + ARG_ANALYTICACCOUNTSUMMARIES = 'analyticaccountsummaries' + ARG_ANALYTICDATASTREAM = 'analyticdatastream' + ARG_ANALYTICDATASTREAMS = 'analyticdatastreams' + ARG_ANALYTICPROPERTY = 'analyticproperty' + ARG_ANALYTICPROPERTIES = 'analyticproperties' + ARG_API = 'api' + ARG_APIS = 'apis' + ARG_APIPROJECT = 'apiproject' + ARG_APPACCESSSETTINGS = 'appaccesssettings' + ARG_APPDETAILS = 'appdetails' + ARG_APPLICATIONSPECIFICPASSWORDS = 'applicationspecificpasswords' + ARG_ASP = 'asp' + ARG_ASPS = 'asps' + ARG_BACKUPCODE = 'backupcode' + ARG_BACKUPCODES = 'backupcodes' + ARG_BROWSER = 'browser' + ARG_BROWSERS = 'browsers' + ARG_BROWSERTOKEN = 'browsertoken' + ARG_BROWSERTOKENS = 'browsertokens' + ARG_BUCKET = 'bucket' + ARG_BUCKETS = 'buckets' + ARG_BUILDING = 'building' + ARG_BUILDINGS = 'buildings' + ARG_BUSINESSPROFILEACCOUNT = 'businessprofileaccount' + ARG_BUSINESSPROFILEACCOUNTS = 'businessprofileaccounts' + ARG_CAALEVEL = 'caalevel' + ARG_CAALEVELS = 'caalevels' + ARG_CALATTENDEES = 'calattendees' + ARG_CALENDAR = 'calendar' + ARG_CALENDARS = 'calendars' + ARG_CALENDARACL = 'calendaracl' + ARG_CALENDARACLS = 'calendaracls' + ARG_CALENDARTRASH = 'calendartrash' + ARG_CALSETTINGS = 'calsettings' + ARG_CHANNELCUSTOMER = 'channelcustomer' + ARG_CHANNELCUSTOMERS = 'channelcustomers' + ARG_CHANNELCUSTOMERENTITLEMENT = 'channelcustomerentitlement' + ARG_CHANNELCUSTOMERENTITLEMENTS = 'channelcustomerentitlements' + ARG_CHANNELOFFER = 'channeloffer' + ARG_CHANNELOFFERS = 'channeloffers' + ARG_CHANNELPRODUCT = 'channelproduct' + ARG_CHANNELPRODUCTS = 'channelproducts' + ARG_CHANNELSKU = 'channelsku' + ARG_CHANNELSKUS = 'channelskus' + ARG_CHAT = 'chat' + ARG_CHATEMOJI = 'chatemoji' + ARG_CHATEMOJIS = 'chatemojis' + ARG_CHATEVENT = 'chatevent' + ARG_CHATEVENTS = 'chatevents' + ARG_CHATMEMBER = 'chatmember' + ARG_CHATMEMBERS = 'chatmembers' + ARG_CHATMESSAGE = 'chatmessage' + ARG_CHATMESSAGES = 'chatmessages' + ARG_CHATSEARCHMESSAGE = 'chatsearchmessage' + ARG_CHATSEARCHMESSAGES = 'chatsearchmessages' + ARG_CHATSECTION = 'chatsection' + ARG_CHATSECTIONS = 'chatsections' + ARG_CHATSECTIONITEM = 'chatsectionitem' + ARG_CHATSECTIONITEMS = 'chatsectionitems' + ARG_CHATSPACE = 'chatspace' + ARG_CHATSPACES = 'chatspaces' + ARG_CHATSPACEDM = 'chatspacedm' + ARG_CHROMEDEVICECOUNTS = 'chromedevicecounts' + ARG_CHROMEAPP = 'chromeapp' + ARG_CHROMEAPPS = 'chromeapps' + ARG_CHROMEAPPDEVICES = 'chromeappdevices' + ARG_CHROMEAUES = 'chromeaues' + ARG_CHROMEHISTORY = 'chromehistory' + ARG_CHROMENEEDSATTN = 'chromeneedsattn' + ARG_CHROMENETWORK = 'chromenetwork' + ARG_CHROMENETWORKS = 'chromenetworks' + ARG_CHROMEPOLICYIMAGE = 'chromepolicyimage' + ARG_CHROMEPOLICY = 'chromepolicy' + ARG_CHROMEPOLICIES = 'chromepolicies' + ARG_CHROMEPROFILE = 'chromeprofile' + ARG_CHROMEPROFILES = 'chromeprofiles' + ARG_CHROMEPROFILECOMMAND = 'chromeprofilecommand' + ARG_CHROMEPROFILECOMMANDS = 'chromeprofilecommands' + ARG_CHROMESCHEMA = 'chromeschema' + ARG_CHROMESCHEMAS = 'chromeschemas' + ARG_CHROMESNVALIDITY = 'chromesnvalidity' + ARG_CHROMEVERSIONS = 'chromeversions' + ARG_CIGROUP = 'cigroup' + ARG_CIGROUPS = 'cigroups' + ARG_CIGROUPMEMBERS = 'cigroupmembers' + ARG_CIGROUPSMEMBERS = 'cigroupsmembers' + ARG_CIMEMBER = 'cimember' + ARG_CIMEMBERS = 'cimembers' + ARG_CIPOLICY = 'policy' + ARG_CIPOLICIES = 'policies' + ARG_CLASSIFICATIONLABEL = 'classificationlabel' + ARG_CLASSIFICATIONLABELS = 'classificationlabels' + ARG_CLASSIFICATIONLABELPERMISSION = 'classificationlabelpermission' + ARG_CLASSIFICATIONLABELPERMISSIONS = 'classificationlabelpermissions' + ARG_CLASS = 'class' + ARG_CLASSES = 'classes' + ARG_CLASSCOUNTS = 'classcounts' + ARG_CLASSPARTICIPANTS = 'classparticipants' + ARG_CLASSROOMINVITATION = 'classroominvitation' + ARG_CLASSROOMINVITATIONS = 'classroominvitations' + ARG_CLASSROOMOAUTH2 = 'classroomoauth2' + ARG_CLASSROOMPROFILE = 'classroomprofile' + ARG_CONTACT = 'contact' + ARG_CONTACTS = 'contacts' + ARG_CONTACTDELEGATE = 'contactdelegate' + ARG_CONTACTDELEGATES = 'contactdelegates' + ARG_CONTACTGROUP = 'contactgroup' + ARG_CONTACTGROUPS = 'contactgroups' + ARG_CONTACTPHOTO = 'contactphoto' + ARG_CONTACTPHOTOS = 'contactphotos' + ARG_COUNT = 'count' + ARG_COUNTS = 'counts' + ARG_COURSE = 'course' + ARG_COURSES = 'courses' + ARG_COURSEANNOUNCEMENTS = 'courseannouncements' + ARG_COURSECOUNTS = 'coursecounts' + ARG_COURSEMATERIALS = 'coursematerials' + ARG_COURSEPARTICIPANTS = 'courseparticipants' + ARG_COURSESTUDENTGROUP = 'coursestudentgroup' + ARG_COURSESTUDENTGROUPS = 'coursestudentgroups' + ARG_COURSESTUDENTGROUPMEMBERS = 'coursestudentgroupmembers' + ARG_COURSESUBMISSIONS = 'coursesubmissions' + ARG_COURSETOPICS = 'coursetopics' + ARG_COURSEWORK = 'coursework' + ARG_CROS = 'cros' + ARG_CROSES = 'croses' + ARG_CROSACTIVITY = 'crosactivity' + ARG_CROSTELEMETRY = 'crostelemetry' + ARG_CSEIDENTITY = 'cseidentity' + ARG_CSEIDENTITIES = 'cseidentities' + ARG_CSEKEYPAIR = 'csekeypair' + ARG_CSEKEYPAIRS = 'csekeypairs' + ARG_CURRENTPROJECTID = 'currentprojectid' + ARG_CUSTOMER = 'customer' + ARG_CUSTOMERID = 'customerid' + ARG_DATASTUDIOASSET = 'datastudioasset' + ARG_DATASTUDIOASSETS = 'datastudioassets' + ARG_DATASTUDIOPERMISSION = 'datastudiopermission' + ARG_DATASTUDIOPERMISSIONS = 'datastudiopermissions' + ARG_LOOKERSTUDIOASSET = 'lookerstudioasset' + ARG_LOOKERSTUDIOASSETS = 'lookerstudioassets' + ARG_LOOKERSTUDIOPERMISSION = 'lookerstudiopermission' + ARG_LOOKERSTUDIOPERMISSIONS = 'lookerstudiopermissions' + ARG_DATATRANSFER = 'datatransfer' + ARG_DATATRANSFERS = 'datatransfers' + ARG_DELEGATE = 'delegate' + ARG_DELEGATES = 'delegates' + ARG_DEVICE = 'device' + ARG_DEVICES = 'devices' + ARG_DEVICEFILE = 'devicefile' + ARG_DEVICEFILES = 'devicefiles' + ARG_DEVICEUSER = 'deviceuser' + ARG_DEVICEUSERS = 'deviceusers' + ARG_DEVICEUSERSTATE = 'deviceuserstate' + ARG_DISKUSAGE = 'diskusage' + ARG_DOCUMENT = 'document' + ARG_DOMAIN = 'domain' + ARG_DOMAINS = 'domains' + ARG_DOMAINALIAS = 'domainalias' + ARG_DOMAINALIASES = 'domainaliases' + ARG_DOMAINCONTACT = 'domaincontact' + ARG_DOMAINCONTACTS = 'domaincontacts' + ARG_DOMAINCONTACTPHOTO = 'domaincontactphoto' + ARG_DOMAINCONTACTPHOTOS = 'domaincontactphotas' + ARG_DOMAINPROFILE = 'domainprofile' + ARG_DOMAINPROFILES = 'domainprofiles' + ARG_DRIVE = 'drive' + ARG_DRIVEACTIVITY = 'driveactivity' + ARG_DRIVEFILE = 'drivefile' + ARG_DRIVEFILEACL = 'drivefileacl' + ARG_DRIVEFILEACLS = 'drivefileacls' + ARG_DRIVEFILESHORTCUT = 'drivefileshortcut' + ARG_DRIVEFILESHORTCUTS = 'drivefileshortcuts' + ARG_DRIVEFOLDERPATH = 'drivefolderpath' + ARG_DRIVELABEL = 'drivelabel' + ARG_DRIVELABELS = 'drivelabels' + ARG_DRIVELABELPERMISSION = 'drivelabelpermission' + ARG_DRIVELABELPERMISSIONS = 'drivelabelpermissions' + ARG_DRIVELASTMODIFICATION = 'drivelastmodification' + ARG_DRIVELASTMODIFICATIONS = 'drivelastmodifications' + ARG_DRIVESETTINGS = 'drivesettings' + ARG_DRIVETRASH = 'drivetrash' + ARG_EMPTYDRIVEFOLDERS = 'emptydrivefolders' + ARG_EVENT = 'event' + ARG_EVENTS = 'events' + ARG_EXPORT = 'export' + ARG_EXPORTS = 'exports' + ARG_FEATURE = 'feature' + ARG_FEATURES = 'features' + ARG_FILECOMMENT = 'filecomment' + ARG_FILECOMMENTS = 'filecomments' + ARG_FILECOUNT = 'filecount' + ARG_FILECOUNTS = 'filecounts' + ARG_FILEDRIVELABEL = 'filedrivelabel' + ARG_FILEDRIVELABELS = 'filedrivelabels' + ARG_FILEINFO = 'fileinfo' + ARG_FILELIST = 'filelist' + ARG_FILEPARENTTREE = 'fileparenttree' + ARG_FILEPATH = 'filepath' + ARG_FILEPATHS = 'filepaths' + ARG_FILEREVISION = 'filerevision' + ARG_FILEREVISIONS = 'filerevisions' + ARG_FILESHARECOUNT = 'filesharecount' + ARG_FILESHARECOUNTS = 'filesharecounts' + ARG_FILETREE = 'filetree' + ARG_FILTER = 'filter' + ARG_FILTERS = 'filters' + ARG_FOCUSTIME = 'focustime' + ARG_FOCUSTIMES = 'focustimes' + ARG_FORM = 'form' + ARG_FORMS = 'forms' + ARG_FORMRESPONSE = 'formresponse' + ARG_FORMRESPONSES = 'formresponses' + ARG_FORWARD = 'forward' + ARG_FORWARDS = 'forwards' + ARG_FORWARDINGADDRESS = 'forwardingaddress' + ARG_FORWARDINGADDRESSES = 'forwardingaddresses' + ARG_GCPFOLDER = 'gcpfolder' + ARG_GCPORGID = 'gcporgid' + ARG_GCPSERVICEACCOUNT = 'gcpserviceaccount' + ARG_GMAIL = 'gmail' + ARG_GMAILPROFILE = 'gmailprofile' + ARG_GROUP = 'group' + ARG_GROUPS = 'groups' + ARG_GROUPLIST = 'grouplist' + ARG_GROUPSLIST = 'groupslist' + ARG_GROUPMEMBERS = 'groupmembers' + ARG_GROUPSMEMBERS = 'groupsmembers' + ARG_GROUPTREE = 'grouptree' + ARG_GUARDIAN = 'guardian' + ARG_GUARDIANS = 'guardians' + ARG_GUARDIANINVITE = 'guardianinvite' + ARG_GUARDIANINVITATION = 'guardianinvitation' + ARG_GUARDIANINVITATIONS = 'guardianinvitations' + ARG_GUESTUSER = 'guestuser' + ARG_GUESTUSERS = 'guestusers' + ARG_HOLD = 'hold' + ARG_HOLDS = 'holds' + ARG_IMAP = 'imap' + ARG_IMAP4 = 'imap4' + ARG_INBOUNDSSOASSIGNMENT = 'inboundssoassignment' + ARG_INBOUNDSSOASSIGNMENTS = 'inboundssoassignments' + ARG_INBOUNDSSOCREDENTIAL = 'inboundssocredential' + ARG_INBOUNDSSOCREDENTIALS = 'inboundssocredentials' + ARG_INBOUNDSSOPROFILE = 'inboundssoprofile' + ARG_INBOUNDSSOPROFILES = 'inboundssoprofiles' + ARG_INSTANCE = 'instance' + ARG_INVITEGUARDIAN = 'inviteguardian' + ARG_ISINVITABLE = 'isinvitable' + ARG_LABEL = 'label' + ARG_LABELS = 'labels' + ARG_LABELLIST = 'labellist' + ARG_LABELID = 'labelid' + ARG_LABELIDLIST = 'labelidlist' + ARG_LABELSETTINGS = 'labelsettings' + ARG_LANGUAGE = 'language' + ARG_LICENCE = 'licence' + ARG_LICENCES = 'licences' + ARG_LICENSE = 'license' + ARG_LICENSES = 'licenses' + ARG_MATTER = 'matter' + ARG_MATTERS = 'matters' + ARG_MEETSPACE = 'meetspace' + ARG_MEETSPACES = 'meetspaces' + ARG_MEETCONFERENCE = 'meetconference' + ARG_MEETCONFERENCES = 'meetconferences' + ARG_MEETPARTICIPANT = 'meetparticipant' + ARG_MEETPARTICIPANTS = 'meetparticipants' + ARG_MEETRECORDING = 'meetrecording' + ARG_MEETRECORDINGS = 'meetrecordings' + ARG_MEETTRANSCRIPT = 'meettranscript' + ARG_MEETTRANSCRIPTS = 'meettranscripts' + ARG_MEMBER = 'member' + ARG_MEMBERS = 'members' + ARG_MESSAGE = 'message' + ARG_MESSAGES = 'messages' + ARG_MESSAGEHISTORY = 'messagehistory' + ARG_MOBILE = 'mobile' + ARG_MOBILES = 'mobiles' + ARG_NICKNAME = 'nickname' + ARG_NICKNAMES = 'nicknames' + ARG_NOTE = 'note' + ARG_NOTES = 'notes' + ARG_NOTEACL = 'noteacl' + ARG_NOTEACLS = 'noteacls' + ARG_NOTESACL = 'notesacl' + ARG_NOTESACLS = 'notesacls' + ARG_NOTEATTACHMENT = 'noteattachment' + ARG_NOTEATTACHMENTS = 'noteattachments' + ARG_OAUTH = 'oauth' + ARG_ORG = 'org' + ARG_ORGS = 'orgs' + ARG_ORGTREE = 'orgtree' + ARG_ORGUNIT = 'orgunit' + ARG_ORGUNITS = 'orgunits' + ARG_ORGUNITSHAREDDRIVE = 'orgunitshareddrive' + ARG_ORGUNITSHAREDDRIVES = 'orgunitshareddrives' + ARG_ORPHANS = 'orphans' + ARG_OTHERCONTACT = 'othercontact' + ARG_OTHERCONTACTS = 'othercontacts' + ARG_OU = 'ou' + ARG_OUS = 'ous' + ARG_OUSHAREDDRIVE = 'oushareddrive' + ARG_OUSHAREDDRIVES = 'oushareddrives' + ARG_OUTOFOFFICE = 'outofoffice' + ARG_OUTOFOFFICES = 'outofoffices' + ARG_OUTREE = 'outree' + ARG_OWNERSHIP = 'ownership' + ARG_PARTICIPANTS = 'participants' + ARG_PEOPLE = 'people' + ARG_PEOPLECONTACT = 'peoplecontact' + ARG_PEOPLECONTACTS = 'peoplecontacts' + ARG_PEOPLECONTACTGROUP = 'peoplecontactgroup' + ARG_PEOPLECONTACTGROUPS = 'peoplecontactgroups' + ARG_PEOPLECONTACTPHOTO = 'peoplecontactphoto' + ARG_PEOPLECONTACTPHOTOS = 'peoplecontactphotos' + ARG_PEOPLEOTHERCONTACT = 'peopleothercontact' + ARG_PEOPLEOTHERCONTACTS = 'peopleothercontacts' + ARG_PEOPLEPROFILE = 'peopleprofile' + ARG_PEOPLEPROFILES = 'peopleprofiles' + ARG_PERMISSION = 'permission' + ARG_PERMISSIONS = 'permissions' + ARG_PHOTO = 'photo' + ARG_POP = 'pop' + ARG_POP3 = 'pop3' + ARG_PRINTER = 'printer' + ARG_PRINTERS = 'printers' + ARG_PRINTERMODEL = 'printermodel' + ARG_PRINTERMODELS = 'printermodels' + ARG_PRIVILEGES = 'privileges' + ARG_PROFILE = 'profile' + ARG_PROFILE_PHOTO = 'profilephoto' + ARG_PROJECT = 'project' + ARG_PROJECTS = 'projects' + ARG_RESELLERCUSTOMER = 'resellercustomer' + ARG_RESELLERCUSTOMERS = 'resellercustomers' + ARG_RESELLERSUBSCRIPTION = 'resellersubscription' + ARG_RESELLERSUBSCRIPTIONS = 'resellersubscriptions' + ARG_RESETPIV = 'resetpiv' + ARG_RESOLDCUSTOMER = 'resoldcustomer' + ARG_RESOLDCUSTOMERS = 'resoldcustomers' + ARG_RESOLDSUBSCRIPTION = 'resoldsubscription' + ARG_RESOLDSUBSCRIPTIONS = 'resoldsubscriptions' + ARG_RESOURCE = 'resource' + ARG_RESOURCES = 'resources' + ARG_ROLE = 'role' + ARG_ROLES = 'roles' + ARG_SAKEY = 'sakey' + ARG_SAKEYS = 'sakeys' + ARG_SCHEMA = 'schema' + ARG_SCHEMAS = 'schemas' + ARG_SECCALS = 'seccals' + ARG_SENDAS = 'sendas' + ARG_SERVICEACCOUNT = 'serviceaccount' + ARG_SETTINGS = 'settings' + ARG_SHAREDDRIVE = 'shareddrive' + ARG_SHAREDDRIVES = 'shareddrives' + ARG_SHAREDDRIVEACLS = 'shareddriveacls' + ARG_SHAREDDRIVEINFO = 'shareddriveinfo' + ARG_SHAREDDRIVEORGANIZERS = 'shareddriveorganizers' + ARG_SHAREDDRIVETHEMES = 'shareddrivethemes' + ARG_SHEET = 'sheet' + ARG_SHEETS = 'sheets' + ARG_SHEETRANGE = 'sheetrange' + ARG_SHEETRANGES = 'sheetranges' + ARG_SIG = 'sig' + ARG_SIGNATURE = 'signature' + ARG_SIGNJWTSERVICEACCOUNT = 'signjwtserviceaccount' + ARG_SITE = 'site' + ARG_SITES = 'sites' + ARG_SITEACL = 'siteacl' + ARG_SITEACLS = 'siteacls' + ARG_SITEACTIVITY = 'siteactivity' + ARG_SMIME = 'smime' + ARG_SMIMES = 'smimes' + ARG_STORAGEBUCKET = 'storagebucket' + ARG_STORAGEBUCKETS = 'storagebuckets' + ARG_STORAGEFILE = 'storagefile' + ARG_STORAGEFILES = 'storagefiles' + ARG_SUSPENDED = 'suspended' + ARG_SVCACCT = 'svcacct' + ARG_SVCACCTS = 'svcaccts' + ARG_TAGMANAGERACCOUNT = 'tagmanageraccount' + ARG_TAGMANAGERACCOUNTS = 'tagmanageraccounts' + ARG_TAGMANAGERCONTAINER = 'tagmanagercontainer' + ARG_TAGMANAGERCONTAINERS = 'tagmanagercontainers' + ARG_TAGMANAGERPERMISSION = 'tagmanagerpermission' + ARG_TAGMANAGERPERMISSIONS = 'tagmanagerpermissions' + ARG_TAGMANAGERTAG = 'tagmanagertag' + ARG_TAGMANAGERTAGS = 'tagmanagertags' + ARG_TAGMANAGERWORKSPACE = 'tagmanagerworkspace' + ARG_TAGMANAGERWORKSPACES = 'tagmanagerworkspaces' + ARG_TASK = 'task' + ARG_TASKS = 'tasks' + ARG_TASKLIST = 'tasklist' + ARG_TASKLISTS = 'tasklists' + ARG_TEAMDRIVE = 'teamdrive' + ARG_TEAMDRIVES = 'teamdrives' + ARG_TEAMDRIVEACLS = 'teamdriveacls' + ARG_TEAMDRIVEINFO = 'teamdriveinfo' + ARG_TEAMDRIVEORGANIZERS = 'teamdriveorganizers' + ARG_TEAMDRIVETHEMES = 'teamdrivethemes' + ARG_THREAD = 'thread' + ARG_THREADS = 'threads' + ARG_TOKEN = 'token' + ARG_TOKENS = 'tokens' + ARG_TRANSFER = 'transfer' + ARG_TRANSFERS = 'transfers' + ARG_TRANSFERAPPS = 'transferapps' + ARG_TRUSTEDAPPS = 'trustedapps' + ARG_USER = 'user' + ARG_USERS = 'users' + ARG_USERCOUNTSBYORGUNIT = 'usercountsbyorgunit' + ARG_USERINVITATION = 'userinvitation' + ARG_USERINVITATIONS = 'userinvitations' + ARG_USERLIST = 'userlist' + ARG_VACATION = 'vacation' + ARG_VAULTCOUNT = 'vaultcount' + ARG_VAULTCOUNTS = 'vaultcounts' + ARG_VAULTEXPORT = 'vaultexport' + ARG_VAULTEXPORTS = 'vaultexports' + ARG_VAULTHOLD = 'vaulthold' + ARG_VAULTHOLDS = 'vaultholds' + ARG_VAULTMATTER = 'vaultmatter' + ARG_VAULTMATTERS = 'vaultmatters' + ARG_VAULTQUERY = 'vaultquery' + ARG_VAULTQUERIES = 'vaultqueries' + ARG_VERIFICATION = 'verification' + ARG_VERIFICATIONCODES = 'verificationcodes' + ARG_VERIFY = 'verify' + ARG_WEBMASTERSITE = 'webmastersite' + ARG_WEBMASTERSITES = 'webmastersites' + ARG_WEBRESOURCE = 'webresource' + ARG_WEBRESOURCES = 'webresources' + ARG_WORKINGLOCATION = 'workinglocation' + ARG_WORKINGLOCATIONS = 'workinglocations' + ARG_YOUTUBECHANNEL = 'youtubechannel' + ARG_YOUTUBECHANNELS = 'youtubechannels' +# Lists of arguments for use in checkArgumentPresent + CLEAR_NONE_ARGUMENT = ['clear', 'none',] + +# Object BNF names + OB_ACCESS_LEVEL_NAME = 'AccessLevelName' + OB_ACCESS_TOKEN = 'AccessToken' + OB_ACL_SCOPE = 'ACLScope' + OB_ACL_SCOPE_ENTITY = 'ACLScopeEntity' + OB_ALERT_ID = 'AlertID' + OB_ALIAS_ENTITY = 'AliasEntity' + OB_API_SCOPE_URL_LIST = 'APIScopeURLList' + OB_APP_ID = 'AppID' + OB_ARGUMENT = 'argument' + OB_ASP_ID_LIST = 'ASPIDList' + OB_ASSET_ID = 'AssetID' + OB_ADMIN_ASSIGNEE_TYPE_LIST = 'AdminAssigneeTypeList' + OB_BROWSER_ENROLLEMNT_TOKEN_ID = 'BrowserEnrollmentTokenID' + OB_BROWSER_ENTITY = 'BrowserEntity' + OB_BUILDING_ID = 'BuildingID' + OB_CALENDAR_ENTITY = 'CalendarEntity' + OB_CALENDAR_ITEM = 'CalendarItem' + OB_CHANNEL_CUSTOMER_ID = 'ChannelCustomerID' + OB_CHARACTER = 'Character' + OB_CHAR_SET = 'CharacterSet' + OG_CHAT_ATTACHMENT = 'ChatAttachment' + OB_CHAT_EMOJI = 'ChatEmoji' + OB_CHAT_EMOJI_NAME = 'ChatEmojiName' + OB_CHAT_EVENT = 'ChatEvent' + OB_CHAT_MEMBER = 'ChatMember' + OB_CHAT_MESSAGE = 'ChatMessage' + OB_CHAT_MESSAGE_ID = 'ChatMessageID' + OB_CHAT_SECTION = 'ChatSection' + OB_CHAT_SPACE = 'ChatSpace' + OB_CHAT_SPACE_LIST = 'ChatSpaceList' + OB_CHAT_THREAD = 'ChatThread' + OB_CHROMEPROFILE_NAME = 'ChromeProfileName' + OB_CHROMEPROFILE_NAME_LIST = 'ChromeProfileNameList' + OB_CHROMEPROFILE_COMMAND_NAME = 'ChromeProfileCommandName' + OB_CHROMEPROFILE_COMMAND_NAME_LIST = 'ChromeProfileNameCommandList' + OB_CHROME_VERSION = 'ChromeVersion' + OB_CIDR_NETMASK = 'CIDRnetmask' + OB_CIGROUP_ALIAS_LIST = "CIGroupAliasList" + OB_CIPOLICY_NAME_ENTITY = 'CIPolicyNameEntity' + OB_CLASSIFICATION_LABEL_ID = 'ClassificationLabelID' + OB_CLASSIFICATION_LABEL_NAME = 'ClassificationLabelName' + OB_CLASSIFICATION_LABEL_PERMISSION_NAME = 'ClassificationLabelPermissionName' + OB_CLASSIFICATION_LABEL_FIELD_ID = 'ClassificationLabelFieldID' + OB_CLASSIFICATION_LABEL_SELECTION_ID_LIST = 'ClassificationLabelSelectionIDList' + OB_CLASSROOM_INVITATION_ID_ENTITY = 'ClassroomInvitationIDEntity' + OB_CLIENT_ID = 'ClientID' + OB_COLLABORATOR_ITEM = 'CollaboratorItem' + OB_COLLABORATOR_ENTITY = 'CollaboratorEntity' + OB_COMMAND_ID = 'CommandID' + OB_CONTACT_EMAIL_TYPE = 'ContactEmailType' + OB_CONTACT_ENTITY = 'ContactEntity' + OB_CONTACT_GROUP_ENTITY = 'ContactGroupEntity' + OB_CONTACT_GROUP_ITEM = 'ContactGroupItem' + OB_COURSE_ALIAS = 'CourseAlias' + OB_COURSE_ALIAS_ENTITY = 'CourseAliasEntity' + OB_COURSE_ANNOUNCEMENT_ID = "CourseAnnouncementID" + OB_COURSE_ANNOUNCEMENT_ID_ENTITY = "CourseAnnouncementIDEntity" + OB_COURSE_ANNOUNCEMENT_STATE_LIST = "CourseAnnouncementStateList" + OB_COURSE_ANNOUNCEMENT_ADD_STATE_LIST = "CourseAnnouncementAddStateList" + OB_COURSE_ANNOUNCEMENT_UPDATE_STATE_LIST = "CourseAnnouncementUpdateStateList" + OB_COURSE_ENTITY = 'CourseEntity' + OB_COURSE_ID = 'CourseID' + OB_COURSE_MATERIAL_ID_ENTITY = 'CourseMaterialIDEntity' + OB_COURSE_MATERIAL_STATE_LIST = "CourseMaterialStateList" + OB_COURSE_STATE_LIST = "CourseStateList" + OB_COURSE_SUBMISSION_ID_ENTITY = "CourseSubmissionIDEntity" + OB_COURSE_SUBMISSION_STATE_LIST = "CourseSubmissionStateList" + OB_COURSE_TOPIC = 'CourseTopic' + OB_COURSE_TOPIC_ENTITY = "CourseTopicEntity" + OB_COURSE_TOPIC_ID = 'CourseTopicID' + OB_COURSE_TOPIC_ID_ENTITY = "CourseTopicIDEntity" + OB_COURSE_WORK_ID_ENTITY = 'CourseWorkIDEntity' + OB_COURSE_WORK_STATE_LIST = "CourseWorkStateList" + OB_CROS_DEVICE_ENTITY = 'CrOSDeviceEntity' + OB_CROS_ENTITY = 'CrOSEntity' + OB_CSE_KEYPAIR_ID = 'CSEKeyPairID' + OB_CUSTOMER_ID = 'CustomerID' + OB_CUSTOMER_AUTH_TOKEN = 'CustomerAuthToken' + OB_DATETIME_FORMAT = 'DateTimeFormat' + OB_DEVICE_FILE_ENTITY = 'DeviceFileEntity' + OB_DEVICE_ENTITY = 'DeviceEntity' + OB_DEVICE_ID = 'DeviceID' + OB_DEVICE_ID_LIST = 'DeviceIDList' + OB_DEVICE_USER_ENTITY = 'DeviceUserEntity' + OB_DEVICE_USER_ID = 'DeviceUserID' + OB_DOMAIN_ALIAS = 'DomainAlias' + OB_DOMAIN_NAME = 'DomainName' + OB_DOMAIN_NAME_ENTITY = 'DomainNameEntity' + OB_DOMAIN_NAME_LIST = 'DomainNameList' + OB_DRIVE_FILE_ENTITY = 'DriveFileEntity' + OB_DRIVE_FILE_ID = 'DriveFileID' + OB_DRIVE_FILE_ID_LIST = 'DriveFileIDList' + OB_DRIVE_FILE_NAME = 'DriveFileName' + OB_DRIVE_FILE_PERMISSION_ENTITY = 'DriveFilePermissionEntity' + OB_DRIVE_FILE_PERMISSION_ID = 'DriveFilePermissionID' + OB_DRIVE_FILE_PERMISSION_ID_ENTITY = 'DriveFilePermissionIDEntity' + OB_DRIVE_FILE_REVISION_ID = 'DriveFileRevisionID' + OB_DRIVE_FOLDER_ID = 'DriveFolderID' + OB_DRIVE_FOLDER_ID_LIST = 'DriveFolderIDList' + OB_DRIVE_FOLDER_NAME = 'DriveFolderName' + OB_DRIVE_FOLDER_NAME_LIST = 'DriveFolderNameList' + OB_DRIVE_FOLDER_PATH = 'DriveFolderPath' + OB_EMAIL_ADDRESS = 'EmailAddress' + OB_EMAIL_ADDRESS_ENTITY = 'EmailAddressEntity' + OB_EMAIL_ADDRESS_LIST = 'EmailAddressList' + OB_EMAIL_ADDRESS_OR_UID = 'EmailAaddress|UniqueID' + OB_EMAIL_REPLACEMENT = 'EmailReplacement' + OB_ENTITY = 'Entity' + OB_ENTITY_TYPE = 'EntityType' + OB_EVENT_ID = 'EventID' + OB_EVENT_ID_ENTITY = 'EventIDEntity' + OB_EVENT_NAME_LIST = "EventNameList" + OB_EXPORT_ITEM = 'ExportItem' + OB_FIELD_NAME = 'FieldName' + OB_FIELD_NAME_LIST = "FieldNameList" + OB_FIELDS = 'Fields' + OB_FILE_NAME = 'FileName' + OB_FILE_NAME_FIELD_NAME = OB_FILE_NAME+'(:'+OB_FIELD_NAME+')+' + OB_FILE_NAME_OR_URL = 'FileName|URL' + OB_FILE_NAME_PATTERN = 'FileNamePattern' + OB_FILE_PATH = 'FilePath' + OB_FILTER_ID_ENTITY = 'FilterIDEntity' + OB_FORMAT_LIST = 'FormatList' + OB_GAM_ARGUMENT_LIST = 'GAM argument list' + OB_GROUP_ENTITY = 'GroupEntity' + OB_GROUP_ITEM = 'GroupItem' + OB_GROUP_ROLE_LIST = 'GroupRoleList' + OB_GROUP_TYPE_LIST = 'GroupTypeList' + OB_GUARDIAN_INVITATION_ID = 'GuardianInvitationID' + OB_GUARDIAN_INVITATION_ID_ENTITY = 'GuardianInvitationIDEntity' + OB_GUARDIAN_ENTITY = 'GuardianEntity' + OB_GUARDIAN_ITEM = 'GuardianItem' + OB_GUARDIAN_STATE_LIST = 'GuardianStateList' + OB_HOLD_ITEM = 'HoldItem' + OB_HOST_NAME = 'HostName' + OB_ICALUID = 'iCalUID' + OB_ID_TOKEN = 'IDToken' + OB_JOB_ID = 'JobID' + OB_JSON_DATA = 'JSONData' + OB_LABEL_COLOR_HEX = 'LabelColorHex' + OB_LABEL_ID = 'LabelID' + OB_LABEL_ID_LIST = 'LabelIDLIst' + OB_LABEL_NAME = 'LabelName' + OB_LABEL_NAME_LIST = 'LabelNameList' + OB_LANGUAGE_LIST = 'LanguageList' + OB_LOOKERSTUDIO_PERMISSION_ENTITY = 'LookerStudioPermissionEntity' + OB_MATTER_ITEM = 'MatterItem' + OB_MATTER_ITEM_LIST = 'MatterItemList' + OB_MEET_CONFERENCE_NAME = 'MeetConferenceName' + OB_MEET_ID = 'MeetID' + OB_MESSAGE_ID = 'MessageID' + OB_MIMETYPE = 'MimeType' + OB_MIMETYPE_LIST = 'MimeTypeList' + OB_MOBILE_DEVICE_ENTITY = 'MobileDeviceEntity' + OB_MOBILE_ENTITY = 'MobileEntity' + OB_NETWORK_ID = 'networkID' + OB_NAME = 'Name' + OB_NUMBER_RANGE_LIST = 'NumberRangeList' + OB_ORGANIZER_TYPE_LIST = 'OrganizerTypeList' + OB_ORGUNIT_ENTITY = 'OrgUnitEntity' + OB_ORGUNIT_ITEM = 'OrgUnitItem' + OB_ORGUNIT_PATH = 'OrgUnitPath' + OB_PARAMETER_VALUE = 'ParameterValue' + OB_PASSWORD = 'Password' + OB_PERMISSION_ID_LIST = 'PermissionIDList' + OB_PERMISSION_ROLE_LIST = 'PermissionRoleList' + OB_PERMISSION_TYPE_LIST = 'PermissionTypeList' + OB_PRINTER_ID = 'PrinterID' + OB_PRIVILEGE_LIST = 'PrivilegeList' + OB_PRODUCT_ID = 'ProductID' + OB_PRODUCT_ID_LIST = 'ProductIDList' + OB_PROJECT_ID = 'ProjectID' + OB_PROJECT_ID_ENTITY = 'ProjectIDEntity' + OB_PROPERTY_KEY = 'PropertyKey' + OB_PROPERTY_VALUE = 'PropertyValue' + OB_PUBSUB_TOPIC_NAME = 'PubSubTopicName' + OB_QUERY = 'Query' + OB_QUERY_ITEM = 'QueryItem' + OB_QUERY_LIST = 'QueryList' + OB_RECURRENCE = 'RRULE EXRULE RDATE and EXDATE lines' + OB_REQUEST_ID = 'RequestID' + OB_RESELLER_ID = 'ResellerID' + OB_RESOURCE_ENTITY = 'ResourceEntity' + OB_RESOURCE_ID = 'ResourceID' + OB_RE_PATTERN = 'REPattern' + OB_RE_SUBSTITUTION = 'RESubstitution' + OB_ROLE_ASSIGNMENT_ID = 'RoleAssignmentID' + OB_ROLE_ITEM = 'RoleItem' + OB_ROLE_LIST = 'RoleList' + OB_SCHEMA_ENTITY = 'SchemaEntity' + OB_SCHEMA_NAME = 'SchemaName' + OB_SCHEMA_NAME_FIELD_NAME = 'SchemaName.FieldName' + OB_SCHEMA_NAME_LIST = 'SchemaNameList' + OB_SECTION_NAME = 'SectionName' + OB_SERIAL_NUMBER = 'SerialNumber' + OB_SERIAL_NUMBER_LIST = 'SerialNumberList' + OB_SERVICE_NAME_LIST = 'ServiceNameList' + OB_SERVICE_ACCOUNT_KEY_LIST = 'ServiceAccountKeyList' + OB_SHAREDDRIVE_ID = 'SharedDriveID' + OB_SHAREDDRIVE_ID_LIST = 'SharedDriveIDList' + OB_SHAREDDRIVE_NAME = 'SharedDriveName' + OB_SHEET_ENTITY = 'SheetEntity' + OB_SITE_ENTITY = 'SiteEntity' + OB_SKU_ID = 'SKUID' + OB_SKU_ID_LIST = 'SKUIDList' + OB_SMIME_ID = 'S/MIMEID' + OB_SMTP_HOST_NAME = 'SMTPHostName' + OB_SPREADSHEET_JSON_CREATEREQUEST = 'SpreadsheetJSONCreateRequest' + OB_SPREADSHEET_JSON_RANGEVALUESLIST = 'SpreadsheetJSONRangeValuesList' + OB_SPREADSHEET_JSON_UPDATEREQUEST = 'SpreadsheetJSONUpdateRequest' + OB_SPREADSHEET_JSON_VALUES = 'SpreadsheetJSONValues' + OB_SPREADSHEET_RANGE = 'SpreadsheetRange' + OB_SPREADSHEET_RANGE_LIST = 'SpreadsheetRangeList' + OB_STATE_NAME_LIST = "StateNameList" + OB_STRING = 'String' + OB_STRING_ENTITY = 'StringEntity' + OB_STRING_LIST = 'StringList' + OB_STUDENTGROUP_ID = 'StudentGroupID' + OB_STUDENTGROUP_ID_ENTITY = 'StudentGroupIDEntity' + OB_STUDENT_ITEM = 'StudentItem' + OB_TAG = 'Tag' + OB_TAGMANAGER_PATH_LIST = 'TagManagerPathList' + OB_TASK_ID = 'TaskID' + OB_TASKLIST_ID = 'TaskListID' + OB_TASKLIST_ID_ENTITY = 'TaskListIDEntity' + OB_TASKLIST_ID_TASK_ID = 'TaskListIDTaskID' + OB_TASKLIST_ID_TASK_ID_ENTITY = 'TaskListIDTaskIDEntity' + OB_THREAD_ID = 'ThreadID' + OB_TIME_LIST = 'TimeList' + OB_TRANSFER_ID = 'TransferID' + OB_URI = 'URI' + OB_URL = 'URL' + OB_URL_LIST = 'URLList' + OB_USER_ENTITY = 'UserEntity' + OB_USER_ITEM = 'UserItem' + OB_USER_NAME = 'UserName' + OB_YOUTUBE_CHANNEL_ID_LIST = 'YouTubeChannelIDlist' + +# +# Error message types; keys into ARGUMENT_ERROR_NAMES; arbitrary values but must be unique + ARGUMENT_BLANK = 'blnk' + ARGUMENT_DEPRECATED = 'depr' + ARGUMENT_EMPTY = 'empt' + ARGUMENT_EXTRANEOUS = 'extr' + ARGUMENT_INVALID = 'inva' + ARGUMENT_INVALID_CHOICE = 'invc' + ARGUMENT_MISSING = 'miss' +# ARGUMENT_ERROR_NAMES[0] is plural,ARGUMENT_ERROR_NAMES[1] is singular +# These values can be translated into other languages + ARGUMENT_ERROR_NAMES = { + ARGUMENT_BLANK: ['Blank arguments', 'Blank argument'], + ARGUMENT_DEPRECATED: ['Deprecated arguments', 'Deprecated argument'], + ARGUMENT_EMPTY: ['Empty arguments', 'Empty argument'], + ARGUMENT_EXTRANEOUS: ['Extra arguments', 'Extra argument'], + ARGUMENT_INVALID: ['Invalid arguments', 'Invalid argument'], + ARGUMENT_INVALID_CHOICE: ['Invalid choices', 'Invalid choice ({0})'], + ARGUMENT_MISSING: ['Missing arguments', 'Missing argument'], + } + + # Shared state across all instances (class-level) + _argv = [] + _argvI = 0 + _argvLen = 0 + _argvIsave = 0 + _origArgv = [] + _origArgvI = 0 + _origArgvLen = 0 + _encoding = 'utf-8' + + @property + def argv(self): + return GamCLArgs._argv + @argv.setter + def argv(self, value): + GamCLArgs._argv = value + + @property + def argvI(self): + return GamCLArgs._argvI + @argvI.setter + def argvI(self, value): + GamCLArgs._argvI = value + + @property + def argvLen(self): + return GamCLArgs._argvLen + @argvLen.setter + def argvLen(self, value): + GamCLArgs._argvLen = value + + @property + def argvIsave(self): + return GamCLArgs._argvIsave + @argvIsave.setter + def argvIsave(self, value): + GamCLArgs._argvIsave = value + + @property + def origArgv(self): + return GamCLArgs._origArgv + @origArgv.setter + def origArgv(self, value): + GamCLArgs._origArgv = value + + @property + def origArgvI(self): + return GamCLArgs._origArgvI + @origArgvI.setter + def origArgvI(self, value): + GamCLArgs._origArgvI = value + + @property + def origArgvLen(self): + return GamCLArgs._origArgvLen + @origArgvLen.setter + def origArgvLen(self, value): + GamCLArgs._origArgvLen = value + + @property + def encoding(self): + return GamCLArgs._encoding + @encoding.setter + def encoding(self, value): + GamCLArgs._encoding = value + + def __init__(self): + pass # state is shared at class level + +# Initialize arguments + def InitializeArguments(self, args): + GamCLArgs._argv = args[:] + GamCLArgs._argvI = 1 + GamCLArgs._argvLen = len(GamCLArgs._argv) + +# Number of arguments remaining + def NumArgumentsRemaining(self): + return GamCLArgs._argvLen - GamCLArgs._argvI + +# Any arguments remaining + def ArgumentsRemaining(self): + return GamCLArgs._argvI < GamCLArgs._argvLen + +# Multiple arguments remaining + def MultipleArgumentsRemaining(self): + return not GamCLArgs._argvI+1 == GamCLArgs._argvLen + +# All arguments + def AllArguments(self): + return GamCLArgs._argv + +# Specific argument + def Argument(self, index): + return GamCLArgs._argv[index] + +# Current argument + def Current(self): + return GamCLArgs._argv[GamCLArgs._argvI] + +# Previous argument + def Previous(self): + return GamCLArgs._argv[GamCLArgs._argvI-1] + +# Remaining arguments + def Remaining(self): + return GamCLArgs._argv[GamCLArgs._argvI:] + +# Argument location + def Location(self): + return GamCLArgs._argvI + +# Advance to next argument + def Advance(self): + GamCLArgs._argvI += 1 + +# Backup to previous argument + def Backup(self): + GamCLArgs._argvI -= 1 + +# Save argument location + def SaveLocation(self): + GamCLArgs._argvIsave = GamCLArgs._argvI + +# Reset argument location + def ResetLocation(self, offset): + GamCLArgs._argvI = GamCLArgs._argvIsave+offset + +# Set argument location + def SetLocation(self, location): + GamCLArgs._argvI = location + +# Set encoding + def SetEncoding(self, encoding): + GamCLArgs._encoding = encoding + +# Concatenate list members, any item containing spaces, commas or single quotes is enclosed in "" + @staticmethod + def QuotedArgumentList(items): + return ' '.join([item if item and (item.find(' ') == -1) and (item.find(',') == -1) and (item.find("'") == -1) else '"'+item+'"' for item in items]) + +# Mark bad argument in command line + def CommandLineWithBadArgumentMarked(self, extraneous): + if extraneous: + return f'Command: {self.QuotedArgumentList(GamCLArgs._argv[:GamCLArgs._argvI])} >>>{self.QuotedArgumentList(GamCLArgs._argv[GamCLArgs._argvI:])}<<<\n' + if self.ArgumentsRemaining(): + return f'Command: {self.QuotedArgumentList(GamCLArgs._argv[:GamCLArgs._argvI])} >>>{self.QuotedArgumentList([GamCLArgs._argv[GamCLArgs._argvI]])}<<< {self.QuotedArgumentList(GamCLArgs._argv[GamCLArgs._argvI+1:])}\n' + return f'Command: {self.QuotedArgumentList(GamCLArgs._argv)} >>><<<\n' + +# Deprecated command + def CommandDeprecated(self): + return f'{self.QuotedArgumentList(GamCLArgs._argv)}\n' + +# Peek to see if next argument is in choices + def PeekArgumentPresent(self, choices): + if self.ArgumentsRemaining(): + choiceList = choices if isinstance(choices, (list, set)) else [choices] + choice = self.Current().strip().lower().replace('_', '') + if choice and choice in choiceList: + return True + return False + +# Look ahead to see if argument is present + def ArgumentIsAhead(self, argument): + self.SaveLocation() + while self.ArgumentsRemaining(): + if argument == self.Current().strip().lower().replace('_', ''): + self.ResetLocation(0) + return True + self.Advance() + self.ResetLocation(0) + return False + +# Merge new arguments into current argument list + def MergeArguments(self, arguments): + GamCLArgs._origArgv = GamCLArgs._argv[:] + GamCLArgs._origArgvI = GamCLArgs._argvI + GamCLArgs._origArgvLen = GamCLArgs._argvLen + GamCLArgs._argv = GamCLArgs._argv[0:GamCLArgs._argvI]+arguments+GamCLArgs._argv[GamCLArgs._argvI:] + GamCLArgs._argvLen += len(arguments) + +# Restore + def RestoreArguments(self): + GamCLArgs._argv = GamCLArgs._origArgv[:] + GamCLArgs._argvI = GamCLArgs._origArgvI + GamCLArgs._argvLen = GamCLArgs._origArgvLen diff --git a/src/gam/gamlib/entity.py b/src/gam/gamlib/entity.py new file mode 100644 index 00000000..0b5401c1 --- /dev/null +++ b/src/gam/gamlib/entity.py @@ -0,0 +1,900 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM entity processing + +""" + +class GamEntity(): + + ROLE_MANAGER = 'MANAGER' + ROLE_MEMBER = 'MEMBER' + ROLE_OWNER = 'OWNER' + ROLE_LIST = [ROLE_MANAGER, ROLE_MEMBER, ROLE_OWNER] + ROLE_USER = 'USER' + ROLE_MANAGER_MEMBER = ','.join([ROLE_MANAGER, ROLE_MEMBER]) + ROLE_MANAGER_OWNER = ','.join([ROLE_MANAGER, ROLE_OWNER]) + ROLE_MEMBER_OWNER = ','.join([ROLE_MEMBER, ROLE_OWNER]) + ROLE_MANAGER_MEMBER_OWNER = ','.join(ROLE_LIST) + ROLE_PUBLIC = 'PUBLIC' + ROLE_ALL = ROLE_MANAGER_MEMBER_OWNER + + TYPE_CBCM_BROWSER = 'CBCM_BROWSER' + TYPE_CUSTOMER = 'CUSTOMER' + TYPE_EXTERNAL = 'EXTERNAL' + TYPE_OTHER = 'OTHER' + TYPE_GROUP = 'GROUP' + TYPE_SERVICE_ACCOUNT = 'SERVICE_ACCOUNT' + TYPE_USER = 'USER' + +# Keys into NAMES; arbitrary values but must be unique + ACCESS_TOKEN = 'atok' + ACCOUNT = 'acct' + ACTION = 'actn' + ACTIVITY = 'actv' + ADMINISTRATOR = 'admi' + ADMIN_ROLE = 'adro' + ADMIN_ROLE_ASSIGNMENT = 'adra' + ALERT = 'alrt' + ALERT_ID = 'alri' + ALERT_FEEDBACK = 'alfb' + ALERT_FEEDBACK_ID = 'alfi' + ALERT_SETTINGS = 'alrs' + ALIAS = 'alia' + ALIAS_EMAIL = 'alie' + ALIAS_TARGET = 'alit' + ANALYTIC_ACCOUNT = 'anac' + ANALYTIC_ACCOUNT_SUMMARY = 'anas' + ANALYTIC_DATASTREAM = 'anad' + ANALYTIC_PROPERTY = 'anap' + API = 'api ' + APP_ACCESS_SETTINGS = 'apps' + APP_ID = 'appi' + APP_NAME = 'appn' + APPLICATION_SPECIFIC_PASSWORD = 'aspa' + ARROWS_ENABLED = 'arro' + ATTACHMENT = 'atta' + ATTENDEE = 'atnd' + AUDIT_ACTIVITY_REQUEST = 'auda' + AUDIT_EXPORT_REQUEST = 'audx' + AUDIT_MONITOR_REQUEST = 'audm' + BACKUP_VERIFICATION_CODES = 'buvc' + BUILDING = 'bldg' + BUILDING_ID = 'bldi' + BUSINESS_PROFILE_ACCOUNT = 'bpac' + CAA_LEVEL = 'calv' + CALENDAR = 'cale' + CALENDAR_ACL = 'cacl' + CALENDAR_SETTINGS = 'cset' + CHANNEL_CUSTOMER = 'chcu' + CHANNEL_CUSTOMER_ENTITLEMENT = 'chce' + CHANNEL_OFFER = 'chof' + CHANNEL_PRODUCT = 'chpr' + CHANNEL_SKU = 'chsk' + CHAT_BOT = 'chbo' + CHAT_ADMIN = 'chad' + CHAT_EMOJI = 'chem' + CHAT_EVENT = 'chev' + CHAT_MANAGER_USER = 'chgu' + CHAT_MEMBER = 'chme' + CHAT_MEMBER_GROUP = 'chmg' + CHAT_MEMBER_USER = 'chmu' + CHAT_MESSAGE = 'chms' + CHAT_MESSAGE_ID = 'chmi' + CHAT_OWNER_USER = 'chou' + CHAT_SECTION = 'chse' + CHAT_SECTION_ITEM = 'chsi' + CHAT_SPACE = 'chsp' + CHAT_THREAD = 'chth' + CHILD_ORGANIZATIONAL_UNIT = 'corg' + CHROME_APP = 'capp' + CHROME_APP_DEVICE = 'capd' + CHROME_BROWSER = 'chbr' + CHROME_BROWSER_ENROLLMENT_TOKEN = 'cbet' + CHROME_CHANNEL = 'chan' + CHROME_DEVICE = 'chdv' + CHROME_DEVICE_COUNT = 'chdc' + CHROME_MODEL = 'chmo' + CHROME_NETWORK_ID = 'chni' + CHROME_NETWORK_NAME = 'chnn' + CHROME_PLATFORM = 'cpla' + CHROME_POLICY = 'cpol' + CHROME_POLICY_IMAGE = 'cpim' + CHROME_POLICY_SCHEMA = 'cpsc' + CHROME_PROFILE = 'cpro' + CHROME_PROFILE_COMMAND = 'cpcm' + CHROME_RELEASE = 'crel' + CHROME_VERSION = 'cver' + CLASSIFICATION_LABEL = 'dlab' + CLASSIFICATION_LABEL_FIELD_ID = 'dlfi' + CLASSIFICATION_LABEL_ID = 'dlid' + CLASSIFICATION_LABEL_NAME = 'dlna' + CLASSIFICATION_LABEL_PERMISSION = 'dlpe' + CLASSIFICATION_LABEL_PERMISSION_NAME = 'dlpn' + CLASSROOM_INVITATION = 'clai' + CLASSROOM_INVITATION_OWNER = 'clio' + CLASSROOM_INVITATION_STUDENT = 'clis' + CLASSROOM_INVITATION_TEACHER = 'clit' + CLASSROOM_OAUTH2_TXT_FILE = 'coa' + CLASSROOM_USER_PROFILE = 'clup' + CLIENT_ID = 'clid' + CLIENT_SECRETS_JSON_FILE = 'csjf' + CLOUD_IDENTITY_GROUP = 'cidg' + CLOUD_STORAGE_BUCKET = 'clsb' + CLOUD_STORAGE_FILE = 'clsf' + COLLABORATOR = 'cola' + COMMAND_ID = 'cmdi' + COMPANY_DEVICE = 'codv' + CONFIG_FILE = 'conf' + CONTACT = 'cont' + CONTACT_DELEGATE = 'cond' + CONTACT_GROUP = 'cogr' + CONTACT_GROUP_NAME = 'cogn' + COPYFROM_COURSE = 'cfco' + COPYFROM_GROUP = 'cfgr' + COURSE = 'cour' + COURSE_ALIAS = 'coal' + COURSE_ANNOUNCEMENT = 'cann' + COURSE_ANNOUNCEMENT_ID = 'caid' + COURSE_ANNOUNCEMENT_STATE = 'cast' + COURSE_MATERIAL_DRIVEFILE = 'comd' + COURSE_MATERIAL_FORM = 'comf' + COURSE_MATERIAL = 'cmtl' + COURSE_MATERIAL_ID = 'cmid' + COURSE_MATERIAL_STATE = 'cmst' + COURSE_NAME = 'cona' + COURSE_STATE = 'cost' + COURSE_STUDENTGROUP = 'cosg' + COURSE_STUDENTGROUP_MEMBER = 'csgm' + COURSE_SUBMISSION_ID = 'csid' + COURSE_SUBMISSION_STATE = 'csst' + COURSE_TOPIC = 'ctop' + COURSE_TOPIC_ID = 'ctoi' + COURSE_WORK = 'cwrk' + COURSE_WORK_ID = 'cwid' + COURSE_WORK_STATE = 'cwst' + CREATOR_ID = 'crid' + CREDENTIALS = 'cred' + CRITERIA = 'crit' + CROS_DEVICE = 'cros' + CROS_SERIAL_NUMBER = 'crsn' + CSE_IDENTITY = 'csei' + CSE_KEYPAIR = 'csek' + CUSTOMER_DOMAIN = 'cudo' + CUSTOMER_ID = 'cuid' + DATE = 'date' + DEFAULT_LANGUAGE = 'dfla' + DELEGATE = 'dele' + DELETED_USER = 'delu' + DELIVERY = 'deli' + DEVICE = 'devi' + DEVICE_FILE = 'devf' + DIRECTORY = 'drct' + DEVICE_USER = 'devu' + DEVICE_USER_CLIENT_STATE = 'ducs' + DISCOVERY_JSON_FILE = 'disc' + DOCUMENT = 'docu' + DOMAIN = 'doma' + DOMAIN_ALIAS = 'doal' + DOMAIN_CONTACT = 'doco' + DOMAIN_PEOPLE_CONTACT = 'dopc' + DOMAIN_PROFILE = 'dopr' + DRIVE_DISK_USAGE = 'drdu' + DRIVE_FILE = 'dfil' + DRIVE_FILE_COMMENT = 'filc' + DRIVE_FILE_ID = 'fili' + DRIVE_FILE_NAME = 'filn' + DRIVE_FILE_RENAMED = 'firn' + DRIVE_FILE_REVISION = 'filr' + DRIVE_FILE_SHORTCUT = 'fils' + DRIVE_FILE_OR_FOLDER = 'fifo' + DRIVE_FILE_OR_FOLDER_ACL = 'fiac' + DRIVE_FILE_OR_FOLDER_ID = 'fifi' + DRIVE_FOLDER = 'fold' + DRIVE_FOLDER_ID = 'foli' + DRIVE_FOLDER_NAME = 'foln' + DRIVE_FOLDER_PATH = 'folp' + DRIVE_FOLDER_RENAMED = 'forn' + DRIVE_FOLDER_SHORTCUT = 'fols' + DRIVE_ORPHAN_FILE_OR_FOLDER = 'orph' + DRIVE_PARENT_FOLDER = 'fipf' + DRIVE_PARENT_FOLDER_ID = 'fipi' + DRIVE_PARENT_FOLDER_REFERENCE = 'pfrf' + DRIVE_PATH = 'drvp' + DRIVE_SETTINGS = 'drvs' + DRIVE_SHORTCUT = 'drsc' + DRIVE_SHORTCUT_ID = 'dsci' + DRIVE_3PSHORTCUT = 'dr3s' + DRIVE_TRASH = 'drvt' + EMAIL = 'emai' + EMAIL_ALIAS = 'emal' + EMAIL_SETTINGS = 'emse' + END_TIME = 'endt' + ENTITY = 'enti' + EVENT = 'evnt' + EVENT_BIRTHDAY = 'evbd' + EVENT_FOCUSTIME = 'evft' + EVENT_OUTOFOFFICE = 'evoo' + EVENT_WORKINGLOCATION = 'evwl' + FEATURE = 'feat' + FIELD = 'fiel' + FILE = 'file' + FILE_PARENT_TREE = 'fptr' + FILTER = 'filt' + FORM = 'form' + FORM_RESPONSE = 'frmr' + FORWARD_ENABLED = 'fwde' + FORWARDING_ADDRESS = 'fwda' + GCP_FOLDER = 'gcpf' + GCP_FOLDER_NAME = 'gcpn' + GCP_ORG_ID = 'gcpo' + GMAIL_PROFILE = 'gmpr' + GROUP = 'grou' + GROUP_ALIAS = 'gali' + GROUP_EMAIL = 'gale' + GROUP_MEMBERSHIP = 'gmem' + GROUP_MEMBERSHIP_TREE = 'gmtr' + GROUP_SETTINGS = 'gset' + GROUP_TREE = 'gtre' + GUARDIAN = 'guar' + GUARDIAN_INVITATION = 'gari' + GUARDIAN_AND_INVITATION = 'gani' + GUEST_USER = 'gstu' + IAM_POLICY = 'iamp' + IMAP_ENABLED = 'imap' + INBOUND_SSO_ASSIGNMENT = 'insa' + INBOUND_SSO_CREDENTIALS = 'insc' + INBOUND_SSO_PROFILE = 'insp' + INSTANCE = 'inst' + ITEM = 'item' + ISSUER_CN = 'iscn' + KEYBOARD_SHORTCUTS_ENABLED = 'kbsc' + LABEL = 'labe' + LABEL_ID = 'labi' + LANGUAGE = 'lang' + LICENSE = 'lice' + LOCATION = 'loca' + LOOKERSTUDIO_ASSET = 'lsas' + LOOKERSTUDIO_ASSET_DATASOURCE = 'lsad' + LOOKERSTUDIO_ASSETID = 'lsai' + LOOKERSTUDIO_ASSET_REPORT = 'lsar' + LOOKERSTUDIO_PERMISSION = 'lspe' + MD5HASH = 'md5h' + MEET_SPACE = 'mesp' + MEET_CONFERENCE = 'msco' + MEET_PARTICIPANT = 'msps' + MEET_RECORDING = 'msre' + MEET_TRANSCRIPT = 'mstr' + MEMBER = 'memb' + MEMBER_NOT_ARCHIVED = 'mena' + MEMBER_ARCHIVED = 'mear' + MEMBER_NOT_SUSPENDED = 'mens' + MEMBER_SUSPENDED = 'mesu' + MEMBER_NOT_SUSPENDED_NOT_ARCHIVED = 'nsna' + MEMBER_SUSPENDED_ARCHIVED = 'suar' + MEMBER_RESTRICTION = 'memr' + MEMBER_URI = 'memu' + MEMBERSHIP_TREE = 'metr' + MESSAGE = 'mesg' + MIMETYPE = 'mime' + MOBILE_DEVICE = 'mobi' + NAME = 'name' + NONEDITABLE_ALIAS = 'neal' + NOTE = 'note' + NOTE_ACL = 'nota' + NOTES_ACLS = 'naac' + NOTIFICATION = 'noti' + OAUTH2_TXT_FILE = 'oaut' + OAUTH2SERVICE_JSON_FILE = 'oau2' + ORGANIZATIONAL_UNIT = 'orgu' + OTHER_CONTACT = 'otco' + OWNER = 'ownr' + OWNER_ID = 'owid' + PAGE_SIZE = 'page' + PARENT_ORGANIZATIONAL_UNIT = 'porg' + PARTICIPANT = 'part' + PEOPLE_CONTACT = 'peco' + PEOPLE_CONTACT_GROUP = 'pecg' + PEOPLE_PHOTO = 'peph' + PEOPLE_PROFILE = 'pepr' + PERMISSION = 'perm' + PERMISSION_ID = 'peid' + PERMITTEE = 'prmt' + PERSONAL_DEVICE = 'pedv' + PHOTO = 'phot' + POLICY = 'poli' + POP_ENABLED = 'popa' + PRESENTATION = 'pres' + PRINTER = 'prin' + PRINTER_ID = 'prid' + PRINTER_MODEL = 'prmd' + PRIVILEGE = 'priv' + PRODUCT = 'prod' + PROFILE_SHARING_ENABLED = 'prof' + PROJECT = 'proj' + PROJECT_FOLDER = 'prjf' + PROJECT_ID = 'prji' + PUBLIC_KEY = 'pubk' + QUERY = 'quer' + RECIPIENT = 'recp' + RECIPIENT_BCC = 'rebc' + RECIPIENT_CC = 'recc' + REPORT = 'rept' + REQUEST_ID = 'reqi' + RESOURCE_CALENDAR = 'resc' + RESOURCE_ID = 'resi' + ROLE = 'role' + ROW = 'row ' + SCOPE = 'scop' + SECTION = 'sect' + SENDAS_ADDRESS = 'sasa' + SENDER = 'send' + SERVICE = 'serv' + SHAREDDRIVE = 'tdrv' + SHAREDDRIVE_ACL = 'tdac' + SHAREDDRIVE_FOLDER = 'tdfo' + SHAREDDRIVE_ID = 'tdid' + SHAREDDRIVE_NAME = 'tdna' + SHAREDDRIVE_THEME = 'tdth' + SHEET = 'shet' + SHEET_ID = 'shti' + SIGNATURE = 'sign' + SIZE = 'size' + SKU = 'sku ' + SMIME_ID = 'smid' + SNIPPETS_ENABLED = 'snip' + SSO_KEY = 'ssok' + SSO_SETTINGS = 'ssos' + SOURCE_USER = 'srcu' + SPREADSHEET = 'sprd' + SPREADSHEET_RANGE = 'ssrn' + START_TIME = 'strt' + STATUS = 'stat' + STUDENT = 'stud' + SUBSCRIPTION = 'subs' + SVCACCT = 'svac' + SVCACCT_KEY = 'svky' + TAGMANAGER_ACCOUNT = 'tmac' + TAGMANAGER_CONTAINER = 'tmco' + TAGMANAGER_PERMISSION = 'tmpm' + TAGMANAGER_TAG = 'tmtg' + TAGMANAGER_WORKSPACE = 'tmws' + TARGET_USER = 'tgt ' + TASK = 'task' + TASKLIST = 'tali' + TEACHER = 'teac' + THREAD = 'thre' + TRANSFER_APPLICATION = 'trap' + TRANSFER_ID = 'trid' + TRANSFER_REQUEST = 'trnr' + TRASHED_EVENT = 'trev' + TRUSTED_APPLICATION = 'trus' + TYPE = 'type' + UNICODE_ENCODING_ENABLED = 'unic' + UNIQUE_ID = 'uniq' + URL = 'url ' + USER = 'user' + USER_ALIAS = 'uali' + USER_NOT_ARCHIVED = 'usna' + USER_ARCHIVED = 'usar' + USER_EMAIL = 'uema' + USER_INVITATION = 'uinv' + USER_NOT_SUSPENDED = 'usns' + USER_SUSPENDED = 'usup' + USER_SCHEMA = 'usch' + VACATION = 'vaca' + VACATION_ENABLED = 'vace' + VALUE = 'val' + VAULT_EXPORT = 'vlte' + VAULT_HOLD = 'vlth' + VAULT_MATTER = 'vltm' + VAULT_MATTER_ARTIFACT = 'vlma' + VAULT_MATTER_ID = 'vlmi' + VAULT_OPERATION = 'vlto' + VAULT_QUERY = 'vltq' + WEB_MASTERSITE = 'wems' + WEB_RESOURCE = 'were' + WEBCLIPS_ENABLED = 'webc' + YOUTUBE_CHANNEL = 'ytch' + # _NAMES[0] is plural, _NAMES[1] is singular unless the item name is explicitly plural (Calendar Settings) + # For items with Boolean values, both entries are singular (Forward, POP) + # These values can be translated into other languages + _NAMES = { + ACCESS_TOKEN: ['Access Tokens', 'Access Token'], + ACCOUNT: ['Google Workspace Accounts', 'Google Workspace Account'], + ACTION: ['Actions', 'Action'], + ACTIVITY: ['Activities', 'Activity'], + ADMINISTRATOR: ['Administrators', 'Administrator'], + ADMIN_ROLE: ['Admin Roles', 'Admin Role'], + ADMIN_ROLE_ASSIGNMENT: ['Admin Role Assignments', 'Admin Role Assignment'], + ALERT: ['Alerts', 'Alert'], + ALERT_ID: ['Alert IDs', 'Alert ID'], + ALERT_FEEDBACK: ['Alert Feedbacks', 'Alert Feedback'], + ALERT_FEEDBACK_ID: ['Alert Feedback IDs', 'Alert Feedback ID'], + ALERT_SETTINGS: ['Alert Settings', 'Alert Settings'], + ALIAS: ['Aliases', 'Alias'], + ALIAS_EMAIL: ['Alias Emails', 'Alias Email'], + ALIAS_TARGET: ['Alias Targets', 'Alias Target'], + ANALYTIC_ACCOUNT: ['Analytic Accounts', 'Analytic Account'], + ANALYTIC_ACCOUNT_SUMMARY: ['Analytic Account Summaries', 'Analytic Account Summary'], + ANALYTIC_DATASTREAM: ['Analytic Datastreams', 'Analytic Datastream'], + ANALYTIC_PROPERTY: ['Analytic GA4 Properties', 'Analytic GA4 Property'], + API: ['APIs', 'API'], + APP_ACCESS_SETTINGS: ['Application Access Settings', 'Application Access Settings'], + APP_ID: ['Application IDs', 'Application ID'], + APP_NAME: ['Application Names', 'Application Name'], + APPLICATION_SPECIFIC_PASSWORD: ['Application Specific Password IDs', 'Application Specific Password ID'], + ARROWS_ENABLED: ['Personal Indicator Arrows Enabled', 'Personal Indicator Arrows Enabled'], + ATTACHMENT: ['Attachments', 'Attachment'], + ATTENDEE: ['Attendees', 'Attendee'], + AUDIT_ACTIVITY_REQUEST: ['Audit Activity Requests', 'Audit Activity Request'], + AUDIT_EXPORT_REQUEST: ['Audit Export Requests', 'Audit Export Request'], + AUDIT_MONITOR_REQUEST: ['Audit Monitor Requests', 'Audit Monitor Request'], + BACKUP_VERIFICATION_CODES: ['Backup Verification Codes', 'Backup Verification Codes'], + BUILDING: ['Buildings', 'Building'], + BUILDING_ID: ['Building IDs', 'Building ID'], + BUSINESS_PROFILE_ACCOUNT: ['Business Profile Accounts', 'Business Profile Account'], + CAA_LEVEL: ['CAA Levels', 'CAA Level'], + CALENDAR: ['Calendars', 'Calendar'], + CALENDAR_ACL: ['Calendar ACLs', 'Calendar ACL'], + CALENDAR_SETTINGS: ['Calendar Settings', 'Calendar Settings'], + CHANNEL_CUSTOMER: ['Channel Customers', 'Channel Customer'], + CHANNEL_CUSTOMER_ENTITLEMENT: ['Channel Customer Entitlements', 'Channel Customer Entitlement'], + CHANNEL_OFFER: ['Channel Offers', 'Channel Offer'], + CHANNEL_PRODUCT: ['Channel Products', 'Channel Product'], + CHANNEL_SKU: ['Channel SKUs', 'Channel SKU'], + CHAT_BOT: ['Chat BOTs', 'Chat BOT'], + CHAT_ADMIN: ['Chat Admins', 'Chat Admin'], + CHAT_EMOJI: ['Chat Emojis', 'Chat Emoji'], + CHAT_EVENT: ['Chat Events', 'Chat Event'], + CHAT_MANAGER_USER: ['Chat User Managers', 'Chat User Manager'], + CHAT_MESSAGE: ['Chat Messages', 'Chat Message'], + CHAT_MESSAGE_ID: ['Chat Message IDs', 'Chat Message ID'], + CHAT_MEMBER: ['Chat Members', 'Chat Member'], + CHAT_MEMBER_GROUP: ['Chat Group Members', 'Chat Group Member'], + CHAT_MEMBER_USER: ['Chat User Members', 'Chat User Member'], + CHAT_OWNER_USER: ['Chat User Owners', 'Chat User Owner'], + CHAT_SECTION: ['Chat User Sections', 'Chat User Section'], + CHAT_SECTION_ITEM: ['Chat User Section Items', 'Chat User Section Item'], + CHAT_SPACE: ['Chat Spaces', 'Chat Space'], + CHAT_THREAD: ['Chat Threads', 'Chat Thread'], + CHILD_ORGANIZATIONAL_UNIT: ['Child Organizational Units', 'Child Organizational Unit'], + CHROME_APP: ['Chrome Applications', 'Chrome Application'], + CHROME_APP_DEVICE: ['Chrome Application Devices', 'Chrome Application Device'], + CHROME_BROWSER: ['Chrome Browsers', 'Chrome Browser'], + CHROME_BROWSER_ENROLLMENT_TOKEN: ['Chrome Browser Enrollment Tokens', 'Chrome Browser Enrollment Token'], + CHROME_CHANNEL: ['Chrome Channels', 'Chrome Channel'], + CHROME_DEVICE: ['Chrome Devices', 'Chrome Device'], + CHROME_DEVICE_COUNT: ['Chrome Device Counts', 'Chrome Device Count'], + CHROME_MODEL: ['Chrome Models', 'Chrome Model'], + CHROME_NETWORK_ID: ['Chrome Network IDs', 'Chrome Network ID'], + CHROME_NETWORK_NAME: ['Chrome Network Names', 'Chrome Network Name'], + CHROME_PLATFORM: ['Chrome Platforms', 'Chrome Platform'], + CHROME_POLICY: ['Chrome Policies', 'Chrome Policy'], + CHROME_POLICY_IMAGE: ['Chrome Policy Images', 'Chrome Policy Image'], + CHROME_POLICY_SCHEMA: ['Chrome Policy Schemas', 'Chrome Policy Schema'], + CHROME_PROFILE: ['Chrome Profiles', 'Chrome Profile'], + CHROME_PROFILE_COMMAND: ['Chrome Profile Commands', 'Chrome Profile Command'], + CHROME_RELEASE: ['Chrome Releases', 'Chrome Release'], + CHROME_VERSION: ['Chrome Versions', 'Chrome Version'], + CLASSIFICATION_LABEL: ['Classification Labels', 'Classification Label'], + CLASSIFICATION_LABEL_FIELD_ID: ['Classification Label Field IDs', 'Classification Label Field ID'], + CLASSIFICATION_LABEL_ID: ['Classification Label IDs', 'Classification Label ID'], + CLASSIFICATION_LABEL_NAME: ['Classification Label Names', 'Classification Label Name'], + CLASSIFICATION_LABEL_PERMISSION: ['Classification Label Permissions', 'Classification Label Permission'], + CLASSIFICATION_LABEL_PERMISSION_NAME: ['Classification Label Permission Names', 'Classification Label Permission Name'], + CLASSROOM_INVITATION: ['Classroom Invitations', 'Classroom Invitation'], + CLASSROOM_INVITATION_OWNER: ['Classroom Owner Invitations', 'Classroom Owner Invitation'], + CLASSROOM_INVITATION_STUDENT: ['Classroom Student Invitations', 'Classroom Student Invitation'], + CLASSROOM_INVITATION_TEACHER: ['Classroom Teacher Invitations', 'Classroom Teacher Invitation'], + CLASSROOM_OAUTH2_TXT_FILE: ['Classroom OAuth2 File', 'Classroom OAuth2 File'], + CLASSROOM_USER_PROFILE: ['Classroom User Profile', 'Classroom User Profile'], + CLIENT_ID: ['Client IDs', 'Client ID'], + CLIENT_SECRETS_JSON_FILE: ['Client Secrets File', 'Client Secrets File'], + CLOUD_IDENTITY_GROUP: ['Cloud Identity Groups', 'Cloud Identity Group'], + CLOUD_STORAGE_BUCKET: ['Cloud Storage Buckets', 'Cloud Storage Bucket'], + CLOUD_STORAGE_FILE: ['Cloud Storage Files', 'Cloud Storage File'], + COLLABORATOR: ['Collaborators', 'Collaborator'], + COMMAND_ID: ['Command IDs', 'Command ID'], + COMPANY_DEVICE: ['Company Devices', 'Company Device'], + CONFIG_FILE: ['Config File', 'Config File'], + CONTACT: ['Contacts', 'Contact'], + CONTACT_DELEGATE: ['Contact Delegates', 'Contact Delegate'], + CONTACT_GROUP: ['Contact Groups', 'Contact Group'], + CONTACT_GROUP_NAME: ['Contact Group Names', 'Contact Group Name'], + COPYFROM_COURSE: ['Copy From Courses', 'CopyFrom Course'], + COPYFROM_GROUP: ['Copy From Groups', 'CopyFrom Group'], + COURSE: ['Courses', 'Course'], + COURSE_ALIAS: ['Course Aliases', 'Course Alias'], + COURSE_ANNOUNCEMENT: ['Course Announcements', 'Course Announcement'], + COURSE_ANNOUNCEMENT_ID: ['Course Announcement IDs', 'Course Announcement ID'], + COURSE_ANNOUNCEMENT_STATE: ['Course Announcement States', 'Course Announcement State'], + COURSE_MATERIAL_DRIVEFILE: ['Course Material Drive Files', 'Course Material Drive File'], + COURSE_MATERIAL_FORM: ['Course Material Forms', 'Course Material Form'], + COURSE_MATERIAL: ['Course Materials', 'Course Material'], + COURSE_MATERIAL_ID: ['Course Material IDs', 'Course Material ID'], + COURSE_MATERIAL_STATE: ['Course Material States', 'Course Material State'], + COURSE_NAME: ['Course Names', 'Course Name'], + COURSE_STATE: ['Course States', 'Course State'], + COURSE_STUDENTGROUP: ['Course Student Groups', 'Course Student Group'], + COURSE_STUDENTGROUP_MEMBER: ['Course Student Group Members', 'Course Student Group Member'], + COURSE_SUBMISSION_ID: ['Course Submission IDs', 'Course Submission ID'], + COURSE_SUBMISSION_STATE: ['Course Submission States', 'Course Submission State'], + COURSE_TOPIC: ['Course Topics', 'Course Topic'], + COURSE_TOPIC_ID: ['Course Topic IDs', 'Course Topic ID'], + COURSE_WORK: ['Course Works', 'Course Work'], + COURSE_WORK_ID: ['Course Work IDs', 'Course Work ID'], + COURSE_WORK_STATE: ['Course Work States', 'Course Work State'], + CREATOR_ID: ['Creator IDs', 'Creator ID'], + CREDENTIALS: ['Credentials', 'Credentials'], + CRITERIA: ['Criteria', 'Criteria'], + CROS_DEVICE: ['CrOS Devices', 'CrOS Device'], + CROS_SERIAL_NUMBER: ['CrOS Serial Numbers', 'CrOS Serial Numbers'], + CSE_IDENTITY: ['CSE Identities', 'CSE Identity'], + CSE_KEYPAIR: ['CSE KeyPairs', 'CSE KeyPair'], + CUSTOMER_DOMAIN: ['Customer Domains', 'Customer Domain'], + CUSTOMER_ID: ['Customer IDs', 'Customer ID'], + DATE: ['Dates', 'Date'], + DEFAULT_LANGUAGE: ['Default Language', 'Default Language'], + DELEGATE: ['Delegates', 'Delegate'], + DELETED_USER: ['Deleted Users', 'Deleted User'], + DELIVERY: ['Delivery', 'Delivery'], + DEVICE: ['Devices', 'Device'], + DEVICE_FILE: ['Device Files', 'Device File'], + DEVICE_USER: ['Device Users', 'Device User'], + DEVICE_USER_CLIENT_STATE: ['Device Users Client States', 'Device User Client State'], + DIRECTORY: ['Directories', 'Directory'], + DISCOVERY_JSON_FILE: ['Discovery File', 'Discovery File'], + DOCUMENT: ['Documents', 'Document'], + DOMAIN: ['Domains', 'Domain'], + DOMAIN_ALIAS: ['Domain Aliases', 'Domain Alias'], + DOMAIN_CONTACT: ['Domain Contacts', 'Domain Contact'], + DOMAIN_PEOPLE_CONTACT: ['Domain People Contacts', 'Domain People Contact'], + DOMAIN_PROFILE: ['Domain Profiles', 'Domain Profile'], + DRIVE_DISK_USAGE: ['Drive Disk Usages', 'Drive Disk Usage'], + DRIVE_FILE: ['Drive Files', 'Drive File'], + DRIVE_FILE_COMMENT: ['Drive File Comments', 'Drive File Comment'], + DRIVE_FILE_ID: ['Drive File IDs', 'Drive File ID'], + DRIVE_FILE_NAME: ['Drive File Names', 'Drive File Name'], + DRIVE_FILE_REVISION: ['Drive File Revisions', 'Drive File Revision'], + DRIVE_FILE_RENAMED: ['Drive Files Renamed', 'Drive File Renamed'], + DRIVE_FILE_SHORTCUT: ['Drive File Shortcuts', 'Drive File Shortcut'], + DRIVE_FILE_OR_FOLDER: ['Drive Files/Folders', 'Drive File/Folder'], + DRIVE_FILE_OR_FOLDER_ACL: ['Drive File/Folder ACLs', 'Drive File/Folder ACL'], + DRIVE_FILE_OR_FOLDER_ID: ['Drive File/Folder IDs', 'Drive File/Folder ID'], + DRIVE_FOLDER: ['Drive Folders', 'Drive Folder'], + DRIVE_FOLDER_ID: ['Drive Folder IDs', 'Drive Folder ID'], + DRIVE_FOLDER_NAME: ['Drive Folder Names', 'Drive Folder Name'], + DRIVE_FOLDER_PATH: ['Drive Folder Paths', 'Drive Folder Path'], + DRIVE_FOLDER_RENAMED: ['Drive Folders Renamed', 'Drive Folder Renamed'], + DRIVE_FOLDER_SHORTCUT: ['Drive Folder Shortcuts', 'Drive Folder Shortcut'], + DRIVE_ORPHAN_FILE_OR_FOLDER: ['Drive Orphan Files/Folders', 'Drive Orphan File/Folder'], + DRIVE_PARENT_FOLDER: ['Drive Parent Folders', 'Drive Parent Folder'], + DRIVE_PARENT_FOLDER_ID: ['Drive Parent Folder IDs', 'Drive Parent Folder ID'], + DRIVE_PARENT_FOLDER_REFERENCE: ['Drive Parent Folder References', 'Drive Parent Folder Reference'], + DRIVE_PATH: ['Drive Paths', 'Drive Path'], + DRIVE_SETTINGS: ['Drive Settings', 'Drive Settings'], + DRIVE_SHORTCUT: ['Drive Shortcuts', 'Drive Shortcut'], + DRIVE_SHORTCUT_ID: ['Drive Shortcut IDs', 'Drive Shortcut ID'], + DRIVE_3PSHORTCUT: ['Drive 3rd Party Shortcuts', 'Drive 3rd Party Shortcut'], + DRIVE_TRASH: ['Drive Trash', 'Drive Trash'], + EMAIL: ['Email Addresses', 'Email Address'], + EMAIL_ALIAS: ['Email Aliases', 'Email Alias'], + EMAIL_SETTINGS: ['Email Settings', 'Email Settings'], + END_TIME: ['End Times', 'End Time'], + ENTITY: ['Entities', 'Entity'], + EVENT: ['Events', 'Event'], + EVENT_BIRTHDAY: ['Borthday Events', 'Birthday Event'], + EVENT_FOCUSTIME: ['Focus Time Events', 'Focus Time Event'], + EVENT_OUTOFOFFICE: ['Out of Office Events', 'Out of Office Event'], + EVENT_WORKINGLOCATION: ['Working Location Events', 'Working Location Event'], + FEATURE: ['Features', 'Feature'], + FIELD: ['Fields', 'Field'], + FILE: ['Files', 'File'], + FILE_PARENT_TREE: ['File Parent Trees', 'File Parent Tree'], + FILTER: ['Filters', 'Filter'], + FORM: ['Forms', 'Form'], + FORM_RESPONSE: ['Form Responses', 'Form Response'], + FORWARD_ENABLED: ['Forward Enabled', 'Forward Enabled'], + FORWARDING_ADDRESS: ['Forwarding Addresses', 'Forwarding Address'], + GCP_FOLDER: ['GCP Folders', 'GCP Folder'], + GCP_FOLDER_NAME: ['GCP Folder Names', 'GCP Folder Name'], + GCP_ORG_ID: ['GCP Organization ID', 'GCP Organization ID'], + GMAIL_PROFILE: ['Gmail Profile', 'Gmail Profile'], + GROUP: ['Groups', 'Group'], + GROUP_ALIAS: ['Group Aliases', 'Group Alias'], + GROUP_EMAIL: ['Group Emails', 'Group Email'], + GROUP_MEMBERSHIP: ['Group Memberships', 'Group Membership'], + GROUP_MEMBERSHIP_TREE: ['Group Membership Trees', 'Group Membership Tree'], + GROUP_SETTINGS: ['Group Settings', 'Group Settings'], + GROUP_TREE: ['Group Trees', 'Group Tree'], + GUEST_USER: ['Guest Users', 'Guest User'], + GUARDIAN: ['Guardians', 'Guardian'], + GUARDIAN_INVITATION: ['Guardian Invitations', 'Guardian Invitation'], + GUARDIAN_AND_INVITATION: ['Guardians and Invitations', 'Guardian and Invitation'], + IAM_POLICY: ['IAM Policies', 'IAM Policy'], + IMAP_ENABLED: ['IMAP Enabled', 'IMAP Enabled'], + INBOUND_SSO_ASSIGNMENT: ['Inbound SSO Assignments', 'Inbound SSO Assignment'], + INBOUND_SSO_CREDENTIALS: ['Inbound SSO Credentials', 'Inbound SSO Credential'], + INBOUND_SSO_PROFILE: ['Inbound SSO Profiles', 'Inbound SSO Profile'], + INSTANCE: ['Instances', 'Instance'], + ISSUER_CN: ['Issuer CNs', 'Issuer CN'], + ITEM: ['Items', 'Item'], + KEYBOARD_SHORTCUTS_ENABLED: ['Keyboard Shortcuts Enabled', 'Keyboard Shortcuts Enabled'], + LABEL: ['Labels', 'Label'], + LABEL_ID: ['Label IDs', 'Label ID'], + LANGUAGE: ['Languages', 'Language'], + LICENSE: ['Licenses', 'License'], + LOCATION: ['Locations', 'Location'], + LOOKERSTUDIO_ASSET: ['Looker Studio Assets', 'Looker Studio Asset'], + LOOKERSTUDIO_ASSET_DATASOURCE: ['Looker Studio DATA_SOURCE Assets', 'Looker Studio DATA_SOURCE Asset'], + LOOKERSTUDIO_ASSETID: ['Looker Studio Asset IDs', 'Looker Studio Asset ID'], + LOOKERSTUDIO_ASSET_REPORT: ['Looker Studio REPORT Assets', 'Looker Studio REPORT Asset'], + LOOKERSTUDIO_PERMISSION: ['Looker Studio Permissions', 'Looker Studio Permission'], + MD5HASH: ['MD5 hash', 'MD5 Hash'], + MEET_SPACE: ['Meet Spaces', 'Meet Space'], + MEET_CONFERENCE: ['Meet Conferences', 'Meet Conference'], + MEET_PARTICIPANT: ['Meet Participants', 'Meet Participant'], + MEET_RECORDING: ['Meet Recordings', 'Meet Recording'], + MEET_TRANSCRIPT: ['Meet Transcripts', 'Meet Transcript'], + MEMBER: ['Members', 'Member'], + MEMBER_NOT_ARCHIVED: ['Members (Not Archived)', 'Member (Not Archived)'], + MEMBER_ARCHIVED: ['Members (Archived)', 'Member (Archived)'], + MEMBER_NOT_SUSPENDED: ['Members (Not Suspended)', 'Member (Not Suspended)'], + MEMBER_SUSPENDED: ['Members (Suspended)', 'Member (Suspended)'], + MEMBER_NOT_SUSPENDED_NOT_ARCHIVED: ['Members (Not Suspended & Not Archived)', 'Member (Not Suspended & Not Archived)'], + MEMBER_SUSPENDED_ARCHIVED: ['Members (Suspended & Archived)', 'Member (Suspended & Archived)'], + MEMBER_RESTRICTION: ['Member Restrictions', 'Member Restriction'], + MEMBER_URI: ['Member URIs', 'Member URI'], + MEMBERSHIP_TREE: ['Membership Trees', 'Membership Tree'], + MESSAGE: ['Messages', 'Message'], + MIMETYPE: ['MIME Types', 'MIME Type'], + MOBILE_DEVICE: ['Mobile Devices', 'Mobile Device'], + NAME: ['Names', 'Name'], + NONEDITABLE_ALIAS: ['Non-Editable Aliases', 'Non-Editable Alias'], + NOTE: ['Notes', 'Note'], + NOTE_ACL: ['Note ACLs', 'Note ACL'], + NOTES_ACLS: ["'Note's ACLs", "Note's ACLs"], + NOTIFICATION: ['Notifications', 'Notification'], + OAUTH2_TXT_FILE: ['Client OAuth2 File', 'Client OAuth2 File'], + OAUTH2SERVICE_JSON_FILE: ['Service Account OAuth2 File', 'Service Account OAuth2 File'], + ORGANIZATIONAL_UNIT: ['Organizational Units', 'Organizational Unit'], + OTHER_CONTACT: ['Other Contacts', 'Other Contact'], + OWNER: ['Owners', 'Owner'], + OWNER_ID: ['Owner IDs', 'Owner ID'], + PAGE_SIZE: ['Page Size', 'Page Size'], + PARENT_ORGANIZATIONAL_UNIT: ['Parent Organizational Units', 'Parent Organizational Unit'], + PARTICIPANT: ['Participants', 'Participant'], + PEOPLE_CONTACT: ['People Contacts', 'Person Contact'], + PEOPLE_CONTACT_GROUP: ['People Contact Groups', 'People Contact Group'], + PEOPLE_PHOTO: ['People Photos', 'Person Photo'], + PEOPLE_PROFILE: ['People Profiles', 'People Profile'], + PERMISSION: ['Permissions', 'Permission'], + PERMISSION_ID: ['Permission IDs', 'Permission ID'], + PERMITTEE: ['Permittees', 'Permittee'], + PERSONAL_DEVICE: ['Personal Devices', 'Personal Device'], + PHOTO: ['Photos', 'Photo'], + POLICY: ['Policies', 'Policy'], + POP_ENABLED: ['POP Enabled', 'POP Enabled'], + PRESENTATION: ['Presentations', 'Presentation'], + PRINTER: ['Printers', 'Printer'], + PRINTER_ID: ['Printer IDs', 'Printer ID'], + PRINTER_MODEL: ['Printer Models', 'Printer Model'], + PRIVILEGE: ['Privileges', 'Privilege'], + PRODUCT: ['Products', 'Product'], + PROFILE_SHARING_ENABLED: ['Profile Sharing Enabled', 'Profile Sharing Enabled'], + PROJECT: ['Projects', 'Project'], + PROJECT_FOLDER: ['Project Folders', 'Project Folder'], + PROJECT_ID: ['Project IDs', 'Project ID'], + PUBLIC_KEY: ['Public Key', 'Public Key'], + QUERY: ['Queries', 'Query'], + RECIPIENT: ['Recipients', 'Recipient'], + RECIPIENT_BCC: ['Recipients (BCC)', 'Recipient (BCC)'], + RECIPIENT_CC: ['Recipients (CC)', 'Recipient (CC)'], + REPORT: ['Reports', 'Report'], + REQUEST_ID: ['Request IDs', 'Request ID'], + RESOURCE_CALENDAR: ['Resource Calendars', 'Resource Calendar'], + RESOURCE_ID: ['Resource IDs', 'Resource ID'], + ROLE: ['Roles', 'Role'], + ROW: ['Rows', 'Row'], + SCOPE: ['Scopes', 'Scope'], + SECTION: ['Sections', 'Section'], + SENDAS_ADDRESS: ['SendAs Addresses', 'SendAs Address'], + SENDER: ['Senders', 'Sender'], + SERVICE: ['Services', 'Service'], + SHAREDDRIVE: ['Shared Drives', 'Shared Drive'], + SHAREDDRIVE_ACL: ['Shared Drive ACLs', 'Shared Drive ACL'], + SHAREDDRIVE_FOLDER: ['Shared Drive Folders', 'Shared Drive Folder'], + SHAREDDRIVE_ID: ['Shared Drive IDs', 'Shared Drive ID'], + SHAREDDRIVE_NAME: ['Shared Drive Names', 'Shared Drive Name'], + SHAREDDRIVE_THEME: ['Shared Drive Themes', 'Shared Drive Theme'], + SHEET: ['Sheets', 'Sheet'], + SHEET_ID: ['Sheet IDs', 'Sheet ID'], + SIGNATURE: ['Signatures', 'Signature'], + SIZE: ['Sizes', 'Size'], + SKU: ['SKUs', 'SKU'], + SMIME_ID: ['S/MIME Certificate IDs', 'S/MIME Certificate ID'], + SNIPPETS_ENABLED: ['Preview Snippets Enabled', 'Preview Snippets Enabled'], + SSO_KEY: ['SSO Key', 'SSO Key'], + SSO_SETTINGS: ['SSO Settings', 'SSO Settings'], + SOURCE_USER: ['Source Users', 'Source User'], + SPREADSHEET: ['Spreadsheets', 'Spreadsheet'], + SPREADSHEET_RANGE: ['Spreadsheet Ranges', 'Spreadsheet Range'], + START_TIME: ['Start Times', 'Start Time'], + STATUS: ['Status', 'Status'], + STUDENT: ['Students', 'Student'], + SUBSCRIPTION: ['Subscriptions', 'Subscription'], + SVCACCT: ['Service Accounts', 'Service Account'], + SVCACCT_KEY: ['Service Account Keys', 'Service Account Key'], + TAGMANAGER_ACCOUNT: ['Tag Manager Accounts', 'Tag Manager Account'], + TAGMANAGER_CONTAINER: ['Tag Manager Containers', 'Tag Manager Container'], + TAGMANAGER_PERMISSION: ['Tag Manager Permissions', 'Tag Manager Permission'], + TAGMANAGER_TAG: ['Tag Manager Tags', 'Tag Manager Tag'], + TAGMANAGER_WORKSPACE: ['Tag Manager Workspaces', 'Tag Manager Workspace'], + TARGET_USER: ['Target Users', 'Target User'], + TASK: ['Tasks', 'Task'], + TASKLIST: ['Tasklists', 'Tasklist'], + TEACHER: ['Teachers', 'Teacher'], + THREAD: ['Threads', 'Thread'], + TRANSFER_APPLICATION: ['Transfer Applications', 'Transfer Application'], + TRANSFER_ID: ['Transfer IDs', 'Transfer ID'], + TRANSFER_REQUEST: ['Transfer Requests', 'Transfer Request'], + TRASHED_EVENT: ['Trashed Events', 'Trashed Event'], + TRUSTED_APPLICATION: ['Trusted Applications', 'Trusted Application'], + TYPE: ['Types', 'Type'], + UNICODE_ENCODING_ENABLED: ['UTF-8 Encoding Enabled', 'UTF-8 Encoding Enabled'], + UNIQUE_ID: ['Unique IDs', 'Unique ID'], + URL: ['URLs', 'URL'], + USER: ['Users', 'User'], + USER_ALIAS: ['User Aliases', 'User Alias'], + USER_NOT_ARCHIVED: ['Users (Not archived)', 'User (Not archived)'], + USER_ARCHIVED: ['Users (Archived)', 'User (Archived)'], + USER_EMAIL: ['User Emails', 'User Email'], + USER_INVITATION: ['User Invitations', 'User Invitation'], + USER_NOT_SUSPENDED: ['Users (Not suspended)', 'User (Not suspended)'], + USER_SUSPENDED: ['Users (Suspended)', 'User (Suspended)'], + USER_SCHEMA: ['Schemas', 'Schema'], + VACATION: ['Vacation', 'Vacation'], + VACATION_ENABLED: ['Vacation Enabled', 'Vacation Enabled'], + VALUE: ['Values', 'Value'], + VAULT_EXPORT: ['Vault Exports', 'Vault Export'], + VAULT_HOLD: ['Vault Holds', 'Vault Hold'], + VAULT_MATTER: ['Vault Matters', 'Vault Matter'], + VAULT_MATTER_ARTIFACT: ['Vault Matter Artifacts', 'Vault Matter Artifact'], + VAULT_MATTER_ID: ['Vault Matter IDs', 'Vault Matter ID'], + VAULT_OPERATION: ['Vault Operations', 'Vault Operation'], + VAULT_QUERY: ['Vault Queries', 'Vault Query'], + WEBCLIPS_ENABLED: ['Web Clips Enabled', 'Web Clips Enabled'], + WEB_MASTERSITE: ['Web Master Sites', 'Web Master Site'], + WEB_RESOURCE: ['Web Resources', 'Web Resource'], + YOUTUBE_CHANNEL: ['YouTube Channels', 'YouTube Channel'], + ROLE_MANAGER: ['Managers', 'Manager'], + ROLE_MEMBER: ['Members', 'Member'], + ROLE_OWNER: ['Owners', 'Owner'], + ROLE_ALL: ['Members, Managers, Owners', 'Member, Manager, Owner'], + ROLE_USER: ['Users', 'User'], + ROLE_MANAGER_MEMBER: ['Members, Managers', 'Member, Manager'], + ROLE_MANAGER_OWNER: ['Managers, Owners', 'Manager, Owner'], + ROLE_MEMBER_OWNER: ['Members, Owners', 'Member, Owner'], + ROLE_MANAGER_MEMBER_OWNER: ['Members, Managers, Owners', 'Member, Manager, Owner'], + ROLE_PUBLIC: ['Public', 'Public'], + } + + # Shared state across all instances (class-level) + _entityType = None + _forWhom = None + _preQualifier = '' + _postQualifier = '' + + @property + def entityType(self): + return GamEntity._entityType + @entityType.setter + def entityType(self, value): + GamEntity._entityType = value + + @property + def forWhom(self): + return GamEntity._forWhom + @forWhom.setter + def forWhom(self, value): + GamEntity._forWhom = value + + @property + def preQualifier(self): + return GamEntity._preQualifier + @preQualifier.setter + def preQualifier(self, value): + GamEntity._preQualifier = value + + @property + def postQualifier(self): + return GamEntity._postQualifier + @postQualifier.setter + def postQualifier(self, value): + GamEntity._postQualifier = value + + def __init__(self): + pass # state is shared at class level + + def SetGetting(self, entityType): + GamEntity._entityType = entityType + GamEntity._preQualifier = GamEntity._postQualifier = '' + + def SetGettingQuery(self, entityType, query): + GamEntity._entityType = entityType + GamEntity._preQualifier = f' that match query ({query})' + GamEntity._postQualifier = f' that matched query ({query})' + + def SetGettingQualifier(self, entityType, qualifier): + GamEntity._entityType = entityType + GamEntity._preQualifier = GamEntity._postQualifier = qualifier + + def Getting(self): + return GamEntity._entityType + + def GettingPreQualifier(self): + return GamEntity._preQualifier + + def GettingPostQualifier(self): + return GamEntity._postQualifier + + def SetGettingForWhom(self, forWhom): + GamEntity._forWhom = forWhom + + def GettingForWhom(self): + return GamEntity._forWhom + + def Choose(self, entityType, count): + return self._NAMES[entityType][[0, 1][count == 1]] + + def ChooseGetting(self, count): + return self._NAMES[self.entityType][[0, 1][count == 1]] + + def Plural(self, entityType): + return self._NAMES[entityType][0] + + def PluralGetting(self): + return self._NAMES[GamEntity._entityType][0] + + def Singular(self, entityType): + return self._NAMES[entityType][1] + + def SingularGetting(self): + return self._NAMES[GamEntity._entityType][1] + + def MayTakeTime(self, entityType): + if entityType: + return f', may take some time on a large {self.Singular(entityType)}...' + return '' + + def FormatEntityValueList(self, entityValueList): + evList = [] + for j in range(0, len(entityValueList), 2): + evList.append(self.Singular(entityValueList[j])) + evList.append(entityValueList[j+1]) + return evList + + def TypeMessage(self, entityType, message): + return f'{self.Singular(entityType)}: {message}' + + def TypeName(self, entityType, entityName): + return f'{self.Singular(entityType)}: {entityName}' + + def TypeNameMessage(self, entityType, entityName, message): + return f'{self.Singular(entityType)}: {entityName} {message}' diff --git a/src/gam/gamlib/gapi.py b/src/gam/gamlib/gapi.py new file mode 100644 index 00000000..f9b0f2af --- /dev/null +++ b/src/gam/gamlib/gapi.py @@ -0,0 +1,866 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM GAPI resources + +""" +# callGAPI throw reasons +ABORTED = 'aborted' +ABUSIVE_CONTENT_RESTRICTION = 'abusiveContentRestriction' +ACCESS_NOT_CONFIGURED = 'accessNotConfigured' +ADMIN_CANNOT_UNSUSPEND = 'adminCannotUnsuspend' +ALREADY_EXISTS = 'alreadyExists' +APPLY_LABEL_FORBIDDEN = 'applyLabelForbidden' +AUTH_ERROR = 'authError' +BACKEND_ERROR = 'backendError' +BAD_GATEWAY = 'badGateway' +BAD_REQUEST = 'badRequest' +CANNOT_ADD_PARENT = 'cannotAddParent' +CANNOT_CHANGE_ORGANIZER = 'cannotChangeOrganizer' +CANNOT_CHANGE_ORGANIZER_OF_INSTANCE = 'cannotChangeOrganizerOfInstance' +CANNOT_CHANGE_OWN_ACL = 'cannotChangeOwnAcl' +CANNOT_CHANGE_OWNER_ACL = 'cannotChangeOwnerAcl' +CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION = 'cannotChangeOwnPrimarySubscription' +CANNOT_COPY_FILE = 'cannotCopyFile' +CANNOT_DELETE_ONLY_REVISION = 'cannotDeleteOnlyRevision' +CANNOT_DELETE_PERMISSION = 'cannotDeletePermission' +CANNOT_DELETE_PRIMARY_CALENDAR = 'cannotDeletePrimaryCalendar' +CANNOT_DELETE_PRIMARY_SENDAS = 'cannotDeletePrimarySendAs' +CANNOT_DELETE_RESOURCE_WITH_CHILDREN = 'cannotDeleteResourceWithChildren' +CANNOT_MODIFY_ACL_OF_CALENDAR_OWNER = 'cannotModifyAclOfCalendarOwner' +CANNOT_MODIFY_INHERITED_PERMISSION = 'cannotModifyInheritedPermission' +CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION = 'cannotModifyInheritedTeamDrivePermission' +CANNOT_MODIFY_RESTRICTED_LABEL = 'cannotModifyRestrictedLabel' +CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT = 'cannotModifyViewersCanCopyContent' +CANNOT_MOVE_TRASHED_ITEM_INTO_TEAMDRIVE = 'cannotMoveTrashedItemIntoTeamDrive' +CANNOT_MOVE_TRASHED_ITEM_OUT_OF_TEAMDRIVE = 'cannotMoveTrashedItemOutOfTeamDrive' +CANNOT_REMOVE_OWNER = 'cannotRemoveOwner' +CANNOT_SET_EXPIRATION = 'cannotSetExpiration' +CANNOT_SET_EXPIRATION_ON_ANYONE_OR_DOMAIN = 'cannotSetExpirationOnAnyoneOrDomain' +CANNOT_SHARE_GROUPS_WITHLINK = 'cannotShareGroupsWithLink' +CANNOT_SHARE_USERS_WITHLINK = 'cannotShareUsersWithLink' +CANNOT_SHARE_TEAMDRIVE_TOPFOLDER_WITH_ANYONEORDOMAINS = 'cannotShareTeamDriveTopFolderWithAnyoneOrDomains' +CANNOT_SHARE_TEAMDRIVE_WITH_NONGOOGLE_ACCOUNTS = 'cannotShareTeamDriveWithNonGoogleAccounts' +CANNOT_UNSUBSCRIBE_FROM_OWNED_CALENDAR = 'cannotUnsubscribeFromOwnedCalendar' +CANNOT_UPDATE_PERMISSION = 'cannotUpdatePermission' +CONDITION_NOT_MET = 'conditionNotMet' +CONFLICT = 'conflict' +CONTENT_OWNER_ACCOUNT_NOT_FOUND = 'contentOwnerAccountNotFound' +CROSS_DOMAIN_MOVE_RESTRICTION = 'crossDomainMoveRestriction' +CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT = 'CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT' +CUSTOMER_NOT_FOUND = 'customerNotFound' +CYCLIC_MEMBERSHIPS_NOT_ALLOWED = 'cyclicMembershipsNotAllowed' +DAILY_LIMIT_EXCEEDED = 'dailyLimitExceeded' +DELETED = 'deleted' +DELETED_USER_NOT_FOUND = 'deletedUserNotFound' +DOMAIN_ALIAS_NOT_FOUND = 'domainAliasNotFound' +DOMAIN_CANNOT_USE_APIS = 'domainCannotUseApis' +DOMAIN_NOT_FOUND = 'domainNotFound' +DOMAIN_NOT_VERIFIED_SECONDARY = 'domainNotVerifiedSecondary' +DOMAIN_POLICY = 'domainPolicy' +DOWNLOAD_QUOTA_EXCEEDED = 'downloadQuotaExceeded' +DUPLICATE = 'duplicate' +EVENT_DURATION_EXCEEDS_LIMIT = 'eventDurationExceedsLimit' +EVENT_TYPE_RESTRICTION = 'eventTypeRestriction' +EXPIRATION_DATES_MUST_BE_IN_THE_FUTURE = 'expirationDatesMustBeInTheFuture' +EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS = 'expirationDateNotAllowedForSharedDriveMembers' +FAILED_PRECONDITION = 'failedPrecondition' +FIELD_IN_USE = 'fieldInUse' +FIELD_NOT_WRITABLE = 'fieldNotWritable' +FILE_NEVER_WRITABLE = 'fileNeverWritable' +FILE_NOT_FOUND = 'fileNotFound' +FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE = 'fileOrganizerNotYetEnabledForThisTeamDrive' +FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY = 'fileOrganizerOnFoldersInSharedDriveOnly' +FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED = 'fileOrganizerOnNonTeamDriveNotSupported' +FILE_OWNER_NOT_MEMBER_OF_TEAMDRIVE = 'fileOwnerNotMemberOfTeamDrive' +FILE_OWNER_NOT_MEMBER_OF_WRITER_DOMAIN = 'fileOwnerNotMemberOfWriterDomain' +FILE_WRITER_TEAMDRIVE_MOVE_IN_DISABLED = 'fileWriterTeamDriveMoveInDisabled' +FORBIDDEN = 'forbidden' +GATEWAY_TIMEOUT = 'gatewayTimeout' +GROUP_NOT_FOUND = 'groupNotFound' +ILLEGAL_ACCESS_ROLE_FOR_DEFAULT = 'illegalAccessRoleForDefault' +INSUFFICIENT_ADMINISTRATOR_PRIVILEGES = 'insufficientAdministratorPrivileges' +INSUFFICIENT_ARCHIVED_USER_LICENSES = 'insufficientArchivedUserLicenses' +INSUFFICIENT_FILE_PERMISSIONS = 'insufficientFilePermissions' +INSUFFICIENT_PARENT_PERMISSIONS = 'insufficientParentPermissions' +INSUFFICIENT_PERMISSIONS = 'insufficientPermissions' +INTERNAL_ERROR = 'internalError' +INVALID = 'invalid' +INVALID_ARGUMENT = 'invalidArgument' +INVALID_ATTRIBUTE_VALUE = 'invalidAttributeValue' +INVALID_CUSTOMER_ID = 'invalidCustomerId' +INVALID_INPUT = 'invalidInput' +INVALID_LINK_VISIBILITY = 'invalidLinkVisibility' +INVALID_MEMBER = 'invalidMember' +INVALID_MESSAGE_ID = 'invalidMessageId' +INVALID_ORGUNIT = 'invalidOrgunit' +INVALID_ORGUNIT_NAME = 'invalidOrgunitName' +INVALID_OWNERSHIP_TRANSFER = 'invalidOwnershipTransfer' +INVALID_PARAMETER = 'invalidParameter' +INVALID_PARENT_ORGUNIT = 'invalidParentOrgunit' +INVALID_QUERY = 'invalidQuery' +INVALID_RESOURCE = 'invalidResource' +INVALID_SCHEMA_VALUE = 'invalidSchemaValue' +INVALID_SCOPE_VALUE = 'invalidScopeValue' +INVALID_SHARING_REQUEST = 'invalidSharingRequest' +LABEL_MULTIPLE_VALUES_FOR_SINGULAR_FIELD = 'labelMultipleValuesForSingularField' +LABEL_MUTATION_FORBIDDEN = 'labelMutationForbidden' +LABEL_MUTATION_ILLEGAL_SELECTION = 'labelMutationIllegalSelection' +LABEL_MUTATION_UNKNOWN_FIELD = 'labelMutationUnknownField' +LIMIT_EXCEEDED = 'limitExceeded' +LOGIN_REQUIRED = 'loginRequired' +MALFORMED_WORKING_LOCATION_EVENT = 'malformedWorkingLocationEvent' +MEMBER_NOT_FOUND = 'memberNotFound' +MYDRIVE_HIERARCHY_DEPTH_LIMIT_EXCEEDED = 'myDriveHierarchyDepthLimitExceeded' +NO_LIST_TEAMDRIVES_ADMINISTRATOR_PRIVILEGE = 'noListTeamDrivesAdministratorPrivilege' +NO_MANAGE_TEAMDRIVE_ADMINISTRATOR_PRIVILEGE = 'noManageTeamDriveAdministratorPrivilege' +NOT_A_CALENDAR_USER = 'notACalendarUser' +NOT_FOUND = 'notFound' +NOT_IMPLEMENTED = 'notImplemented' +NUM_CHILDREN_IN_NON_ROOT_LIMIT_EXCEEDED = 'numChildrenInNonRootLimitExceeded' +OPERATION_NOT_SUPPORTED = 'operationNotSupported' +ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED = 'organizerOnNonTeamDriveNotSupported' +ORGANIZER_ON_NON_TEAMDRIVE_ITEM_NOT_SUPPORTED = 'organizerOnNonTeamDriveItemNotSupported' +ORGUNIT_NOT_FOUND = 'orgunitNotFound' +OUTSIDE_DOMAIN_MEMBER_CANNOT_CHANGE_TEAMDRIVE_RESTRICTIONS = 'outsideDomainMemberCannotChangeTeamDriveRestrictions' +OWNER_ON_TEAMDRIVE_ITEM_NOT_SUPPORTED = 'ownerOnTeamDriveItemNotSupported' +OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED = 'ownershipChangeAcrossDomainNotPermitted' +PARTICIPANT_IS_NEITHER_ORGANIZER_NOR_ATTENDEE = 'participantIsNeitherOrganizerNorAttendee' +PERMISSION_DENIED = 'permissionDenied' +PERMISSION_NOT_FOUND = 'permissionNotFound' +PHOTO_NOT_FOUND = 'photoNotFound' +PUBLISH_OUT_NOT_PERMITTED = 'publishOutNotPermitted' +QUERY_REQUIRES_ADMIN_CREDENTIALS = 'queryRequiresAdminCredentials' +QUOTA_EXCEEDED = 'quotaExceeded' +RATE_LIMIT_EXCEEDED = 'rateLimitExceeded' +REQUIRED = 'required' +REQUIRED_ACCESS_LEVEL = 'requiredAccessLevel' +RESOURCE_EXHAUSTED = 'resourceExhausted' +RESOURCE_ID_NOT_FOUND = 'resourceIdNotFound' +RESOURCE_NOT_FOUND = 'resourceNotFound' +RESPONSE_PREPARATION_FAILURE = 'responsePreparationFailure' +REVISION_DELETION_NOT_SUPPORTED = 'revisionDeletionNotSupported' +REVISION_NOT_FOUND = 'revisionNotFound' +REVISIONS_NOT_SUPPORTED = 'revisionsNotSupported' +SERVICE_LIMIT = 'serviceLimit' +SERVICE_NOT_AVAILABLE = 'serviceNotAvailable' +SHARE_IN_NOT_PERMITTED = 'shareInNotPermitted' +SHARE_OUT_NOT_PERMITTED = 'shareOutNotPermitted' +SHARE_OUT_NOT_PERMITTED_TO_USER = 'shareOutNotPermittedToUser' +SHARE_OUT_WARNING = 'shareOutWarning' +SHARING_RATE_LIMIT_EXCEEDED = 'sharingRateLimitExceeded' +SHORTCUT_TARGET_INVALID = 'shortcutTargetInvalid' +STORAGE_QUOTA_EXCEEDED = 'storageQuotaExceeded' +SYSTEM_ERROR = 'systemError' +TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION = 'targetUserRoleLimitedByLicenseRestriction' +TEAMDRIVE_ALREADY_EXISTS = 'teamDriveAlreadyExists' +TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION = 'teamDriveDomainUsersOnlyRestriction' +TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION = 'teamDriveTeamMembersOnlyRestriction' +TEAMDRIVE_FILE_LIMIT_EXCEEDED = 'teamDriveFileLimitExceeded' +TEAMDRIVE_HIERARCHY_TOO_DEEP = 'teamDriveHierarchyTooDeep' +TEAMDRIVE_MEMBERSHIP_REQUIRED = 'teamDriveMembershipRequired' +TEAMDRIVES_FOLDER_MOVE_IN_NOT_SUPPORTED = 'teamDrivesFolderMoveInNotSupported' +TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED = 'teamDrivesFolderSharingNotSupported' +TEAMDRIVES_PARENT_LIMIT = 'teamDrivesParentLimit' +TEAMDRIVES_SHARING_RESTRICTION_NOT_ALLOWED = 'teamDrivesSharingRestrictionNotAllowed' +TEAMDRIVES_SHORTCUT_FILE_NOT_SUPPORTED = 'teamDrivesShortcutFileNotSupported' +TIME_RANGE_EMPTY = 'timeRangeEmpty' +TRANSIENT_ERROR = 'transientError' +UNIMPLEMENTED_ERROR = 'unimplementedError' +UNKNOWN_ERROR = 'unknownError' +UNSUPPORTED_LANGUAGE_CODE = 'unsupportedLanguageCode' +UNSUPPORTED_SUPERVISED_ACCOUNT = 'unsupportedSupervisedAccount' +UPLOAD_TOO_LARGE = 'uploadTooLarge' +USER_CANNOT_CREATE_TEAMDRIVES = 'userCannotCreateTeamDrives' +USER_ACCESS = 'userAccess' +USER_NOT_FOUND = 'userNotFound' +USER_RATE_LIMIT_EXCEEDED = 'userRateLimitExceeded' +# +DEFAULT_RETRY_REASONS = [QUOTA_EXCEEDED, RATE_LIMIT_EXCEEDED, SHARING_RATE_LIMIT_EXCEEDED, USER_RATE_LIMIT_EXCEEDED, + BACKEND_ERROR, BAD_GATEWAY, GATEWAY_TIMEOUT, INTERNAL_ERROR, TRANSIENT_ERROR] +SERVICE_NOT_AVAILABLE_RETRY_REASONS = [SERVICE_NOT_AVAILABLE] +ACTIVITY_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST] +ALERT_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, PERMISSION_DENIED] +CALENDAR_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, NOT_A_CALENDAR_USER] +CIGROUP_CREATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, ALREADY_EXISTS, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED, FAILED_PRECONDITION] +CIGROUP_GET_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, INVALID_ARGUMENT, SYSTEM_ERROR, PERMISSION_DENIED] +CIGROUP_LIST_THROW_REASONS = [SERVICE_NOT_AVAILABLE, RESOURCE_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, INVALID_ARGUMENT, SYSTEM_ERROR, PERMISSION_DENIED] +CIGROUP_LIST_USERKEY_THROW_REASONS = CIGROUP_LIST_THROW_REASONS+[INVALID_ARGUMENT] +CIGROUP_UPDATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, + FORBIDDEN, BAD_REQUEST, INVALID, INVALID_INPUT, INVALID_ARGUMENT, + SYSTEM_ERROR, PERMISSION_DENIED, FAILED_PRECONDITION] +CIGROUP_RETRY_REASONS = [INVALID, SYSTEM_ERROR, SERVICE_NOT_AVAILABLE] +CIMEMBERS_THROW_REASONS = [SERVICE_NOT_AVAILABLE, MEMBER_NOT_FOUND, INVALID_MEMBER] +CISSO_CREATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, FAILED_PRECONDITION, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_ARGUMENT, PERMISSION_DENIED, INTERNAL_ERROR] +CISSO_GET_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR] +CISSO_LIST_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR] +CISSO_UPDATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, NOT_FOUND, FAILED_PRECONDITION, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, + FORBIDDEN, BAD_REQUEST, INVALID, INVALID_INPUT, INVALID_ARGUMENT, + SYSTEM_ERROR, PERMISSION_DENIED, INTERNAL_ERROR] +CONTACT_DELEGATE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, FAILED_PRECONDITION, PERMISSION_DENIED, FORBIDDEN, INVALID_ARGUMENT] +COURSE_ACCESS_THROW_REASONS = [NOT_FOUND, INSUFFICIENT_PERMISSIONS, PERMISSION_DENIED, FORBIDDEN, INVALID_ARGUMENT] +DRIVE_USER_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, DOMAIN_POLICY] +DRIVE_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, INSUFFICIENT_FILE_PERMISSIONS, UNKNOWN_ERROR, INVALID] +DRIVE_COPY_THROW_REASONS = DRIVE_ACCESS_THROW_REASONS+[CANNOT_COPY_FILE, BAD_REQUEST, RESPONSE_PREPARATION_FAILURE, TEAMDRIVES_SHARING_RESTRICTION_NOT_ALLOWED, + FIELD_NOT_WRITABLE, RATE_LIMIT_EXCEEDED, USER_RATE_LIMIT_EXCEEDED, + STORAGE_QUOTA_EXCEEDED, TEAMDRIVE_FILE_LIMIT_EXCEEDED, TEAMDRIVE_HIERARCHY_TOO_DEEP] +DRIVE_GET_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, DOWNLOAD_QUOTA_EXCEEDED] +DRIVE3_CREATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID, INVALID_SHARING_REQUEST, OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED, + CANNOT_SET_EXPIRATION, CANNOT_SET_EXPIRATION_ON_ANYONE_OR_DOMAIN, + EXPIRATION_DATES_MUST_BE_IN_THE_FUTURE, EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS, + NOT_FOUND, TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION, TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION, + TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED, + PUBLISH_OUT_NOT_PERMITTED, SHARE_IN_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED_TO_USER, + CANNOT_SHARE_TEAMDRIVE_TOPFOLDER_WITH_ANYONEORDOMAINS, + CANNOT_SHARE_TEAMDRIVE_WITH_NONGOOGLE_ACCOUNTS, + OWNER_ON_TEAMDRIVE_ITEM_NOT_SUPPORTED, + ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, + ORGANIZER_ON_NON_TEAMDRIVE_ITEM_NOT_SUPPORTED, + FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE, + FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY, + FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, + CANNOT_MODIFY_INHERITED_PERMISSION, + TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED, INVALID_LINK_VISIBILITY, ABUSIVE_CONTENT_RESTRICTION] +DRIVE3_GET_ACL_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, + INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS, + UNKNOWN_ERROR, INVALID] +DRIVE3_UPDATE_ACL_THROW_REASONS = [BAD_REQUEST, INVALID_OWNERSHIP_TRANSFER, CANNOT_REMOVE_OWNER, + CANNOT_SET_EXPIRATION, CANNOT_SET_EXPIRATION_ON_ANYONE_OR_DOMAIN, + EXPIRATION_DATES_MUST_BE_IN_THE_FUTURE, EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS, + OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED, + NOT_FOUND, TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION, TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION, + TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION, INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED, + PUBLISH_OUT_NOT_PERMITTED, SHARE_IN_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED, SHARE_OUT_NOT_PERMITTED_TO_USER, + CANNOT_SHARE_TEAMDRIVE_TOPFOLDER_WITH_ANYONEORDOMAINS, + CANNOT_SHARE_TEAMDRIVE_WITH_NONGOOGLE_ACCOUNTS, + OWNER_ON_TEAMDRIVE_ITEM_NOT_SUPPORTED, + ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, + ORGANIZER_ON_NON_TEAMDRIVE_ITEM_NOT_SUPPORTED, + FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE, + FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY, + FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED, + CANNOT_UPDATE_PERMISSION, + CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION, + FIELD_NOT_WRITABLE, PERMISSION_NOT_FOUND] +DRIVE3_DELETE_ACL_THROW_REASONS = [BAD_REQUEST, NOT_FOUND, PERMISSION_NOT_FOUND, CANNOT_REMOVE_OWNER, + CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION, CANNOT_MODIFY_INHERITED_PERMISSION, + INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, SHARING_RATE_LIMIT_EXCEEDED, + CANNOT_DELETE_PERMISSION, FILE_NEVER_WRITABLE] +DRIVE3_MODIFY_LABEL_THROW_REASONS = DRIVE_USER_THROW_REASONS+[FILE_NOT_FOUND, NOT_FOUND, FORBIDDEN, INTERNAL_ERROR, + FILE_NEVER_WRITABLE, APPLY_LABEL_FORBIDDEN, + INSUFFICIENT_ADMINISTRATOR_PRIVILEGES, INSUFFICIENT_FILE_PERMISSIONS, + UNKNOWN_ERROR, INVALID_INPUT, BAD_REQUEST, + LABEL_MULTIPLE_VALUES_FOR_SINGULAR_FIELD, LABEL_MUTATION_FORBIDDEN, + LABEL_MUTATION_ILLEGAL_SELECTION, LABEL_MUTATION_UNKNOWN_FIELD] +DOCS_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[NOT_FOUND, PERMISSION_DENIED, FORBIDDEN, INTERNAL_ERROR, INSUFFICIENT_FILE_PERMISSIONS, + BAD_REQUEST, INVALID, INVALID_ARGUMENT, FAILED_PRECONDITION] +GMAIL_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST] +GMAIL_LIST_THROW_REASONS = [FAILED_PRECONDITION, PERMISSION_DENIED, INVALID, INVALID_ARGUMENT] +GMAIL_SMIME_THROW_REASONS = [SERVICE_NOT_AVAILABLE, BAD_REQUEST, INVALID_ARGUMENT, FORBIDDEN, NOT_FOUND, PERMISSION_DENIED] +GROUP_GET_THROW_REASONS = [GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, INVALID, SYSTEM_ERROR] +GROUP_GET_RETRY_REASONS = [INVALID, SYSTEM_ERROR, SERVICE_NOT_AVAILABLE] +GROUP_CREATE_THROW_REASONS = [DUPLICATE, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_INPUT, RESOURCE_NOT_FOUND] +GROUP_UPDATE_THROW_REASONS = [GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, INVALID, INVALID_INPUT] +GROUP_SETTINGS_THROW_REASONS = [NOT_FOUND, GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, SYSTEM_ERROR, PERMISSION_DENIED, + INVALID, INVALID_ARGUMENT, INVALID_PARAMETER, INVALID_ATTRIBUTE_VALUE, INVALID_INPUT, + SERVICE_LIMIT, SERVICE_NOT_AVAILABLE, AUTH_ERROR, REQUIRED] +GROUP_SETTINGS_RETRY_REASONS = [INVALID, SERVICE_LIMIT, SERVICE_NOT_AVAILABLE] +GROUP_LIST_THROW_REASONS = [RESOURCE_NOT_FOUND, DOMAIN_NOT_FOUND, FORBIDDEN, BAD_REQUEST, PERMISSION_DENIED] +GROUP_LIST_USERKEY_THROW_REASONS = GROUP_LIST_THROW_REASONS+[INVALID_MEMBER, INVALID_INPUT] +KEEP_THROW_REASONS = [AUTH_ERROR, BAD_REQUEST, PERMISSION_DENIED, INVALID_ARGUMENT, NOT_FOUND] +LOOKERSTUDIO_THROW_REASONS = [INVALID_ARGUMENT, SERVICE_NOT_AVAILABLE, BAD_REQUEST, NOT_FOUND, PERMISSION_DENIED, INTERNAL_ERROR] +MEMBERS_THROW_REASONS = [GROUP_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, INVALID, FORBIDDEN, SERVICE_NOT_AVAILABLE, PERMISSION_DENIED] +MEMBERS_RETRY_REASONS = [SYSTEM_ERROR, SERVICE_NOT_AVAILABLE] +ORGUNIT_GET_THROW_REASONS = [INVALID_ORGUNIT, ORGUNIT_NOT_FOUND, BACKEND_ERROR, BAD_REQUEST, INVALID_CUSTOMER_ID, LOGIN_REQUIRED] +PEOPLE_ACCESS_THROW_REASONS = [SERVICE_NOT_AVAILABLE, FORBIDDEN, PERMISSION_DENIED, FAILED_PRECONDITION] +RESELLER_THROW_REASONS = [BAD_REQUEST, RESOURCE_NOT_FOUND, FORBIDDEN, INVALID] +SHEETS_ACCESS_THROW_REASONS = DRIVE_USER_THROW_REASONS+[NOT_FOUND, PERMISSION_DENIED, FORBIDDEN, INTERNAL_ERROR, INSUFFICIENT_FILE_PERMISSIONS, + BAD_REQUEST, INVALID, INVALID_ARGUMENT, FAILED_PRECONDITION] +TAGMANAGER_THROW_REASONS = [BAD_REQUEST, PERMISSION_DENIED, INVALID, NOT_FOUND, ACCESS_NOT_CONFIGURED] +TASK_THROW_REASONS = [BAD_REQUEST, PERMISSION_DENIED, INVALID, NOT_FOUND, ACCESS_NOT_CONFIGURED] +TASKLIST_THROW_REASONS = [BAD_REQUEST, PERMISSION_DENIED, INVALID, NOT_FOUND, ACCESS_NOT_CONFIGURED] +USER_GET_THROW_REASONS = [USER_NOT_FOUND, DOMAIN_NOT_FOUND, DOMAIN_CANNOT_USE_APIS, FORBIDDEN, BAD_REQUEST, SYSTEM_ERROR] +YOUTUBE_THROW_REASONS = [SERVICE_NOT_AVAILABLE, AUTH_ERROR, UNSUPPORTED_SUPERVISED_ACCOUNT, UNSUPPORTED_LANGUAGE_CODE, CONTENT_OWNER_ACCOUNT_NOT_FOUND] + +REASON_MESSAGE_MAP = { + ABORTED: [ + ('Label name exists or conflicts', DUPLICATE), + ('The operation was aborted', ABORTED), + ], + CONDITION_NOT_MET: [ + ('Cyclic memberships not allowed', CYCLIC_MEMBERSHIPS_NOT_ALLOWED), + ('undelete', DELETED_USER_NOT_FOUND), + ], + FAILED_PRECONDITION: [ + ('Bad Request', BAD_REQUEST), + ('Mail service not enabled', SERVICE_NOT_AVAILABLE), + ], + INVALID: [ + ('userId', USER_NOT_FOUND), + ('memberKey', INVALID_MEMBER), + ('A system error has occurred', SYSTEM_ERROR), + ('Expiration dates must be in the future', EXPIRATION_DATES_MUST_BE_IN_THE_FUTURE), + ('Invalid attribute value', INVALID_ATTRIBUTE_VALUE), + ('Invalid Customer Id', INVALID_CUSTOMER_ID), + ('Invalid Input: INVALID_OU_ID', INVALID_ORGUNIT), + ('Invalid Input: custom_schema', INVALID_SCHEMA_VALUE), + ('Invalid Input: groupKey', INVALID_INPUT), + ('Invalid Input: resource', INVALID_RESOURCE), + ('Invalid Input:', INVALID_INPUT), + ('Invalid Input', INVALID_INPUT), + ('Invalid Org Unit', INVALID_ORGUNIT), + ('Invalid Ou Id', INVALID_ORGUNIT), + ('Invalid Ou Name', INVALID_ORGUNIT_NAME), + ('Invalid Parent Orgunit Id', INVALID_PARENT_ORGUNIT), + ('Invalid query', INVALID_QUERY), + ('Invalid scope value', INVALID_SCOPE_VALUE), + ('Invalid value', INVALID_INPUT), + ('New domain name is not a verified secondary domain', DOMAIN_NOT_VERIFIED_SECONDARY), + ('PermissionDenied', PERMISSION_DENIED), + ], + INVALID_ARGUMENT: [ + ('Cannot delete primary send-as', CANNOT_DELETE_PRIMARY_SENDAS), + ('Invalid id value', INVALID_MESSAGE_ID), + ('Invalid ids value', INVALID_MESSAGE_ID), + ], + NOT_FOUND: [ + ('userKey', USER_NOT_FOUND), + ('groupKey', GROUP_NOT_FOUND), + ('memberKey', MEMBER_NOT_FOUND), + ('photo', PHOTO_NOT_FOUND), + ('resource_id', RESOURCE_ID_NOT_FOUND), + ('resourceId', RESOURCE_ID_NOT_FOUND), + ('Customer doesn\'t exist', CUSTOMER_NOT_FOUND), + ('Domain alias does not exist', DOMAIN_ALIAS_NOT_FOUND), + ('Domain not found', DOMAIN_NOT_FOUND), + ('domain', DOMAIN_NOT_FOUND), + ('File not found', FILE_NOT_FOUND), + ('Org unit not found', ORGUNIT_NOT_FOUND), + ('Permission not found', PERMISSION_NOT_FOUND), + ('Resource Not Found', RESOURCE_NOT_FOUND), + ('Revision not found', REVISION_NOT_FOUND), + ('Shared Drive not found', NOT_FOUND), + ('Not Found', NOT_FOUND), + ], + REQUIRED: [ + ('Login Required', LOGIN_REQUIRED), + ('memberKey', MEMBER_NOT_FOUND), + ], + RESOURCE_NOT_FOUND: [ + ('resourceId', RESOURCE_ID_NOT_FOUND), + ], + } + +class aborted(Exception): + pass +class abusiveContentRestriction(Exception): + pass +class accessNotConfigured(Exception): + pass +class adminCannotUnsuspend(Exception): + pass +class alreadyExists(Exception): + pass +class applyLabelForbidden(Exception): + pass +class authError(Exception): + pass +class backendError(Exception): + pass +class badRequest(Exception): + pass +class cannotAddParent(Exception): + pass +class cannotChangeOrganizer(Exception): + pass +class cannotChangeOrganizerOfInstance(Exception): + pass +class cannotChangeOwnAcl(Exception): + pass +class cannotChangeOwnerAcl(Exception): + pass +class cannotChangeOwnPrimarySubscription(Exception): + pass +class cannotCopyFile(Exception): + pass +class cannotDeleteOnlyRevision(Exception): + pass +class cannotDeletePermission(Exception): + pass +class cannotDeletePrimaryCalendar(Exception): + pass +class cannotDeletePrimarySendAs(Exception): + pass +class cannotDeleteResourceWithChildren(Exception): + pass +class cannotModifyAclOfCalendarOwner(Exception): + pass +class cannotModifyInheritedPermission(Exception): + pass +class cannotModifyInheritedTeamDrivePermission(Exception): + pass +class cannotModifyRestrictedLabel(Exception): + pass +class cannotModifyViewersCanCopyContent(Exception): + pass +class cannotMoveTrashedItemIntoTeamDrive(Exception): + pass +class cannotMoveTrashedItemOutOfTeamDrive(Exception): + pass +class cannotRemoveOwner(Exception): + pass +class cannotSetExpiration(Exception): + pass +class cannotSetExpirationOnAnyoneOrDomain(Exception): + pass +class cannotShareGroupsWithLink(Exception): + pass +class cannotShareUsersWithLink(Exception): + pass +class cannotShareTeamDriveTopFolderWithAnyoneOrDomains(Exception): + pass +class cannotShareTeamDriveWithNonGoogleAccounts(Exception): + pass +class cannotUnsubscribeFromOwnedCalendar(Exception): + pass +class cannotUpdatePermission(Exception): + pass +class conditionNotMet(Exception): + pass +class conflict(Exception): + pass +class contentOwnerAccountNotFound(Exception): + pass +class crossDomainMoveRestriction(Exception): + pass +class customerExceededRoleAssignmentsLimit(Exception): + pass +class customerNotFound(Exception): + pass +class cyclicMembershipsNotAllowed(Exception): + pass +class deleted(Exception): + pass +class deletedUserNotFound(Exception): + pass +class domainAliasNotFound(Exception): + pass +class domainCannotUseApis(Exception): + pass +class domainNotFound(Exception): + pass +class domainNotVerifiedSecondary(Exception): + pass +class domainPolicy(Exception): + pass +class downloadQuotaExceeded(Exception): + pass +class duplicate(Exception): + pass +class eventDurationExceedsLimit(Exception): + pass +class eventTypeRestriction(Exception): + pass +class expirationDatesMustBeInTheFuture(Exception): + pass +class expirationDateNotAllowedForSharedDriveMembers(Exception): + pass +class failedPrecondition(Exception): + pass +class fieldInUse(Exception): + pass +class fieldNotWritable(Exception): + pass +class fileNeverWritable(Exception): + pass +class fileNotFound(Exception): + pass +class fileOrganizerNotYetEnabledForThisTeamDrive(Exception): + pass +class fileOrganizerOnFoldersInSharedDriveOnly(Exception): + pass +class fileOrganizerOnNonTeamDriveNotSupported(Exception): + pass +class fileOwnerNotMemberOfTeamDrive(Exception): + pass +class fileOwnerNotMemberOfWriterDomain(Exception): + pass +class fileWriterTeamDriveMoveInDisabled(Exception): + pass +class forbidden(Exception): + pass +class groupNotFound(Exception): + pass +class illegalAccessRoleForDefault(Exception): + pass +class insufficientAdministratorPrivileges(Exception): + pass +class insufficientArchivedUserLicenses(Exception): + pass +class insufficientFilePermissions(Exception): + pass +class insufficientParentPermissions(Exception): + pass +class insufficientPermissions(Exception): + pass +class internalError(Exception): + pass +class invalid(Exception): + pass +class invalidArgument(Exception): + pass +class invalidAttributeValue(Exception): + pass +class invalidCustomerId(Exception): + pass +class invalidInput(Exception): + pass +class invalidLinkVisibility(Exception): + pass +class invalidMember(Exception): + pass +class invalidMessageId(Exception): + pass +class invalidOrgunit(Exception): + pass +class invalidOrgunitName(Exception): + pass +class invalidOwnershipTransfer(Exception): + pass +class invalidParameter(Exception): + pass +class invalidParentOrgunit(Exception): + pass +class invalidQuery(Exception): + pass +class invalidResource(Exception): + pass +class invalidSchemaValue(Exception): + pass +class invalidScopeValue(Exception): + pass +class invalidSharingRequest(Exception): + pass +class labelMultipleValuesForSingularField(Exception): + pass +class labelMutationForbidden(Exception): + pass +class labelMutationIllegalSelection(Exception): + pass +class labelMutationUnknownField(Exception): + pass +class limitExceeded(Exception): + pass +class loginRequired(Exception): + pass +class malformedWorkingLocationEvent(Exception): + pass +class memberNotFound(Exception): + pass +class noListTeamDrivesAdministratorPrivilege(Exception): + pass +class noManageTeamDriveAdministratorPrivilege(Exception): + pass +class notACalendarUser(Exception): + pass +class notFound(Exception): + pass +class notImplemented(Exception): + pass +class operationNotSupported(Exception): + pass +class organizerOnNonTeamDriveNotSupported(Exception): + pass +class organizerOnNonTeamDriveItemNotSupported(Exception): + pass +class orgunitNotFound(Exception): + pass +class outsideDomainMemberCannotChangeTeamDriveRestrictions(Exception): + pass +class ownerOnTeamDriveItemNotSupported(Exception): + pass +class ownershipChangeAcrossDomainNotPermitted(Exception): + pass +class participantIsNeitherOrganizerNorAttendee(Exception): + pass +class permissionDenied(Exception): + pass +class permissionNotFound(Exception): + pass +class photoNotFound(Exception): + pass +class publishOutNotPermitted(Exception): + pass +class queryRequiresAdminCredentials(Exception): + pass +class quotaExceeded(Exception): + pass +class rateLimitExceeded(Exception): + pass +class required(Exception): + pass +class requiredAccessLevel(Exception): + pass +class resourceExhausted(Exception): + pass +class resourceIdNotFound(Exception): + pass +class resourceNotFound(Exception): + pass +class responsePreparationFailure(Exception): + pass +class revisionDeletionNotSupported(Exception): + pass +class revisionNotFound(Exception): + pass +class revisionsNotSupported(Exception): + pass +class serviceLimit(Exception): + pass +class serviceNotAvailable(Exception): + pass +class shareInNotPermitted(Exception): + pass +class shareOutNotPermitted(Exception): + pass +class shareOutNotPermittedToUser(Exception): + pass +class shareOutWarning(Exception): + pass +class sharingRateLimitExceeded(Exception): + pass +class shortcutTargetInvalid(Exception): + pass +class storageQuotaExceeded(Exception): + pass +class systemError(Exception): + pass +class targetUserRoleLimitedByLicenseRestriction(Exception): + pass +class teamDriveAlreadyExists(Exception): + pass +class teamDriveDomainUsersOnlyRestriction(Exception): + pass +class teamDriveTeamMembersOnlyRestriction(Exception): + pass +class teamDriveFileLimitExceeded(Exception): + pass +class teamDriveHierarchyTooDeep(Exception): + pass +class teamDriveMembershipRequired(Exception): + pass +class teamDrivesFolderMoveInNotSupported(Exception): + pass +class teamDrivesFolderSharingNotSupported(Exception): + pass +class teamDrivesParentLimit(Exception): + pass +class teamDrivesSharingRestrictionNotAllowed(Exception): + pass +class teamDrivesShortcutFileNotSupported(Exception): + pass +class timeRangeEmpty(Exception): + pass +class transientError(Exception): + pass +class unimplementedError(Exception): + pass +class unknownError(Exception): + pass +class unsupportedLanguageCode(Exception): + pass +class unsupportedSupervisedAccount(Exception): + pass +class uploadTooLarge(Exception): + pass +class userCannotCreateTeamDrives(Exception): + pass +class userAccess(Exception): + pass +class userNotFound(Exception): + pass +class userRateLimitExceeded(Exception): + pass + +REASON_EXCEPTION_MAP = { + ABORTED: aborted, + ABUSIVE_CONTENT_RESTRICTION: abusiveContentRestriction, + ACCESS_NOT_CONFIGURED: accessNotConfigured, + ADMIN_CANNOT_UNSUSPEND: adminCannotUnsuspend, + ALREADY_EXISTS: alreadyExists, + APPLY_LABEL_FORBIDDEN: applyLabelForbidden, + AUTH_ERROR: authError, + BACKEND_ERROR: backendError, + BAD_REQUEST: badRequest, + CANNOT_ADD_PARENT: cannotAddParent, + CANNOT_CHANGE_ORGANIZER: cannotChangeOrganizer, + CANNOT_CHANGE_ORGANIZER_OF_INSTANCE: cannotChangeOrganizerOfInstance, + CANNOT_CHANGE_OWN_ACL: cannotChangeOwnAcl, + CANNOT_CHANGE_OWNER_ACL: cannotChangeOwnerAcl, + CANNOT_CHANGE_OWN_PRIMARY_SUBSCRIPTION: cannotChangeOwnPrimarySubscription, + CANNOT_COPY_FILE: cannotCopyFile, + CANNOT_DELETE_ONLY_REVISION: cannotDeleteOnlyRevision, + CANNOT_DELETE_PERMISSION: cannotDeletePermission, + CANNOT_DELETE_PRIMARY_CALENDAR: cannotDeletePrimaryCalendar, + CANNOT_DELETE_PRIMARY_SENDAS: cannotDeletePrimarySendAs, + CANNOT_DELETE_RESOURCE_WITH_CHILDREN: cannotDeleteResourceWithChildren, + CANNOT_MODIFY_ACL_OF_CALENDAR_OWNER: cannotModifyAclOfCalendarOwner, + CANNOT_MODIFY_INHERITED_PERMISSION: cannotModifyInheritedPermission, + CANNOT_MODIFY_INHERITED_TEAMDRIVE_PERMISSION: cannotModifyInheritedTeamDrivePermission, + CANNOT_MODIFY_RESTRICTED_LABEL: cannotModifyRestrictedLabel, + CANNOT_MODIFY_VIEWERS_CAN_COPY_CONTENT: cannotModifyViewersCanCopyContent, + CANNOT_MOVE_TRASHED_ITEM_INTO_TEAMDRIVE: cannotMoveTrashedItemIntoTeamDrive, + CANNOT_MOVE_TRASHED_ITEM_OUT_OF_TEAMDRIVE: cannotMoveTrashedItemOutOfTeamDrive, + CANNOT_REMOVE_OWNER: cannotRemoveOwner, + CANNOT_SET_EXPIRATION: cannotSetExpiration, + CANNOT_SET_EXPIRATION_ON_ANYONE_OR_DOMAIN: cannotSetExpirationOnAnyoneOrDomain, + CANNOT_SHARE_GROUPS_WITHLINK: cannotShareGroupsWithLink, + CANNOT_SHARE_USERS_WITHLINK: cannotShareUsersWithLink, + CANNOT_SHARE_TEAMDRIVE_TOPFOLDER_WITH_ANYONEORDOMAINS: cannotShareTeamDriveTopFolderWithAnyoneOrDomains, + CANNOT_SHARE_TEAMDRIVE_WITH_NONGOOGLE_ACCOUNTS: cannotShareTeamDriveWithNonGoogleAccounts, + CANNOT_UNSUBSCRIBE_FROM_OWNED_CALENDAR: cannotUnsubscribeFromOwnedCalendar, + CANNOT_UPDATE_PERMISSION: cannotUpdatePermission, + CONDITION_NOT_MET: conditionNotMet, + CONFLICT: conflict, + CONTENT_OWNER_ACCOUNT_NOT_FOUND: contentOwnerAccountNotFound, + CROSS_DOMAIN_MOVE_RESTRICTION: crossDomainMoveRestriction, + CUSTOMER_EXCEEDED_ROLE_ASSIGNMENTS_LIMIT: customerExceededRoleAssignmentsLimit, + CUSTOMER_NOT_FOUND: customerNotFound, + CYCLIC_MEMBERSHIPS_NOT_ALLOWED: cyclicMembershipsNotAllowed, + DELETED: deleted, + DELETED_USER_NOT_FOUND: deletedUserNotFound, + DOMAIN_ALIAS_NOT_FOUND: domainAliasNotFound, + DOMAIN_CANNOT_USE_APIS: domainCannotUseApis, + DOMAIN_NOT_FOUND: domainNotFound, + DOMAIN_NOT_VERIFIED_SECONDARY: domainNotVerifiedSecondary, + DOMAIN_POLICY: domainPolicy, + DOWNLOAD_QUOTA_EXCEEDED: downloadQuotaExceeded, + DUPLICATE: duplicate, + EVENT_DURATION_EXCEEDS_LIMIT: eventDurationExceedsLimit, + EVENT_TYPE_RESTRICTION: eventTypeRestriction, + EXPIRATION_DATES_MUST_BE_IN_THE_FUTURE: expirationDatesMustBeInTheFuture, + EXPIRATION_DATE_NOT_ALLOWED_FOR_SHARED_DRIVE_MEMBERS: expirationDateNotAllowedForSharedDriveMembers, + FAILED_PRECONDITION: failedPrecondition, + FIELD_IN_USE: fieldInUse, + FIELD_NOT_WRITABLE: fieldNotWritable, + FILE_NEVER_WRITABLE: fileNeverWritable, + FILE_NOT_FOUND: fileNotFound, + FILE_ORGANIZER_NOT_YET_ENABLED_FOR_THIS_TEAMDRIVE: fileOrganizerNotYetEnabledForThisTeamDrive, + FILE_ORGANIZER_ON_FOLDERS_IN_SHARED_DRIVE_ONLY: fileOrganizerOnFoldersInSharedDriveOnly, + FILE_ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED: fileOrganizerOnNonTeamDriveNotSupported, + FILE_OWNER_NOT_MEMBER_OF_TEAMDRIVE: fileOwnerNotMemberOfTeamDrive, + FILE_OWNER_NOT_MEMBER_OF_WRITER_DOMAIN: fileOwnerNotMemberOfWriterDomain, + FILE_WRITER_TEAMDRIVE_MOVE_IN_DISABLED: fileWriterTeamDriveMoveInDisabled, + FORBIDDEN: forbidden, + GROUP_NOT_FOUND: groupNotFound, + ILLEGAL_ACCESS_ROLE_FOR_DEFAULT: illegalAccessRoleForDefault, + INSUFFICIENT_ADMINISTRATOR_PRIVILEGES: insufficientAdministratorPrivileges, + INSUFFICIENT_ARCHIVED_USER_LICENSES: insufficientArchivedUserLicenses, + INSUFFICIENT_FILE_PERMISSIONS: insufficientFilePermissions, + INSUFFICIENT_PARENT_PERMISSIONS: insufficientParentPermissions, + INSUFFICIENT_PERMISSIONS: insufficientPermissions, + INTERNAL_ERROR: internalError, + INVALID: invalid, + INVALID_ARGUMENT: invalidArgument, + INVALID_ATTRIBUTE_VALUE: invalidAttributeValue, + INVALID_CUSTOMER_ID: invalidCustomerId, + INVALID_INPUT: invalidInput, + INVALID_LINK_VISIBILITY: invalidLinkVisibility, + INVALID_MEMBER: invalidMember, + INVALID_MESSAGE_ID: invalidMessageId, + INVALID_ORGUNIT: invalidOrgunit, + INVALID_ORGUNIT_NAME: invalidOrgunitName, + INVALID_OWNERSHIP_TRANSFER: invalidOwnershipTransfer, + INVALID_PARAMETER: invalidParameter, + INVALID_PARENT_ORGUNIT: invalidParentOrgunit, + INVALID_QUERY: invalidQuery, + INVALID_RESOURCE: invalidResource, + INVALID_SCHEMA_VALUE: invalidSchemaValue, + INVALID_SCOPE_VALUE: invalidScopeValue, + INVALID_SHARING_REQUEST: invalidSharingRequest, + LABEL_MULTIPLE_VALUES_FOR_SINGULAR_FIELD: labelMultipleValuesForSingularField, + LABEL_MUTATION_FORBIDDEN: labelMutationForbidden, + LABEL_MUTATION_ILLEGAL_SELECTION: labelMutationIllegalSelection, + LABEL_MUTATION_UNKNOWN_FIELD: labelMutationUnknownField, + LIMIT_EXCEEDED: limitExceeded, + LOGIN_REQUIRED: loginRequired, + MALFORMED_WORKING_LOCATION_EVENT: malformedWorkingLocationEvent, + MEMBER_NOT_FOUND: memberNotFound, + NO_LIST_TEAMDRIVES_ADMINISTRATOR_PRIVILEGE: noListTeamDrivesAdministratorPrivilege, + NO_MANAGE_TEAMDRIVE_ADMINISTRATOR_PRIVILEGE: noManageTeamDriveAdministratorPrivilege, + NOT_A_CALENDAR_USER: notACalendarUser, + NOT_FOUND: notFound, + NOT_IMPLEMENTED: notImplemented, + OPERATION_NOT_SUPPORTED: operationNotSupported, + ORGANIZER_ON_NON_TEAMDRIVE_NOT_SUPPORTED: organizerOnNonTeamDriveNotSupported, + ORGANIZER_ON_NON_TEAMDRIVE_ITEM_NOT_SUPPORTED: organizerOnNonTeamDriveItemNotSupported, + ORGUNIT_NOT_FOUND: orgunitNotFound, + OUTSIDE_DOMAIN_MEMBER_CANNOT_CHANGE_TEAMDRIVE_RESTRICTIONS: outsideDomainMemberCannotChangeTeamDriveRestrictions, + OWNER_ON_TEAMDRIVE_ITEM_NOT_SUPPORTED: ownerOnTeamDriveItemNotSupported, + OWNERSHIP_CHANGE_ACROSS_DOMAIN_NOT_PERMITTED: ownershipChangeAcrossDomainNotPermitted, + PARTICIPANT_IS_NEITHER_ORGANIZER_NOR_ATTENDEE: participantIsNeitherOrganizerNorAttendee, + PERMISSION_DENIED: permissionDenied, + PERMISSION_NOT_FOUND: permissionNotFound, + PHOTO_NOT_FOUND: photoNotFound, + PUBLISH_OUT_NOT_PERMITTED: publishOutNotPermitted, + QUERY_REQUIRES_ADMIN_CREDENTIALS: queryRequiresAdminCredentials, + QUOTA_EXCEEDED: quotaExceeded, + RATE_LIMIT_EXCEEDED: rateLimitExceeded, + REQUIRED: required, + REQUIRED_ACCESS_LEVEL: requiredAccessLevel, + RESOURCE_EXHAUSTED: resourceExhausted, + RESOURCE_ID_NOT_FOUND: resourceIdNotFound, + RESOURCE_NOT_FOUND: resourceNotFound, + RESPONSE_PREPARATION_FAILURE: responsePreparationFailure, + REVISION_DELETION_NOT_SUPPORTED: revisionDeletionNotSupported, + REVISION_NOT_FOUND: revisionNotFound, + REVISIONS_NOT_SUPPORTED: revisionsNotSupported, + SERVICE_LIMIT: serviceLimit, + SERVICE_NOT_AVAILABLE: serviceNotAvailable, + SHARE_IN_NOT_PERMITTED: shareInNotPermitted, + SHARE_OUT_NOT_PERMITTED: shareOutNotPermitted, + SHARE_OUT_NOT_PERMITTED_TO_USER: shareOutNotPermittedToUser, + SHARE_OUT_WARNING: shareOutWarning, + SHARING_RATE_LIMIT_EXCEEDED: sharingRateLimitExceeded, + SHORTCUT_TARGET_INVALID: shortcutTargetInvalid, + STORAGE_QUOTA_EXCEEDED: storageQuotaExceeded, + SYSTEM_ERROR: systemError, + TARGET_USER_ROLE_LIMITED_BY_LICENSE_RESTRICTION: targetUserRoleLimitedByLicenseRestriction, + TEAMDRIVE_ALREADY_EXISTS: teamDriveAlreadyExists, + TEAMDRIVE_DOMAIN_USERS_ONLY_RESTRICTION: teamDriveDomainUsersOnlyRestriction, + TEAMDRIVE_TEAM_MEMBERS_ONLY_RESTRICTION: teamDriveTeamMembersOnlyRestriction, + TEAMDRIVE_FILE_LIMIT_EXCEEDED: teamDriveFileLimitExceeded, + TEAMDRIVE_HIERARCHY_TOO_DEEP: teamDriveHierarchyTooDeep, + TEAMDRIVE_MEMBERSHIP_REQUIRED: teamDriveMembershipRequired, + TEAMDRIVES_FOLDER_MOVE_IN_NOT_SUPPORTED: teamDrivesFolderMoveInNotSupported, + TEAMDRIVES_FOLDER_SHARING_NOT_SUPPORTED: teamDrivesFolderSharingNotSupported, + TEAMDRIVES_PARENT_LIMIT: teamDrivesParentLimit, + TEAMDRIVES_SHARING_RESTRICTION_NOT_ALLOWED: teamDrivesSharingRestrictionNotAllowed, + TEAMDRIVES_SHORTCUT_FILE_NOT_SUPPORTED: teamDrivesShortcutFileNotSupported, + TIME_RANGE_EMPTY: timeRangeEmpty, + TRANSIENT_ERROR: transientError, + UNIMPLEMENTED_ERROR: unimplementedError, + UNKNOWN_ERROR: unknownError, + UNSUPPORTED_LANGUAGE_CODE: unsupportedLanguageCode, + UNSUPPORTED_SUPERVISED_ACCOUNT: unsupportedSupervisedAccount, + UPLOAD_TOO_LARGE: uploadTooLarge, + USER_CANNOT_CREATE_TEAMDRIVES: userCannotCreateTeamDrives, + USER_ACCESS: userAccess, + USER_NOT_FOUND: userNotFound, + USER_RATE_LIMIT_EXCEEDED: userRateLimitExceeded, + } diff --git a/src/gam/gamlib/gdata.py b/src/gam/gamlib/gdata.py new file mode 100644 index 00000000..d1313e02 --- /dev/null +++ b/src/gam/gamlib/gdata.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2023 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM GData resources + +""" +API_DEPRECATED_MSG = 'Contacts API is being deprecated.' + +# callGData throw errors +API_DEPRECATED = 612 +BAD_GATEWAY = 601 +BAD_REQUEST = 602 +DOES_NOT_EXIST = 1301 +ENTITY_EXISTS = 1300 +FORBIDDEN = 603 +GATEWAY_TIMEOUT = 612 +INSUFFICIENT_PERMISSIONS = 604 +INTERNAL_SERVER_ERROR = 1000 +INVALID_DOMAIN = 605 +INVALID_INPUT = 1317 +INVALID_VALUE = 1801 +NAME_NOT_VALID = 1303 +NOT_FOUND = 606 +NOT_IMPLEMENTED = 607 +PRECONDITION_FAILED = 608 +QUOTA_EXCEEDED = 609 +SERVICE_NOT_APPLICABLE = 1410 +SERVICE_UNAVAILABLE = 610 +TOKEN_EXPIRED = 611 +TOKEN_INVALID = 403 +UNKNOWN_ERROR = 600 +# +NON_TERMINATING_ERRORS = [API_DEPRECATED, BAD_GATEWAY, GATEWAY_TIMEOUT, QUOTA_EXCEEDED, SERVICE_UNAVAILABLE, TOKEN_EXPIRED] +EMAILSETTINGS_THROW_LIST = [INVALID_DOMAIN, DOES_NOT_EXIST, SERVICE_NOT_APPLICABLE, BAD_REQUEST, NAME_NOT_VALID, INTERNAL_SERVER_ERROR, INVALID_VALUE] +# +class apiDeprecated(Exception): + pass +class badRequest(Exception): + pass +class doesNotExist(Exception): + pass +class entityExists(Exception): + pass +class forbidden(Exception): + pass +class insufficientPermissions(Exception): + pass +class internalServerError(Exception): + pass +class invalidDomain(Exception): + pass +class invalidInput(Exception): + pass +class invalidValue(Exception): + pass +class nameNotValid(Exception): + pass +class notFound(Exception): + pass +class notImplemented(Exception): + pass +class preconditionFailed(Exception): + pass +class serviceNotApplicable(Exception): + pass + +ERROR_CODE_EXCEPTION_MAP = { + API_DEPRECATED: apiDeprecated, + BAD_REQUEST: badRequest, + DOES_NOT_EXIST: doesNotExist, + ENTITY_EXISTS: entityExists, + FORBIDDEN: forbidden, + INSUFFICIENT_PERMISSIONS: insufficientPermissions, + INTERNAL_SERVER_ERROR: internalServerError, + INVALID_DOMAIN: invalidDomain, + INVALID_INPUT: invalidInput, + INVALID_VALUE: invalidValue, + NAME_NOT_VALID: nameNotValid, + NOT_FOUND: notFound, + NOT_IMPLEMENTED: notImplemented, + PRECONDITION_FAILED: preconditionFailed, + SERVICE_NOT_APPLICABLE: serviceNotApplicable, + } diff --git a/src/gam/gamlib/indent.py b/src/gam/gamlib/indent.py new file mode 100644 index 00000000..383f875c --- /dev/null +++ b/src/gam/gamlib/indent.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2023 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM indent processing + +""" + +class GamIndent(): + + INDENT_SPACES_PER_LEVEL = ' ' + + # Shared state across all instances (class-level) + _indent = 0 + + @property + def indent(self): + return GamIndent._indent + @indent.setter + def indent(self, value): + GamIndent._indent = value + + def __init__(self): + pass # state is shared at class level + + def Reset(self): + GamIndent._indent = 0 + + def Increment(self): + GamIndent._indent += 1 + + def Decrement(self): + GamIndent._indent -= 1 + + def Spaces(self): + return self.INDENT_SPACES_PER_LEVEL*GamIndent._indent + + def SpacesSub1(self): + return self.INDENT_SPACES_PER_LEVEL*(GamIndent._indent-1) + + def MultiLineText(self, message, n=0): + return message.replace('\n', f'\n{self.INDENT_SPACES_PER_LEVEL*(GamIndent._indent+n)}').rstrip() diff --git a/src/gam/gamlib/msgs.py b/src/gam/gamlib/msgs.py new file mode 100644 index 00000000..40b1e07e --- /dev/null +++ b/src/gam/gamlib/msgs.py @@ -0,0 +1,570 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM messages + +""" + +# These values can be translated into other languages +# Project creation messages in order of appearance +CREATING_PROJECT = 'Creating project "{0}"...\n' +CHECK_INTERRUPTED = 'Check interrupted' +CHECKING_PROJECT_CREATION_STATUS = 'Checking project creation status...\n' +NO_RIGHTS_GOOGLE_CLOUD_ORGANIZATION = 'Looks like you have no rights to your Google Cloud Organization.\nAttempting to fix that...\n' +YOUR_ORGANIZATION_NAME_IS = 'Your organization name is {0}\n' +YOU_HAVE_NO_RIGHTS_TO_CREATE_PROJECTS_AND_YOU_ARE_NOT_A_SUPER_ADMIN = 'You have no rights to create projects for your organization and you don\'t seem to be a super admin! Sorry, there\'s nothing more I can do.' +LOOKS_LIKE_NO_ONE_HAS_RIGHTS_TO_YOUR_GOOGLE_CLOUD_ORGANIZATION_ATTEMPTING_TO_GIVE_YOU_CREATE_RIGHTS = 'Looks like no one has rights to your Google Cloud Organization. Attempting to give you create rights...\n' +THE_FOLLOWING_RIGHTS_SEEM_TO_EXIST = 'The following rights seem to exist:\n' +GIVING_LOGIN_HINT_THE_CREATOR_ROLE = 'Giving {0} the role of {1}...\n' +ACCEPT_CLOUD_TOS = ''' +Please go to: + +https://console.cloud.google.com/projectselector2/home/dashboard?supportedpurview=project + +sign in as {0} and accept the Terms of Service (ToS). As soon as you've accepted the ToS popup, you can return here and press enter.\n''' + +PROJECT_STILL_BEING_CREATED_SLEEPING = 'Project still being created. Sleeping {0} seconds\n' +FAILED_TO_CREATE_PROJECT = 'Failed to create project: {0}\n' +SETTING_GAM_PROJECT_CONSENT_SCREEN_CREATING_CLIENT = 'Setting GAM project consent screen, creating client...\n' +CREATE_CLIENT_INSTRUCTIONS = ''' +Please go to: + + {0} + + 1. If "+ CREATE CLIENT" is on the screen, skip to step 14 + 2. Click "GET STARTED" + 3. Under "App Information", enter {1} or another value in "App name *" + 4. Under "App Information", enter {2} in "User support email *" + 5. Click "NEXT" + 6. Under "Audience", choose INTERNAL + 7. Click "NEXT" + 8. Under, "Contact Information", enter {2} or another value in "Email addresses *" + 9. Click "NEXT" +10. Under "Finish", click "I agree to the Google API Services: User Data Policy." +11. Click "CONTINUE" +12. Click "CREATE" +13. Click "Clients" in the left-hand column +14. Click "+ CREATE CLIENT" +15. Choose "Desktop App" for "Application type" +16. Enter {1} or another value in "Name *" +17. Click "Create" +18. Under "Name", click your client name +19. Copy the "Client ID" value under "Additional information" +20. Paste it at the "Enter your Client ID: " prompt in your terminal +21. Press return/enter in your terminal +22. Switch back to the browser +23. Copy the "Client secret" value under "Client Secrets" +24. Paste it at the "Enter your Client Secret: " prompt in your terminal +25. Press return/enter in your terminal +26. Switch back to the browser +27. Click "OK" +28. These steps are complete +''' +ENTER_YOUR_CLIENT_ID = '\nEnter your Client ID: ' +ENTER_YOUR_CLIENT_SECRET = '\nEnter your Client Secret: ' +IS_NOT_A_VALID_CLIENT_ID = ''' + +{0} + +Is not a valid Client ID. + +Please make sure you are following the directions exactly and that there are no extra spaces in your Client ID. +''' +IS_NOT_A_VALID_CLIENT_SECRET = ''' + +{0} + +Is not a valid Client Secret. + +Please make sure you are following the directions exactly and that there are no extra spaces in your Client Secret. +''' +TRUST_GAM_CLIENT_ID = ''' +It's important to mark the {0} Client ID as trusted by your Workspace instance. + +Please go to: + + https://admin.google.com/ac/owl/list?tab=configuredApps + +1. Click on: Configure new app +2. Enter the following Client ID value in Search for app: + + {1} + +3. Press Search, select the {0} app, click +4. Keep the default scope or select a preferred scope that includes your GAM admin. +5. Press Continue +6. Select Trusted radio button, press Continue and Finish. +7. Press Confirm if Confirm parental consent pops up +8. Press enter here on the terminal once trust is complete. +''' + +ENABLE_SERVICE_ACCOUNT_PRIVATE_KEY_UPLOAD = ''' +Your workspace is configured to disable service account private key uploads. + +Please go to: + + https://github.com/GAM-team/GAM/wiki/Authorization#authorize-service-account-key-uploads + +Follow the steps to allow a service account private key upload for the project ({0}) just created. +Once those steps are completed, you can continue with your project authentication. +''' + +YOUR_GAM_PROJECT_IS_CREATED_AND_READY_TO_USE = ''' +That\'s it! Your GAM Project is created and ready to use. +Proceed to the authentication steps. +''' + +# check|update service messages in order of appearance +SYSTEM_TIME_STATUS = 'System time status' +YOUR_SYSTEM_TIME_DIFFERS_FROM_GOOGLE = 'Your system time differs from {0} by {1}' +PRESS_ENTER_ONCE_AUTHORIZATION_IS_COMPLETE = 'Press enter once authorization is complete.' +SERVICE_ACCOUNT_API_DISABLED = '{0} not enabled. Please run "gam update project" and "gam user user@domain.com update serviceaccount"' +SERVICE_ACCOUNT_PRIVATE_KEY_AUTHENTICATION = 'Service Account Private Key Authentication' +SERVICE_ACCOUNT_CHECK_PRIVATE_KEY_AGE = 'Service Account Private Key age; Google recommends rotating keys on a routine basis' +SERVICE_ACCOUNT_PRIVATE_KEY_AGE = 'Service Account Private Key age: {0} days' +SERVICE_ACCOUNT_SKIPPING_KEY_AGE_CHECK = 'Skipping Private Key age check: {0} rotation not necessary' +UPDATE_PROJECT_TO_VIEW_MANAGE_SAKEYS = 'Please run "gam update project" to view/manage service account keys' +DOMAIN_WIDE_DELEGATION_AUTHENTICATION = 'Domain-wide Delegation authentication' +DEPRECATED_SCOPES = 'Deprecated scopes that GAM should NEVER have DwD access to' +SCOPE_AUTHORIZATION_PASSED = '''All scopes PASSED! + +Service Account Client name: {0} is fully authorized. +''' +SCOPE_AUTHORIZATION_UPDATE_PASSED = '''All scopes PASSED! +To update authorization (in case some scopes were unselected), please go to the following link in your browser: +{0} + {1} + +You will be directed to the Google Workspace admin console Security > API Controls > Domain-wide Delegation page +The "Add a new Client ID" box will open +Make sure that "Overwrite existing client ID" is checked +Click AUTHORIZE +When the box closes you're done +After authorizing it may take some time for this test to pass so wait a few moments and then try this command again. +''' +SCOPE_AUTHORIZATION_FAILED = '''Some scopes FAILED or should be DISABLED! +To update authorization, please go to the following link in your browser: +{0} + {1} + +You will be directed to the Google Workspace admin console Security > API Controls > Domain-wide Delegation page +The "Add a new Client ID" box will open +Make sure that "Overwrite existing client ID" is checked +Click AUTHORIZE +When the box closes you're done +After authorizing it may take some time for this test to pass so wait a few moments and then try this command again. +''' +# General messages +ACCESS_FORBIDDEN = 'Access Forbidden' +ACTION_APPLIED = 'Action Applied' +ACTION_IN_PROGRESS = 'Action {0} in progress' +ACTION_MAY_BE_DELAYED = 'Action may be delayed' +ADMIN_STATUS_CHANGED_TO = 'Admin Status Changed to' +ALL = 'All' +ALL_FOLDER_NAMES_MUST_BE_NON_BLANK = 'All folder names must be non-blank: {0}' +ALL_SKU_PRODUCTIDS_MUST_MATCH = 'All SKU productIds must match, {0} != {1}' +ALREADY_WAS_OWNER = 'Already was owner' +ALREADY_EXISTS = 'Already exists' +ALREADY_EXISTS_IN_TARGET_FOLDER = 'Already exists in {0}: {1}' +ALREADY_EXISTS_USE_MERGE_ARGUMENT = 'Already exists; use the "merge" argument to merge the labels' +API_ACCESS_DENIED = 'API access Denied' +API_CALLS_RETRY_DATA = 'API calls retry data\n' +API_CHECK_CLIENT_AUTHORIZATION = 'Please make sure the Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam oauth create\n' +API_CHECK_SVCACCT_AUTHORIZATION = 'Please make sure the Service Account Client ID: {0} is authorized for the appropriate API or scopes: {1}\n\nRun: gam user {2} update serviceaccount\n' +API_ERROR_SETTINGS = 'API error, some settings not set' +ARE_BOTH_REQUIRED = 'Arguments {0} and {1} are both required' +ARE_MUTUALLY_EXCLUSIVE = 'Arguments {0} and {1} are mutually exclusive' +AS = 'as' +ATTENDEES_ADD = 'Add Attendees' +ATTENDEES_ADD_REMOVE = 'Add/Remove Attendees' +ATTENDEES_REMOVE = 'Remove Attendees' +AUTHORIZATION_FILE_ALREADY_EXISTS = '{0} already exists. Please delete or rename it before attempting to {1} project.' +AUTHENTICATION_FLOW_COMPLETE = '\nThe authentication flow has completed.' +AUTHENTICATION_FLOW_COMPLETE_CLOSE_BROWSER = 'The authentication flow has completed. You may close this browser window and return to {0}.' +AUTHENTICATION_FLOW_FAILED = 'The authentication flow failed, reissue command' +BAD_ENTITIES_IN_SOURCE = '{0} {1} {2} in source marked >>> <<< above' +BAD_REQUEST = 'Bad Request' +BATCH = 'Batch' +BATCH_CSV_LOOP_DASH_DEBUG_INCOMPATIBLE = '"gam {0} - ..." is not compatible with debugging. Disable debugging by setting debug_level = 0 in gam.cfg' +BATCH_CSV_PROCESSING_COMPLETE = '{0},0/{1},Processing complete\n' +BATCH_CSV_TERMINATE_N_PROCESSES = '{0},0/{1},Terminating {2} running {3}\n' +BATCH_CSV_WAIT_LIMIT = ', wait limit {0} seconds' +BATCH_CSV_WAIT_N_PROCESSES = '{0},0/{1},Waiting for {2} running {3} to finish before terminating{4}\n' +BATCH_NOT_PROCESSED_ERRORS = '{0}batch file: {1}, not processed, {2} {3}\n' +CALLING_GCLOUD_FOR_REAUTH = 'Calling gcloud for reauth credentials..."\n' +CAN_NOT_DELETE_USER_WITH_VAULT_HOLD = '{0}: The user may be (or have recently been) on Google Vault Hold and thus not eligible for deletion. You can check holds with "gam user {1} show vaultholds".' +CAN_NOT_BE_SPECIFIED_MORE_THAN_ONCE = 'Argument {0} can not be specified more than once' +CHAT_ADMIN_ACCESS_LIMITED_TO_ONE_USER = 'Chat adminaccess|asadmin limited to one user, {0} specified' +CHROME_TARGET_VERSION_FORMAT = r'^([a-z]+)-(\d+)$ or ^(\d{1,4}\.){1,4}$' +COLUMN_DOES_NOT_MATCH_ANY_INPUT_COLUMNS = '{0} column "{1}" does not match any input columns' +COLUMN_DOES_NOT_MATCH_ANY_OUTPUT_COLUMNS = '{0} column "{1}" does not match any output columns' +COMMAND_NOT_COMPATIBLE_WITH_ENABLE_DASA = 'gam {0} {1} is not compatible with enable_dasa = true in gam.cfg' +COMMIT_BATCH_COMPLETE = '{0},0/{1},commit-batch - running {2} finished, proceeding\n' +COMMIT_BATCH_WAIT_N_PROCESSES = '{0},0/{1},commit-batch - waiting for {2} running {3} to finish before proceeding\n' +CONFIRM_WIPE_YUBIKEY_PIV = 'This will wipe all YubiKey PIV keys and configuration from your YubiKey. Are you sure? (y/N) ' +CONTACT_ADMINISTRATOR_FOR_PASSWORD = 'Contact administrator for password' +CONTACT_PHOTO_NOT_FOUND = 'Contact photo not found' +CONTAINS_AT_LEAST_1_ITEM = 'Contains at least 1 item' +COUNT_N_EXCEEDS_MAX_TO_PROCESS_M = 'Count {0} exceeds maximum to {1} {2}' +CORRUPT_FILE = 'Corrupt file' +COULD_NOT_FIND_ANY_YUBIKEY = 'Could not find any YubiKey\n' +COULD_NOT_FIND_YUBIKEY_WITH_SERIAL = 'Could not find YubiKey with serial number {0}\n' +CREATE_DELEGATE_NOTIFY_MESSAGE = '#user# has granted you #delegate# access to read, delete and send mail on their behalf.' +CREATE_DELEGATE_NOTIFY_SUBJECT = '#user# mail delegation to #delegate#' +CREATE_USER_NOTIFY_MESSAGE = 'Hello #givenname# #familyname#,\n\nYou have a new account at #domain#\nAccount details:\nUsername: #user#\nPassword: #password#\nStart using your new account by signing in at\nhttps://www.google.com/accounts/AccountChooser?Email=#user#&continue=https://workspace.google.com/dashboard\n' +CREATE_USER_NOTIFY_SUBJECT = 'Welcome to #domain#' +CSV_DATA_ALREADY_SAVED = 'CSV data already saved' +CSV_FILE_HEADERS = 'The CSV file ({0}) has the following headers:\n' +CSV_SAMPLE_COMMANDS = 'Here are the first {0} commands {1} will run\n' +DATA_FIELD_MISMATCH = 'datafield {0} does not match saved datafield {1}' +DATA_TRANSFER_COMPLETED = 'Data Transfer completed: {0}\n' +DATA_UPLOADED_TO_DRIVE_FILE = 'Data uploaded to Drive File' +DEFAULT_SMIME = 'Default S/MIME' +DELETED = 'Deleted' +DEVELOPER_PREVIEW_REQUIRED = 'Developer Preview is required for this command\n' +DEVICE_LIST_BUG = 'GAM hit Google internal bug 237397223. Please file a Google Support ticket stating that you are encountering this bug.' +DEVICE_LIST_BUG_WORKAROUND_NOT_POSSIBLE = 'GAM workaround for this issue only works if orderby argument is not used and query does not contain \'register\'.' +DEVICE_LIST_BUG_ATTEMPTING_WORKAROUND = 'GAM is attempting to work around the bug by filtering for devices created on or after the newest we\'ve seen ({0})...\n' +DIRECTLY_IN_THE = ' directly in the {0}' +DISABLE_TLS_MIN_MAX = 'Execute: gam select default config tls_max_version "" tls_min_version "" save\n' +DISPLAYNAME_NOT_ALLOWED_WHEN_UPDATING_MULTIPLE_SCHEMAS = 'displayname not allowed when updating multiple schemas' +DOES_NOT_EXIST = 'Does not exist' +DOES_NOT_EXIST_OR_HAS_INVALID_FORMAT = '{0}: {1}, Does not exist or has invalid format, {2}' +DOES_NOT_MATCH = 'Does not match {0}' +DOMAIN_NOT_FOUND_IN_DNS = 'Domain not found in DNS!' +DOMAIN_NOT_VERIFIED_SECONDARY = 'Domain is not a verified secondary domain' +DONE_GENERATING_PRIVATE_KEY_AND_PUBLIC_CERTIFICATE = 'Done generating private key and public certificate' +DO_NOT_EXIST = 'Do not exist' +DOWNLOADING_AGAIN_AND_OVER_WRITING = 'Downloading again and over-writing...' +DUPLICATE = 'Duplicate' +DUPLICATE_ALREADY_A_ROLE = 'Duplicate, already a {0}' +DYNAMIC_GROUP_MEMBERSHIP_CANNOT_BE_MODIFIED = 'Dynamic group membership cannot be modified' +EITHER = 'Either' +EMAIL_ADDRESS_IS_UNMANAGED_ACCOUNT = 'The email address is an unmanaged account' +ENABLE_PROJECT_APIS_AUTOMATICALLY_OR_MANUALLY = 'Do you want to enable project APIs [a]utomatically or [m]anually? (a/m): ' +ENTER_GSUITE_ADMIN_EMAIL_ADDRESS = '\nEnter your Google Workspace admin email address? ' +ENTER_MANAGE_GCP_PROJECT_EMAIL_ADDRESS = '\nEnter your Google Workspace admin or GCP project manager email address authorized to manage project(s): {0}? ' +ENTER_VERIFICATION_CODE_OR_URL = 'Enter verification code or paste "Unable to connect" URL from other computer (only URL data up to &scope required): ' +ENTITY_DOES_NOT_EXIST = '{0} does not exist' +ENTITY_NAME_NOT_VALID = 'Entity Name Not Valid' +ERROR = 'error' +ERRORS = 'errors' +EVENT_IS_CANCELED = 'Event is canceled' +EXECUTE_GAM_OAUTH_CREATE = '\nPlease run\n\ngam oauth delete\ngam oauth create\n\n' +EXISTS = 'Exists' +EXPECTED = 'Expected' +EXPORT_NOT_COMPLETE = 'Export needs to be complete before downloading, current status is: {0}' +EXTRACTING_PUBLIC_CERTIFICATE = 'Extracting public certificate' +FAILED_PRECONDITION = 'Failed precondition' +FAILED_TO_PARSE_AS_JSON = 'Failed to parse as JSON' +FAILED_TO_PARSE_AS_LIST = 'Failed to parse as list' +FIELD_NOT_FOUND_IN_SCHEMA = 'Field {0} not found in schema {1}' +FILE_NOT_FOUND = 'File {0} not found' +FINISHED = 'Finished' +FILTER_CAN_ONLY_CONTAIN_ONE_CATEGORY_LABEL = 'Filter can only contain one CATEGORY label' +FILTER_CAN_ONLY_CONTAIN_ONE_USER_LABEL = 'Filter can only contain one USER label' +FOR = 'for' +FORBIDDEN = 'Forbidden' +FORMAT_NOT_AVAILABLE = 'Format ({0}) not available' +FORMAT_NOT_DOWNLOADABLE = 'Format not downloadable' +FROM = 'From' +FROM_LC = 'from' +FULL_PATH_MUST_START_WITH_DRIVE = 'fullpath must start with {0} or {1}' +GAM_BATCH_FILE_WRITTEN = 'GAM batch file {0} written\n' +GAM_LATEST_VERSION_NOT_AVAILABLE = 'GAM Latest Version information not available' +GAM_OUT_OF_MEMORY = 'GAM has run out of memory. If this is a large Google Workspace instance, you should use a 64-bit version of GAM on Windows or a 64-bit version of Python on other systems.' +GENERATING_NEW_PRIVATE_KEY = 'Generating new private key' +GETTING = 'Getting' +GETTING_ALL = 'Getting all' +GRANTING_RIGHTS_TO_ROTATE_ITS_OWN_PRIVATE_KEY = '{0} rights to rotate its own private key' +GOOGLE_DELEGATION_ERROR = 'Google delegation error, delegator and delegate both exist and are valid for delegation' +GOT = 'Got' +GROUP_MAPS_TO_MULTIPLE_OUS = 'File: {0}, Group: {1} references multiple OUs: {2}' +GROUP_MAPS_TO_OU_INVALID_ROW = 'File: {0}, Invalid row, must contain non-blank and : <{1}> <{2}>' +GUARDIAN_INVITATION_STATUS_NOT_PENDING = 'Guardian invitation status is not PENDING' +HAS_CHILD_ORGS = 'Has child {0}' +HAS_INVALID_FORMAT = '{0}: {1}, Has invalid format' +HEADER_NOT_FOUND_IN_CSV_HEADERS = 'Header "{0}" not found in CSV headers of "{1}".' +HELP_SYNTAX = 'Help: Syntax in file {0}\n' +HELP_WIKI = 'Help: Documentation is at {0}\n' +IGNORED = 'Ignored' +INSTRUCTIONS_CLIENT_SECRETS_JSON = 'Please run\n\ngam create|use project\ngam oauth create\n\nto create and authorize a Client account.\n' +INSTRUCTIONS_OAUTH2SERVICE_JSON = 'Please run\n\ngam create|use project\ngam user update serviceaccount\n\nto create and authorize a Service account.\n' +INSUFFICIENT_PERMISSIONS_TO_PERFORM_TASK = 'Insufficient permissions to perform this task' +INTER_BATCH_WAIT_INCREASED = 'inter_batch_wait increased to {0:.2f}' +INVALID = 'Invalid' +INVALID_ALIAS = 'Invalid Alias' +INVALID_ATTENDEE_CHANGE = 'Invalid attendee change "{0}"' +INVALID_CHARSET = 'Invalid charset "{0}"' +INVALID_DATE_TIME_RANGE = '{0} {1} must be greater than/equal to {2} {3}' +INVALID_DEVICE_QUERY = 'Invalid {0} query "{1}"; it must be if the form "field:value" and must not contain a "?"' +INVALID_EMOJI_NAME = '{0} does not match pattern :[0-9a-z_-]:' +INVALID_ENTITY = 'Invalid {0}, {1}' +INVALID_EVENT_TIMERANGE = '{0} {1} must be less than {2}' +INVALID_FILE_SELECTION_WITH_ADMIN_ACCESS = 'Invalid file selection with adminaccess|asadmin' +INVALID_GROUP = 'Invalid Group' +INVALID_HTTP_HEADER = 'Invalid http header data: {0}' +INVALID_JSON_INFORMATION = 'Google API reported Invalid JSON Information' +INVALID_JSON_SETTING = 'Invalid JSON setting' +INVALID_LIST = 'Invalid list' +INVALID_MEMBER = 'Invalid Member address' +INVALID_MESSAGE_ID = 'Invalid message id(s)' +INVALID_MIMETYPE = 'Invalid mimeType {0}, must be {1}' +INVALID_NUMBER_OF_CHAT_SPACE_MEMBERS = '{0} type {1} number of members, {2}, must be in range {3} to {4}' +INVALID_ORGUNIT = 'Invalid Organizational Unit' +INVALID_PATH = 'Invalid Path' +INVALID_PERMISSION_ATTRIBUTE_TYPE = 'permission attribute {0} not allowed with type {1}' +INVALID_REGION = 'See: https://github.com/GAM-team/GAM/wiki/Context-Aware-Access-Levels#caa-region-codes' +INVALID_QUERY = 'Invalid Query' +INVALID_RE = 'Invalid RE' +INVALID_REQUEST = 'Invalid Request' +INVALID_RESELLER_CUSTOMER_NAME = 'name must be: accounts//customers/' +INVALID_ROLE = 'Invalid subkeyfield Role, must be one of: {0}' +INVALID_SCHEMA_VALUE = 'Invalid Schema Value' +INVALID_SCOPE = 'Invalid Scope' +INVALID_SITE = 'Invalid Site ({0}), must match pattern ({1})' +INVALID_TAG_SPECIFICATION = 'Invalid tag, expected field.subfield or field.subfield.subfield.string' +INVALID_TIMEOFDAY_RANGE = '{0} must be less than/equal to {1}' +IN_SKIPIDS = 'In skipids' +IN_THE = ' in the {0}' +IN_TRASH_AND_EXCLUDE_TRASHED = 'In Trash and excludeTrashed' +IS_EXPIRED_OR_REVOKED = '{0}: {1}, Is expired or has been revoked' +IS_NOT_DONE_CHECKING_IN_SECONDS = 'Is not done, checking again in {0} seconds' +IS_NOT_UNIQUE = 'Is not unique, {0}: {1}' +IS_REQD_TO_CHG_PWD_NO_DELEGATION = 'Is required to change password at next login. You must change password or clear changepassword flag for delegation.' +IS_SUSPENDED_NO_BACKUPCODES = 'User is suspended. You must unsuspend to process backupcodes' +IS_SUSPENDED_NO_DELEGATION = 'Is suspended. You must unsuspend for delegation.' +IS_YUBIKEY_INSERTED = 'Is YubiKey inserted?' +JSON_ERROR = 'JSON error "{0}" in file {1}' +JSON_KEY_NOT_FOUND = 'JSON key "{0}" not found in file {1}' +KIOSK_MODE_REQUIRED = ' This command ({0}) requires that the ChromeOS device be in Kiosk mode.' +LESS_THAN_1_SECOND = 'less than 1 second' +LIST_CHROMEOS_INVALID_INPUT_PAGE_TOKEN_RETRY = 'List ChromeOSdevices Invalid Input: pageToken retry' +LOGGING_INITIALIZATION_ERROR = 'Logging initialization error: {0}' +LOOKING_UP_GOOGLE_UNIQUE_ID = 'Looking up Google Unique ID' +MAP_PERMISSIONS_EMAIL_FILE_HEADERS_REQUIRED = '{0} requires headers "sourceEmail" and "destinationEmail"' +MARKED_AS = 'Marked as' +MATCHED_THE_FOLLOWING = 'Matched the following' +MATTER_NOT_OPEN = 'Matter needs to be open, current state is: {0}' +MAXIMUM_OF = 'maximum of' +MEMBERSHIP_IS_PENDING_WILL_DELETE_ADD_TO_ACCEPT = 'Membership is pending, will delete and add to accept' +MIMETYPE_MISMATCH = 'Shortcut target mimeType {0} does not match actual target mimeType {1}' +MIMETYPE_NOT_PRESENT_IN_ATTACHMENT = 'MIME type not present in attachment' +MISMATCH_RE_SEARCH_REPLACE_SUBFIELDS = 'The subfield ({2}) in replace "{3}" exceeds the number of subfields ({0}) in search "{1}"' +MISMATCH_SEARCH_REPLACE_SUBFIELDS = 'The number of subfields ({0}) in search "{1}" does not match the number of subfields ({2}) in replace "{3}"' +MISSING_FIELDS = 'Missing fields: {0}\n' +MULTIPLE_BUILDINGS_SAME_NAME = '{0} {1} with the same (case-insensitive) name exist' +MULTIPLE_ENTITIES_FOUND = 'Multiple {0} ({1}) found, {2}' +MULTIPLE_ITEMS_SPECIFIED = 'Multiple {0} are specfied, only one is allowed' +MULTIPLE_ITEMS_MARKED_PRIMARY = 'Multiple {0} are marked primary, only one can be primary' +MULTIPLE_PARENTS_SPECIFIED = 'Multiple parents ({0}) specified, only one is allowed' +MULTIPLE_SEARCH_METHODS_SPECIFIED = 'Multiple search methods ({0}) specified, only one is allowed' +MULTIPLE_SSO_PROFILES_MATCH = 'Multiple SSO profiles match display name {0}:\n' +MULTIPLE_YUBIKEYS_CONNECTED = 'Multiple YubiKeys connected. Specify yubikey_serial_number and one of {0}\n' +MUST_BE_NUMERIC = 'Must be numeric' +NEED_READ_ACCESS = 'Need Read access' +NEED_READ_WRITE_ACCESS = 'Need Read/Write access' +NEED_WRITE_ACCESS = 'Need Write access' +NESTED_LOOP_CMD_NOT_ALLOWED = 'Command can not be nested.' +NEWUSER_REQUIREMENTS = 'newuser option requires: at least 1 recipient and givenname, familyname and password options' +NEW_OWNER_MUST_DIFFER_FROM_OLD_OWNER = 'New owner must differ from old owner' +NO_DATA = 'No data' +NON_BLANK = 'Non-blank' +NON_EMPTY = 'Non-empty' +NOT_A = 'Not a' +NOT_A_PRIMARY_EMAIL_ADDRESS = 'Not a primary email address' +NOT_A_MEMBER = 'Not a member' +NOT_ACTIVE = 'Not Active' +NOT_ALLOWED = 'Not Allowed' +NOT_AN_ENTITY = 'Not a {0}' +NOT_APPROPRIATE = 'Not Appropriate' +NOT_COMPATIBLE = 'Not Compatible' +NOT_COPYABLE = 'Not Copyable' +NOT_COPYABLE_INTO_ITSELF = 'Not copyable into itself' +NOT_COPYABLE_SAME_NAME_CURRENT_FOLDER_MERGE = 'Not copyable with same name into current folder with duplicatefolders merge' +NOT_COPYABLE_SAME_NAME_CURRENT_FOLDER_OVERWRITE = 'Not copyable with same name into current folder with duplicatefiles overwriteall|overwriteolder' +NOT_DELETABLE = 'Not Deletable' +NOT_FOUND = 'Not Found' +NOT_MOVABLE = 'Not Movable' +NOT_MOVABLE_IN_TRASH = 'Not Movable, in Trash' +NOT_MOVABLE_INTO_ITSELF = 'Not movable into itself' +NOT_MOVABLE_SAME_NAME_CURRENT_FOLDER_MERGE = 'Not movable with same name into current folder with duplicatefolders merge' +NOT_MOVABLE_SAME_NAME_CURRENT_FOLDER_OVERWRITE = 'Not movable with same name into current folder with duplicatefiles overwriteall|overwriteolder' +NOT_OWNED_BY = 'Not owned by {0}' +NOT_SELECTED = 'Not Selected' +NOT_WRITABLE = 'Not Writable' +NOW_THE_PRIMARY_DOMAIN = 'Now the primary domain' +NO_ACTION_SPECIFIED = 'No action specified' +NO_AVAILABLE_LICENSES = "There aren't enough available licenses for the specified product-SKU pair(s)" +NO_CHANGES = 'No changes' +NO_CLIENT_ACCESS_ALLOWED = 'No Client Access allowed' +NO_CLIENT_ACCESS_CREATE_UPDATE_ALLOWED = 'No Client Access create/update allowed' +NO_COLUMNS_SELECTED_WITH_CSV_OUTPUT_HEADER_FILTER = 'No columns selected with {0} and {1}' +NO_CREDENTIALS_REPLACEMENT = '{0}: {1} has {2} {3}. We only replace if there are 2.\n' +NO_CSV_DATA_TO_UPLOAD = 'No CSV data to upload' +NO_CSV_FILE_DATA_FOUND = 'No CSV file data found' +NO_CSV_FILE_DATA_SAVED = 'No CSV file data saved' +NO_CSV_FILE_SUBKEYS_SAVED = 'No CSV file subkeys saved' +NO_DATA_TRANSFER_APP_FOR_PARAMETER = 'No data transfer application for key {0}' +NO_ENTITIES_FOUND = 'No {0} found' +NO_ENTITIES_MATCHED = 'No {0} matched' +NO_FILTER_ACTIONS = 'No {0} actions specified' +NO_FILTER_CRITERIA = 'No {0} criteria specified' +NO_LABELS_MATCH = 'No Labels match' +NO_LABELS_TO_PROCESS = 'No Labels to process' +NO_MESSAGES_WITH_LABEL = 'No Messages with Label' +NO_PARENTS_TO_CONVERT_TO_SHORTCUTS = 'No parents to convert to shortcuts' +NO_REPORT_AVAILABLE = 'No {0} report available.' +NO_SCOPES_FOR_API = 'There are no scopes authorized for the API(s): {0}' +NO_SERIAL_NUMBERS_SPECIFIED = 'No serial numbers specified' +NO_SSO_PROFILE_MATCHES = 'No SSO profile matches display name {0}' +NO_SSO_PROFILE_ASSIGNED = 'No SSO profile assigned to {0} {1}' +NO_SVCACCT_ACCESS_ALLOWED = 'No Service Account Access allowed' +NO_TRANSFER_LACK_OF_DISK_SPACE = 'Transfer not performed due to lack of target drive space.' +NO_USAGE_PARAMETERS_DATA_AVAILABLE = 'No usage parameters data available.' +NO_USER_COUNTS_DATA_AVAILABLE = 'No User counts data available.' +NUM_SELECTED_CLIENT_SCOPES = '\n{0} scopes are selected, if more than {1} scopes are selected, Google will probably generate a "Something went wrong" error\n' +OAUTH2_GO_TO_LINK_MESSAGE = """ +Go to the following link in a browser on this computer or on another computer: + + {url} + +If you use a browser on another computer, you will get a browser error that the site can't be reached AFTER you +click the Allow button, paste "Unable to connect" URL from other computer (only URL data up to &scope required): +""" +ON_CURRENT_PRIVATE_KEY = ' on current key' +ON_VAULT_HOLD = 'On Google Vault Hold' +ONLY_ADMINISTRATORS_CAN_PERFORM_SHARED_DRIVE_QUERIES = 'Only administrators can perform Shared Drive queries' +ONLY_ADMINISTRATORS_CAN_SPECIFY_SHARED_DRIVE_ORGUNIT = 'Only administrators can specify Shared Drive Org Unit' +ONLY_ONE_DEVICE_SELECTION_ALLOWED = 'Only one device selection allowed, filter = "{0}"' +ONLY_ONE_JSON_RANGE_ALLOWED = 'Only one range/json allowed' +ONLY_ONE_OWNER_ALLOWED = 'Only one owner allowed' +OR = 'or' +OU_AND_MOVETOOU_CANNOT_BE_IDENTICAL = 'ou {0} can not be be identical to movetoou {1}' +OU_SUBOUS_CANNOT_BE_MOVED_TO_MOVETOOU = 'ou {0} sub OUs can not be be moved to movetoou {1}' +PERMISSION_DENIED = 'The caller does not have permission' +PLEASE_CORRECT_YOUR_SYSTEM_TIME = 'Please correct your system time.' +PLEASE_ENTER_A_OR_M = 'Please enter a or m ...\n' +PLEASE_SELECT_ENTITY_TO_PROCESS = '{0} {1} found, please select the correct one to {2} and specify with {3}' +PLEASE_SPECIFY_BUILDING_EXACT_CASE_NAME_OR_ID = 'Please specify building by exact case name or ID.' +POLICY_NAME_NOT_FOUND = 'JSON key "name" not found in JSON data' +PREVIEW_ONLY = 'Preview Only' +PRIMARY_EMAIL_DID_NOT_MATCH_PATTERN = 'primaryEmail address did not match pattern: {0}' +PROCESS = 'process' +PROCESSES = 'processes' +PROCESSING_ITEM_N = '{0},0,Processing item {1}\n' +PROCESSING_ITEM_N_OF_M = '{0},0,Processing item {1}/{2}\n' +PROFILE_PHOTO_NOT_FOUND = 'Profile photo not found' +PROFILE_PHOTO_IS_DEFAULT = 'Profile photo is default' +QUOTA_EXCEEDED = 'Quota exceeded' +REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid with contentrestrictions readonly true' +REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create' +RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n' +REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.' +REFUSING_TO_DEPROVISION_N_DEVICES = 'Refusing to deprovision {0} devices due to maxtodepov {1}.\nSpecify "maxtodeprov 0" to deprovision all {0} devices' +REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo ' +REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again' +REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}' +RERUN_THE_COMMAND_AND_SPECIFY_A_NEW_SANAME = """ +Re-run the command specify a new service account name with: saname +See: https://github.com/GAM-team/GAM/wiki/Authorization#advanced-use +""" +RESOURCE_CAPACITY_FLOOR_REQUIRED = 'Options "capacity " ( > 0) and "floor " required' +RESOURCE_FLOOR_REQUIRED = 'Option "floor " required' +RESULTS_TOO_LARGE_FOR_GOOGLE_SPREADSHEET = 'Results are too large for Google Spreadsheets. Uploading as a regular CSV file.' +RETRIES_EXHAUSTED = 'Retries {0} exhausted' +RETRYING_GOOGLE_SHEET_EXPORT_SLEEPING = 'Retrying Google Sheet export {0}/{1}. Sleeping {2} seconds\n' +ROLE_MUST_BE_ORGANIZER = 'Role must be organizer' +ROLE_NOT_IN_SET = 'Role not in set: {0})' +SCHEMA_WOULD_HAVE_NO_FIELDS = '{0} would have no {1}' +SELECTED = 'Selected' +SERVICE_NOT_APPLICABLE = 'Service not applicable/Does not exist' +SERVICE_NOT_APPLICABLE_THIS_ADDRESS = 'Service not applicable for this address: {0}' +SERVICE_NOT_ENABLED = '{0} Service/App not enabled' +SHORTCUT_TARGET_CAPABILITY_IS_FALSE = '{0} capability {1} is False' +SITES_COMMAND_DEPRECATED = 'The Classic Sites API is deprecated, this command will not work:\n{0}' +SKU_HAS_NO_MATCHING_ARCHIVED_USER_SKU = 'SKU {0} has no matching Archived User SKU' +STARTING_THREAD = 'Starting thread' +STATISTICS_COPY_FILE = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Copy Failed: {5}, Not copyable: {6}, In skipids: {7}, Permissions Failed: {8}, Protected Ranges Failed: {9}' +STATISTICS_COPY_FOLDER = 'Total: {0}, Copied: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Merged: {5}, Copy Failed: {6}, Not writable: {7}, Permissions Failed: {8}' +STATISTICS_MOVE_FILE = 'Total: {0}, Moved: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Move Failed: {5}, Not movable: {6}' +STATISTICS_MOVE_FOLDER = 'Total: {0}, Moved: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Merged: {5}, Move Failed: {6}, Not writable: {7}' +STATISTICS_USER_NOT_ORGANIZER = 'User not organizer: {0}' +STRING_LENGTH = 'string length' +STUDENT_NOT_IN_COURSE = 'Student not in course' +SUBKEY_FIELD_MISMATCH = 'subkeyfield {0} does not match saved subkeyfield {1}' +SUBSCRIPTION_NOT_FOUND = 'Could not find subscription' +SUFFIX_NOT_ALLOWED_WITH_CUSTOMLANGUAGE = 'Suffix {0} not allowed with customLanguage {1}' +TASKLIST_TITLE_NOT_FOUND = 'Task list title not found' +THREAD = 'thread' +THREADS = 'threads' +TO = 'To' +TO_LC = 'to' +TO_MAXIMUM_OF = 'to maximum of' +TO_SET_UP_GOOGLE_CHAT = """ +To set up Google Chat for your current project, please go to: + + {0} + +and follow the instructions at: + + https://github.com/GAM-team/GAM/wiki/Chat-Bot-Setup-Use#set-up-a-chat-bot + + You'll use projects/{1}/topics/no-topic in Connection settings Cloud Pub/Sub Topic Name +""" +TOTAL_ITEMS_IN_ENTITY = 'Total {0} in {1}' +TRIMMED_MESSAGE_FROM_LENGTH_TO_MAXIMUM = 'Trimmed message of length {0} to maximum length {1}' +UNABLE_TO_GET_PERMISSION_ID = 'Unable to get Permission ID for <{0}>' +UNABLE_TO_CREATE_NOT_FOUND_USER = 'Unable to create not found user, some required field (givenName, familyName, password/notfoundpassword) not present' +UNAVAILABLE = 'Unavailable' +UNKNOWN = 'Unknown' +UNKNOWN_API_OR_VERSION = 'Unknown Google API or version: ({0}), contact {1}' +UNRECOVERABLE_ERROR = 'Unrecoverable error' +UPDATE_ATTENDEE_CHANGES = 'Update attendee changes' +UPDATE_GAM_TO_64BIT = "You're running a 32-bit version of GAM on a 64-bit version of Windows, upgrade to a windows-x86_64 version of GAM" +UPDATE_PRIMARY_EMAIL_PREVIEW = 'updateprimaryemail preview: {0}' +UPDATE_USER_PASSWORD_CHANGE_NOTIFY_MESSAGE = 'The account password for #givenname# #familyname#, #user# has been changed to: #password#\n' +UPDATE_USER_PASSWORD_CHANGE_NOTIFY_SUBJECT = 'Account #user# password has been changed' +UPLOAD_CSV_FILE_INTERNAL_ERROR = 'Google reported "{0}" but the file was probably uploaded, check that it has {1} rows' +UPLOADING_NEW_PUBLIC_CERTIFICATE_TO_GOOGLE = 'Uploading new public certificate to Google...\n' +URL_ERROR = 'URL error: {0}' +USE_MIMETYPE_TO_SPECIFY_GOOGLE_FORMAT = 'Use "mimetype " to specify Google file format\n' +USED = 'Used' +USER_BELONGS_TO_N_GROUPS_THAT_MAP_TO_ORGUNITS = 'User belongs to {0} groups ({1}) that map to OUs' +USER_CANCELLED = 'User cancelled' +USER_HAS_MULTIPLE_DIRECT_OR_INHERITED_MEMBERSHIPS_IN_GROUP = 'User has multiple direct or inherited memberships in group' +USER_IN_OTHER_DOMAIN = '{0}: {1} in other domain.' +USER_IS_NOT_ORGANIZER = 'User is not organizer, use anyorganizer option to override' +USER_NOT_IN_MATCHUSERS = 'User not in matchusers' +USER_SUBS_NOT_ALLOWED_TAG_REPLACEMENT = 'user substitutions not allowed in replace ' +USE_DOIT_ARGUMENT_TO_PERFORM_ACTION = 'Use the "doit" argument to perform action' +USING_N_PROCESSES = '{0},0/{1},Using {2} {3}...\n' +VALUES_ARE_NOT_CONSISTENT = 'Values are not consistent' +VERSION_UPDATE_AVAILABLE = 'Version update available' +WAITING_FOR_DATA_TRANSFER_TO_COMPLETE_SLEEPING = 'Waiting for Data Transfer to complete. Sleeping {0} seconds\n' +WAITING_FOR_ITEM_CREATION_TO_COMPLETE_SLEEPING = 'Waiting for {0} creation to complete. Sleeping {1} seconds\n' +WHAT_IS_YOUR_PROJECT_ID = '\nWhat is your project ID? ' +WILL_RERUN_WITH_NO_BROWSER_TRUE = 'Will re-run command with no_browser true\n' +WITH = 'with' +WOULD_MAKE_MEMBERSHIP_CYCLE = 'Would make membership cycle' +WRITER_ACCESS_REQUIRED_TO_BOTH_CALENDARS = 'Writer access required to both calendars' +WROTE_PRIVATE_KEY_DATA = 'Wrote private key data to {0}\n' +WROTE_PUBLIC_CERTIFICATE = 'Wrote public certificate to {0}\n' +YOU_CAN_ADD_DOMAIN_TO_ACCOUNT = 'You can now add: {0} or its subdomains as secondary or domain aliases of the Google Workspace Account: {1}' +YUBIKEY_GENERATING_NONEXPORTABLE_PRIVATE_KEY = 'YubiKey is generating a non-exportable private key...\n' +YUBIKEY_PIN_SET_TO = 'YubiKey PIN set to: {0}\n' diff --git a/src/gam/gamlib/settings.py b/src/gam/gamlib/settings.py new file mode 100644 index 00000000..d00f5da1 --- /dev/null +++ b/src/gam/gamlib/settings.py @@ -0,0 +1,653 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM gam.cfg variables + +""" + +import os + +TRUE = 'true' +FALSE = 'false' +DEFAULT_CHARSET = 'utf-8' +MY_CUSTOMER = 'my_customer' +NEVER = 'Never' +TLS_CHOICE_MAP = { + '': '', + 'tlsv1_2': 'TLSv1_2', 'tlsv1.2': 'TLSv1_2', + 'tlsv1_3': 'TLSv1_3', 'tlsv1.3': 'TLSv1_3', + } + +FN_CACERTS_PEM = 'cacerts.pem' +FN_CLIENT_SECRETS_JSON = 'client_secrets.json' +FN_EXTRA_ARGS_TXT = 'extra-args.txt' +FN_OAUTH2_TXT = 'oauth2.txt' +FN_OAUTH2SERVICE_JSON = 'oauth2service.json' + +# Global variables defined in gam.cfg + +# The following XXX constants are the names of the items in gam.cfg +# When retrieving lists of Google Drive activities from API, how many should be retrieved in each chunk +ACTIVITY_MAX_RESULTS = 'activity_max_results' +# Admin email address, required when enable_dasa is true, overrides oauth2.txt value otherwise +ADMIN_EMAIL = 'admin_email' +# Check if API calls rate exceeds limit +API_CALLS_RATE_CHECK = 'api_calls_rate_check' +# API calls per 100 seconds limit +API_CALLS_RATE_LIMIT = 'api_calls_rate_limit' +# API calls tries limit +API_CALLS_TRIES_LIMIT = 'api_calls_tries_limit' +# Automatically generate gam batch command if number of users specified in gam users xxx command exceeds this number +# Default: 0, do not automatically generate gam batch commands +AUTO_BATCH_MIN = 'auto_batch_min' +# When bailing on internal errors, how many total tries should be performed +BAIL_ON_INTERNAL_ERROR_TRIES = 'bail_on_internal_error_tries' +# When processing items in batches, how many should be processed in each batch +BATCH_SIZE = 'batch_size' +# Location of cacerts.pem for API calls +CACERTS_PEM = 'cacerts_pem' +# GAM cache directory +CACHE_DIR = 'cache_dir' +# GAM cache discovery only. If no_cache is False, only API discovery calls will be cached +CACHE_DISCOVERY_ONLY = 'cache_discovery_only' +# Channel custmerId from gam.cfg +CHANNEL_CUSTOMER_ID = 'channel_customer_id' +# Character set of batch, csv, data files +CHARSET = 'charset' +# When retrieving lists of Chat items from API, how many should be retrieved in each chunk +CHAT_MAX_RESULTS = 'chat_max_results' +# When retrieving lists of Google Classroom items from API, how many should be retrieved in each chunk +CLASSROOM_MAX_RESULTS = 'classroom_max_results' +# Path to client_secrets.json +CLIENT_SECRETS_JSON = 'client_secrets_json' +# Allowed clock skew in seconds +CLOCK_SKEW_IN_SECONDS = 'clock_skew_in_seconds' +# Command logging filename +CMDLOG = 'cmdlog' +# Bogus Command logging maximum number of backup log files +CMDLOG_MAX__BACKUPS = 'cmdlog_max__backups' +# Command logging maximum number of backup log files +CMDLOG_MAX_BACKUPS = 'cmdlog_max_backups' +# Command logging max kilo bytes per log file +CMDLOG_MAX_KILO_BYTES = 'cmdlog_max_kilo_bytes' +# Use client access for command data from Google Docs/Sheets +COMMANDDATA_CLIENTACCESS = 'commanddata_clientaccess' +# GAM config directory containing client_secrets.json, oauth2.txt, oauth2service.json, extra_args.txt +CONFIG_DIR = 'config_dir' +# When retrieving lists of Google Contacts from API, how many should be retrieved in each chunk +CONTACT_MAX_RESULTS = 'contact_max_results' +# Column delimiter in CSV input file +CSV_INPUT_COLUMN_DELIMITER = 'csv_input_column_delimiter' +# No escape character in CSV input file +CSV_INPUT_NO_ESCAPE_CHAR = 'csv_input_no_escape_char' +# Quote character in CSV input file +CSV_INPUT_QUOTE_CHAR = 'csv_input_quote_char' +# Filter for input column values +CSV_INPUT_ROW_FILTER = 'csv_input_row_filter' +# Mode (and|or) for input column values +CSV_INPUT_ROW_FILTER_MODE = 'csv_input_row_filter_mode' +# Filter for input column drop values +CSV_INPUT_ROW_DROP_FILTER = 'csv_input_row_drop_filter' +# Mode (and|or) for input column drop values +CSV_INPUT_ROW_DROP_FILTER_MODE = 'csv_input_row_drop_filter_mode' +# Limit number of input rows +CSV_INPUT_ROW_LIMIT = 'csv_input_row_limit' +# Convert newlines in text fields to "\n" in CSV output file +CSV_OUTPUT_CONVERT_CR_NL = 'csv_output_convert_cr_nl' +# Column delimiter in CSV output file +CSV_OUTPUT_COLUMN_DELIMITER = 'csv_output_column_delimiter' +# No escape character in CSV output file +CSV_OUTPUT_NO_ESCAPE_CHAR = 'csv_output_no_escape_char' +# Field list delimiter in CSV output file +CSV_OUTPUT_FIELD_DELIMITER = 'csv_output_field_delimiter' +# Filter for output column headers +CSV_OUTPUT_HEADER_FILTER = 'csv_output_header_filter' +# Filter for output column headers to drop +CSV_OUTPUT_HEADER_DROP_FILTER = 'csv_output_header_drop_filter' +# Force output column headers +CSV_OUTPUT_HEADER_FORCE = 'csv_output_header_force' +# Orde output column headers +CSV_OUTPUT_HEADER_ORDER = 'csv_output_header_order' +# Required output column headers +CSV_OUTPUT_HEADER_REQUIRED = 'csv_output_header_required' +# Line terminator in CSV output file +CSV_OUTPUT_LINE_TERMINATOR = 'csv_output_line_terminator' +# Quote character in CSV output file +CSV_OUTPUT_QUOTE_CHAR = 'csv_output_quote_char' +# Filter for output column values +CSV_OUTPUT_ROW_FILTER = 'csv_output_row_filter' +# Mode (and|or) for output column values +CSV_OUTPUT_ROW_FILTER_MODE = 'csv_output_row_filter_mode' +# Filter for output column drop values +CSV_OUTPUT_ROW_DROP_FILTER = 'csv_output_row_drop_filter' +# Mode (and|or) for output column drop values +CSV_OUTPUT_ROW_DROP_FILTER_MODE = 'csv_output_row_drop_filter_mode' +# Limit number of output rows +CSV_OUTPUT_ROW_LIMIT = 'csv_output_row_limit' +# Output sort headers +CSV_OUTPUT_SORT_HEADERS = 'csv_output_sort_headers' +# Column header subfield name delimiter in CSV output file +CSV_OUTPUT_SUBFIELD_DELIMITER = 'csv_output_subfield_delimiter' +# Add timestamp column to CSV output file +CSV_OUTPUT_TIMESTAMP_COLUMN = 'csv_output_timestamp_column' +# Output rows for users even if they do not have the print object (delegate, filters, ...) +CSV_OUTPUT_USERS_AUDIT = 'csv_output_users_audit' +# custmerId from gam.cfg or retrieved from Google +CUSTOMER_ID = 'customer_id' +# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True +DEBUG_LEVEL = 'debug_level' +# redact sensitive credentials from debug output +DEBUG_REDACTION = 'debug_redaction' +# Developer Preview APIs +DEVELOPER_PREVIEW_APIS = 'developer_preview_apis' +# Developer Preview API Key +DEVELOPER_PREVIEW_API_KEY = 'developer_preview_api_key' +# When retrieving lists of ChromeOS devices from API, how many should be retrieved in each chunk +DEVICE_MAX_RESULTS = 'device_max_results' +# Domain obtained from gam.cfg or oauth2.txt +DOMAIN = 'domain' +# directory for file output +DRIVE_DIR = 'drive_dir' +# When retrieving lists of Drive files/folders from API, how many should be retrieved in each chunk +DRIVE_MAX_RESULTS = 'drive_max_results' +# When processing email messages in batches, how many should be processed in each batch +EMAIL_BATCH_SIZE = 'email_batch_size' +# Enable Delegated Admin Service Account +ENABLE_DASA = 'enable_dasa' +# Enable Cloud Session Reauthentication by borrowing a RAPT token from gcloud command +ENABLE_GCLOUD_REAUTH = 'enable_gcloud_reauth' +# When retrieving lists of calendar events from API, how many should be retrieved in each chunk +EVENT_MAX_RESULTS = 'event_max_results' +# Path to extra_args.txt +EXTRA_ARGS = 'extra_args' +# Google Cloud Project Organization ID +GCP_ORG_ID = 'gcp_org_id' +# Gmail CSE certificates directory +GMAIL_CSE_INCERT_DIR = 'gmail_cse_incert_dir' +# Gmail CSE KACL wrapped key files +GMAIL_CSE_INKEY_DIR = 'gmail_cse_inkey_dir' +# directory for file input +INPUT_DIR = 'input_dir' +# When processing items in batches, how many seconds should GAM wait between batches +INTER_BATCH_WAIT = 'inter_batch_wait' +# When retrieving lists of licenses from API, how many should be retrieved in each chunk +LICENSE_MAX_RESULTS = 'license_max_results' +# License SKUs to process +LICENSE_SKUS = 'license_skus' +# When retrieving lists of Google Group members from API, how many should be retrieved in each chunk +MEMBER_MAX_RESULTS = 'member_max_results' +# CI API Group members max page size when view=BASIC +MEMBER_MAX_RESULTS_CI_BASIC = 'member_max_results_ci_basic' +# CI API Group members max page size when view=FULL +MEMBER_MAX_RESULTS_CI_FULL = 'member_max_results_ci_full' +# When deleting or modifying Gmail messages, how many should be processed in each batch +MESSAGE_BATCH_SIZE = 'message_batch_size' +# When retrieving lists of Gmail messages from API, how many should be retrieved in each chunk +MESSAGE_MAX_RESULTS = 'message_max_results' +# When retrieving lists of Mobile devices from API, how many should be retrieved in each chunk +MOBILE_MAX_RESULTS = 'mobile_max_results' +# Number of parallel multiprocess pool.apply_async calls; -1: no limit, 0: NUM_THREADS, >0: specific limit +MULTIPROCESS_POOL_LIMIT = 'multiprocess_pool_limit' +# Value to substitute for NEVER_TIME +NEVER_TIME = 'never_time' +# If no_browser is False, writeCSVfile won't open a browser when todrive is set +# and doOAuthRequest prints a link and waits for the verification code when oauth2.txt is being created +NO_BROWSER = 'no_browser' +# Disable GAM API caching +NO_CACHE = 'no_cache' +# Do noit use URL shortner for authentication URLs +NO_SHORT_URLS = 'no_short_urls' +# Disable GAM update check +NO_UPDATE_CHECK = 'no_update_check' +# Disable SSL certificate validation +NO_VERIFY_SSL = 'no_verify_ssl' +# Number of threads for gam tbatch +NUM_TBATCH_THREADS = 'num_tbatch_threads' +# Number of threads for gam batch/csv +NUM_THREADS = 'num_threads' +# Path to oauth2.txt +OAUTH2_TXT = 'oauth2_txt' +# File permissions for oauth2.txt.lock +OAUTH2_TXT_LOCK_MODE = 'oauth2_txt_lock_mode' +# Path to oauth2service.json +OAUTH2SERVICE_JSON = 'oauth2service_json' +# Output date format, empty defalts to ISOFormat +OUTPUT_DATEFORMAT = 'output_dateformat' +# Output time format, empty defalts to ISOFormat +OUTPUT_TIMEFORMAT = 'output_timeformat' +# When retrieving lists of people from API, how many should be retrieved in each chunk +PEOPLE_MAX_RESULTS = 'people_max_results' +# Domains for print alises|groups|users +PRINT_AGU_DOMAINS = 'print_agu_domains' +# OrgUnits for print cros +PRINT_CROS_OUS = 'print_cros_ous' +# OrgUnits and children for print cros +PRINT_CROS_OUS_AND_CHILDREN = 'print_cros_ous_and_children' +# Number of seconds to wait for batch/csv processes to complete +PROCESS_WAIT_LIMIT = 'process_wait_limit' +# Use quick method to move Chromebooks to OU +QUICK_CROS_MOVE = 'quick_cros_move' +# Quick info user: nogroups nolicenses noschemas +QUICK_INFO_USER = 'quick_info_user' +# resellerId from gam.cfg or retrieved from Google +RESELLER_ID = 'reseller_id' +# Retry service not available errors on API calls +RETRY_API_SERVICE_NOT_AVAILABLE = 'retry_api_service_not_available' +# Default section to use for processing +SECTION = 'section' +# Show API calls retry data +SHOW_API_CALLS_RETRY_DATA = 'show_api_calls_retry_data' +# Show commands when processing batch/csv/loop +SHOW_COMMANDS = 'show_commands' +# Convert newlines in text fields to "\n" in show commands +SHOW_CONVERT_CR_NL = 'show_convert_cr_nl' +# Add (n/m) to end of messages if number of items to be processed exceeds this number +SHOW_COUNTS_MIN = 'show_counts_min' +# Enable/disable "Getting ... " messages +SHOW_GETTINGS = 'show_gettings' +# Enable/disable NL at end of "Got ..." messages +SHOW_GETTINGS_GOT_NL = 'show_gettings_got_nl' +# Enable/disable showing multiprocess info in redirected stdout/stderr +SHOW_MULTIPROCESS_INFO = 'show_multiprocess_info' +# SMTP fqdn +SMTP_FQDN = 'smtp_fqdn' +# SMTP host +SMTP_HOST = 'smtp_host' +# SMTP username +SMTP_USERNAME = 'smtp_username' +# SMTP password +SMTP_PASSWORD = 'smtp_password' +# Time Zone +TIMEZONE = 'timezone' +## Minimum TLS Version required for HTTPS connections +TLS_MIN_VERSION = 'tls_min_version' +## Maximum TLS Version used for HTTPS connections +TLS_MAX_VERSION = 'tls_max_version' +# Clear basic filter when updating an existing sheet +TODRIVE_CLEARFILTER = 'todrive_clearfilter' +# Use client access for todrive +TODRIVE_CLIENTACCESS = 'todrive_clientaccess' +# Enable conversion to Google Sheets when uploading todrive files +TODRIVE_CONVERSION = 'todrive_conversion' +# Save local copy of CSV file +TODRIVE_LOCALCOPY = 'todrive_localcopy' +# Specify locale for Google Sheets +TODRIVE_LOCALE = 'todrive_locale' +# Suppress opening browser on todrive upload +TODRIVE_NOBROWSER = 'todrive_nobrowser' +# Suppress sending email on todrive upload +TODRIVE_NOEMAIL = 'todrive_noemail' +# No escape character in CSV output file +TODRIVE_NO_ESCAPE_CHAR = 'todrive_no_escape_char' +# ID/Name of parent folder for todrive files +TODRIVE_PARENT = 'todrive_parent' +# Append timestamp to todrive sheet name +TODRIVE_SHEET_TIMESTAMP = 'todrive_sheet_timestamp' +# Sheet timestamp format, empty defalts to ISOFormat +TODRIVE_SHEET_TIMEFORMAT = 'todrive_sheet_timeformat' +# Append timestamp to todrive file name +TODRIVE_TIMESTAMP = 'todrive_timestamp' +# Timestamp format, empty defalts to ISOFormat +TODRIVE_TIMEFORMAT = 'todrive_timeformat' +# Specify timezone for Google Sheets +TODRIVE_TIMEZONE = 'todrive_timezone' +# Upload data files with no data +TODRIVE_UPLOAD_NODATA = 'todrive_upload_nodata' +# User for todrive files +TODRIVE_USER = 'todrive_user' +# Truncate Client ID +TRUNCATE_CLIENT_ID = 'truncate_client_id' +# Update CrOS org unit with orgUnitId +UPDATE_CROS_OU_WITH_ID = 'update_cros_ou_with_id' +# Use admin access for chat where possible +USE_CHAT_ADMIN_ACCESS = 'use_chat_admin_access' +# Use course owner for course access +USE_COURSE_OWNER_ACCESS = 'use_course_owner_access' +# Use Project ID as Project Name and App Name +USE_PROJECTID_AS_NAME = 'use_projectid_as_name' +# When retrieving lists of Users from API, how many should be retrieved in each chunk +USER_MAX_RESULTS = 'user_max_results' +# User service account access only, no client access +USER_SERVICE_ACCOUNT_ACCESS_ONLY = 'user_service_account_access_only' + +CSV_INPUT_ROW_FILTER_ITEMS = {CSV_INPUT_ROW_FILTER, CSV_INPUT_ROW_FILTER_MODE, + CSV_INPUT_ROW_DROP_FILTER, CSV_INPUT_ROW_DROP_FILTER_MODE, + CSV_INPUT_ROW_LIMIT} + +CSV_OUTPUT_ROW_FILTER_ITEMS = {CSV_OUTPUT_HEADER_FILTER, CSV_OUTPUT_HEADER_DROP_FILTER, + CSV_OUTPUT_HEADER_FORCE, CSV_OUTPUT_HEADER_ORDER, + CSV_OUTPUT_HEADER_REQUIRED, + CSV_OUTPUT_ROW_FILTER, CSV_OUTPUT_ROW_FILTER_MODE, + CSV_OUTPUT_ROW_DROP_FILTER, CSV_OUTPUT_ROW_DROP_FILTER_MODE, + CSV_OUTPUT_ROW_LIMIT} + +Defaults = { + ACTIVITY_MAX_RESULTS: '100', + ADMIN_EMAIL: '', + API_CALLS_RATE_CHECK: FALSE, + API_CALLS_RATE_LIMIT: '100', + API_CALLS_TRIES_LIMIT: '10', + AUTO_BATCH_MIN: '0', + BAIL_ON_INTERNAL_ERROR_TRIES: '2', + BATCH_SIZE: '50', + CACERTS_PEM: '', + CACHE_DIR: '', + CACHE_DISCOVERY_ONLY: TRUE, + CHARSET: DEFAULT_CHARSET, + CHANNEL_CUSTOMER_ID: '', + CHAT_MAX_RESULTS: '100', + CLASSROOM_MAX_RESULTS: '0', + CLIENT_SECRETS_JSON: FN_CLIENT_SECRETS_JSON, + CLOCK_SKEW_IN_SECONDS: '10', + CMDLOG: '', + CMDLOG_MAX_BACKUPS: 5, + CMDLOG_MAX_KILO_BYTES: 1000, + COMMANDDATA_CLIENTACCESS: FALSE, + CONFIG_DIR: '', + CONTACT_MAX_RESULTS: '100', + CSV_INPUT_COLUMN_DELIMITER: ',', + CSV_INPUT_NO_ESCAPE_CHAR: TRUE, + CSV_INPUT_QUOTE_CHAR: '\'"\'', + CSV_INPUT_ROW_FILTER: '', + CSV_INPUT_ROW_FILTER_MODE: 'allmatch', + CSV_INPUT_ROW_DROP_FILTER: '', + CSV_INPUT_ROW_DROP_FILTER_MODE: 'anymatch', + CSV_INPUT_ROW_LIMIT: '0', + CSV_OUTPUT_COLUMN_DELIMITER: ',', + CSV_OUTPUT_CONVERT_CR_NL: FALSE, + CSV_OUTPUT_NO_ESCAPE_CHAR: FALSE, + CSV_OUTPUT_FIELD_DELIMITER: "' '", + CSV_OUTPUT_HEADER_FILTER: '', + CSV_OUTPUT_HEADER_DROP_FILTER: '', + CSV_OUTPUT_HEADER_FORCE: '', + CSV_OUTPUT_HEADER_ORDER: '', + CSV_OUTPUT_HEADER_REQUIRED: '', + CSV_OUTPUT_LINE_TERMINATOR: 'lf', + CSV_OUTPUT_QUOTE_CHAR: '\'"\'', + CSV_OUTPUT_ROW_FILTER: '', + CSV_OUTPUT_ROW_FILTER_MODE: 'allmatch', + CSV_OUTPUT_ROW_DROP_FILTER: '', + CSV_OUTPUT_ROW_DROP_FILTER_MODE: 'anymatch', + CSV_OUTPUT_ROW_LIMIT: '0', + CSV_OUTPUT_SORT_HEADERS: '', + CSV_OUTPUT_SUBFIELD_DELIMITER: '.', + CSV_OUTPUT_TIMESTAMP_COLUMN: '', + CSV_OUTPUT_USERS_AUDIT: FALSE, + CUSTOMER_ID: MY_CUSTOMER, + DEBUG_LEVEL: '0', + DEBUG_REDACTION: TRUE, + DEVELOPER_PREVIEW_APIS: '', + DEVELOPER_PREVIEW_API_KEY: '', + DEVICE_MAX_RESULTS: '200', + DOMAIN: '', + DRIVE_DIR: '', + DRIVE_MAX_RESULTS: '1000', + EMAIL_BATCH_SIZE: '50', + ENABLE_DASA: FALSE, + ENABLE_GCLOUD_REAUTH: FALSE, + EVENT_MAX_RESULTS: '250', + EXTRA_ARGS: '', + GCP_ORG_ID: '', + GMAIL_CSE_INCERT_DIR: '', + GMAIL_CSE_INKEY_DIR: '', + INPUT_DIR: '.', + INTER_BATCH_WAIT: '0', + LICENSE_MAX_RESULTS: '100', + LICENSE_SKUS: '', + MEMBER_MAX_RESULTS: '200', + MEMBER_MAX_RESULTS_CI_BASIC: '1000', + MEMBER_MAX_RESULTS_CI_FULL: '500', + MESSAGE_BATCH_SIZE: '50', + MESSAGE_MAX_RESULTS: '500', + MOBILE_MAX_RESULTS: '100', + MULTIPROCESS_POOL_LIMIT: '0', + NEVER_TIME: NEVER, + NO_BROWSER: FALSE, + NO_CACHE: FALSE, + NO_SHORT_URLS: TRUE, + NO_UPDATE_CHECK: TRUE, + NO_VERIFY_SSL: FALSE, + NUM_TBATCH_THREADS: '2', + NUM_THREADS: '5', + OAUTH2_TXT: FN_OAUTH2_TXT, + OAUTH2_TXT_LOCK_MODE: '644', + OAUTH2SERVICE_JSON: FN_OAUTH2SERVICE_JSON, + OUTPUT_DATEFORMAT: '', + OUTPUT_TIMEFORMAT: '', + PEOPLE_MAX_RESULTS: '100', + PRINT_AGU_DOMAINS: '', + PRINT_CROS_OUS: '', + PRINT_CROS_OUS_AND_CHILDREN: '', + PROCESS_WAIT_LIMIT: '0', + QUICK_CROS_MOVE: FALSE, + QUICK_INFO_USER: FALSE, + RESELLER_ID: '', + RETRY_API_SERVICE_NOT_AVAILABLE: FALSE, + SECTION: '', + SHOW_API_CALLS_RETRY_DATA: FALSE, + SHOW_COMMANDS: FALSE, + SHOW_CONVERT_CR_NL: FALSE, + SHOW_COUNTS_MIN: '1', + SHOW_GETTINGS: TRUE, + SHOW_GETTINGS_GOT_NL: FALSE, + SHOW_MULTIPROCESS_INFO: FALSE, + SMTP_FQDN: '', + SMTP_HOST: '', + SMTP_USERNAME: '', + SMTP_PASSWORD: '', + TIMEZONE: 'utc', + TLS_MIN_VERSION: 'TLSv1_3', + TLS_MAX_VERSION: '', + TODRIVE_CLEARFILTER: FALSE, + TODRIVE_CLIENTACCESS: FALSE, + TODRIVE_CONVERSION: TRUE, + TODRIVE_LOCALCOPY: FALSE, + TODRIVE_LOCALE: '', + TODRIVE_NOBROWSER: '', + TODRIVE_NOEMAIL: '', + TODRIVE_NO_ESCAPE_CHAR: TRUE, + TODRIVE_PARENT: 'root', + TODRIVE_SHEET_TIMESTAMP: 'copy', # copy from TODRIVE_TIMESTAMP + TODRIVE_SHEET_TIMEFORMAT: 'copy', # copy from TODRIVE_TIMEFORMAT + TODRIVE_TIMESTAMP: FALSE, + TODRIVE_TIMEFORMAT: '', + TODRIVE_TIMEZONE: '', + TODRIVE_UPLOAD_NODATA: TRUE, + TODRIVE_USER: '', + TRUNCATE_CLIENT_ID: FALSE, + UPDATE_CROS_OU_WITH_ID: FALSE, + USE_CHAT_ADMIN_ACCESS: FALSE, + USE_COURSE_OWNER_ACCESS: FALSE, + USE_PROJECTID_AS_NAME: FALSE, + USER_MAX_RESULTS: '500', + USER_SERVICE_ACCOUNT_ACCESS_ONLY: FALSE, + } + +Values = {DEBUG_LEVEL: 0} + +TYPE_BOOLEAN = 'bool' +TYPE_CHARACTER = 'char' +TYPE_CHOICE = 'choi' +TYPE_CHOICE_LIST = 'chol' +TYPE_DATETIME = 'datm' +TYPE_DIRECTORY = 'dire' +TYPE_EMAIL = 'emai' +TYPE_EMAIL_OPTIONAL = 'emao' +TYPE_FILE = 'file' +TYPE_FLOAT = 'floa' +TYPE_HEADERFILTER = 'heaf' +TYPE_HEADERFORCEREQUIRED = 'hefr' +TYPE_HEADERORDER = 'heor' +TYPE_INTEGER = 'inte' +TYPE_LANGUAGE = 'lang' +TYPE_LOCALE = 'locl' +TYPE_PASSWORD = 'pass' +TYPE_ROWFILTER = 'rowf' +TYPE_STRING = 'stri' +TYPE_STRINGLIST = 'strl' +TYPE_TIMEZONE = 'tmzn' + +VAR_TYPE = 'type' +VAR_ENVVAR = 'enva' +VAR_CHOICES = 'chod' +VAR_LIMITS = 'lmit' +VAR_SFFT = 'sfft' +VAR_SIGFILE = 'sigf' +VAR_ACCESS = 'aces' + +VAR_INFO = { + ACTIVITY_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)}, + ADMIN_EMAIL: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_ADMIN_EMAIL', VAR_LIMITS: (0, None)}, + API_CALLS_RATE_CHECK: {VAR_TYPE: TYPE_BOOLEAN}, + API_CALLS_RATE_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (50, None)}, + API_CALLS_TRIES_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (3, 30)}, + AUTO_BATCH_MIN: {VAR_TYPE: TYPE_INTEGER, VAR_ENVVAR: 'GAM_AUTOBATCH', VAR_LIMITS: (0, 100)}, + BAIL_ON_INTERNAL_ERROR_TRIES: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10)}, + BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_ENVVAR: 'GAM_BATCH_SIZE', VAR_LIMITS: (1, 1000)}, + CACERTS_PEM: {VAR_TYPE: TYPE_FILE, VAR_ENVVAR: 'GAM_CA_FILE', VAR_ACCESS: os.R_OK}, + CACHE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMCACHEDIR'}, + CACHE_DISCOVERY_ONLY: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'allcache.txt', VAR_SFFT: (TRUE, FALSE)}, + CHARSET: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GAM_CHARSET', VAR_LIMITS: (1, None)}, + CHANNEL_CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + CHAT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, + CLASSROOM_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, 1000)}, + CLIENT_SECRETS_JSON: {VAR_TYPE: TYPE_FILE, VAR_ENVVAR: 'CLIENTSECRETS', VAR_ACCESS: os.R_OK}, + CLOCK_SKEW_IN_SECONDS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (10, 3600)}, + CMDLOG: {VAR_TYPE: TYPE_FILE, VAR_ACCESS: os.W_OK}, + CMDLOG_MAX_BACKUPS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10)}, + CMDLOG_MAX_KILO_BYTES: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (100, 10000)}, + COMMANDDATA_CLIENTACCESS: {VAR_TYPE: TYPE_BOOLEAN}, + CONFIG_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMUSERCONFIGDIR'}, + CONTACT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10000)}, + CSV_INPUT_COLUMN_DELIMITER: {VAR_TYPE: TYPE_CHARACTER}, + CSV_INPUT_NO_ESCAPE_CHAR: {VAR_TYPE: TYPE_BOOLEAN}, + CSV_INPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER}, + CSV_INPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER}, + CSV_INPUT_ROW_FILTER_MODE: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'allmatch': True, 'anymatch': False}}, + CSV_INPUT_ROW_DROP_FILTER: {VAR_TYPE: TYPE_ROWFILTER}, + CSV_INPUT_ROW_DROP_FILTER_MODE: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'allmatch': True, 'anymatch': False}}, + CSV_INPUT_ROW_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, None)}, + CSV_OUTPUT_COLUMN_DELIMITER: {VAR_TYPE: TYPE_CHARACTER}, + CSV_OUTPUT_CONVERT_CR_NL: {VAR_TYPE: TYPE_BOOLEAN}, + CSV_OUTPUT_NO_ESCAPE_CHAR: {VAR_TYPE: TYPE_BOOLEAN}, + CSV_OUTPUT_FIELD_DELIMITER: {VAR_TYPE: TYPE_CHARACTER}, + CSV_OUTPUT_HEADER_FILTER: {VAR_TYPE: TYPE_HEADERFILTER}, + CSV_OUTPUT_HEADER_DROP_FILTER: {VAR_TYPE: TYPE_HEADERFILTER}, + CSV_OUTPUT_HEADER_FORCE: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED}, + CSV_OUTPUT_HEADER_ORDER: {VAR_TYPE: TYPE_HEADERORDER}, + CSV_OUTPUT_HEADER_REQUIRED: {VAR_TYPE: TYPE_HEADERFORCEREQUIRED}, + CSV_OUTPUT_LINE_TERMINATOR: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'cr': '\r', 'lf': '\n', 'crlf': '\r\n'}}, + CSV_OUTPUT_QUOTE_CHAR: {VAR_TYPE: TYPE_CHARACTER}, + CSV_OUTPUT_ROW_FILTER: {VAR_TYPE: TYPE_ROWFILTER}, + CSV_OUTPUT_ROW_FILTER_MODE: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'allmatch': True, 'anymatch': False}}, + CSV_OUTPUT_ROW_DROP_FILTER: {VAR_TYPE: TYPE_ROWFILTER}, + CSV_OUTPUT_ROW_DROP_FILTER_MODE: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'allmatch': True, 'anymatch': False}}, + CSV_OUTPUT_ROW_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, None)}, + CSV_OUTPUT_SORT_HEADERS: {VAR_TYPE: TYPE_STRINGLIST}, + CSV_OUTPUT_SUBFIELD_DELIMITER: {VAR_TYPE: TYPE_CHARACTER}, + CSV_OUTPUT_TIMESTAMP_COLUMN: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + CSV_OUTPUT_USERS_AUDIT: {VAR_TYPE: TYPE_BOOLEAN}, + CUSTOMER_ID: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'CUSTOMER_ID', VAR_LIMITS: (0, None)}, + DEBUG_LEVEL: {VAR_TYPE: TYPE_INTEGER, VAR_SIGFILE: 'debug.gam', VAR_LIMITS: (0, None), VAR_SFFT: ('0', '4')}, + DEBUG_REDACTION: {VAR_TYPE: TYPE_BOOLEAN}, + DEVELOPER_PREVIEW_APIS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + DEVELOPER_PREVIEW_API_KEY: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + DEVICE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)}, + DOMAIN: {VAR_TYPE: TYPE_STRING, VAR_ENVVAR: 'GA_DOMAIN', VAR_LIMITS: (0, None)}, + DRIVE_DIR: {VAR_TYPE: TYPE_DIRECTORY, VAR_ENVVAR: 'GAMDRIVEDIR'}, + DRIVE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, + EMAIL_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)}, + ENABLE_DASA: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'enabledasa.txt', VAR_SFFT: (FALSE, TRUE)}, + ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN}, + EVENT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 2500)}, + EXTRA_ARGS: {VAR_TYPE: TYPE_FILE, VAR_SIGFILE: FN_EXTRA_ARGS_TXT, VAR_SFFT: ('', FN_EXTRA_ARGS_TXT), VAR_ACCESS: os.R_OK}, + GCP_ORG_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + GMAIL_CSE_INCERT_DIR: {VAR_TYPE: TYPE_DIRECTORY}, + GMAIL_CSE_INKEY_DIR: {VAR_TYPE: TYPE_DIRECTORY}, + INPUT_DIR: {VAR_TYPE: TYPE_DIRECTORY}, + INTER_BATCH_WAIT: {VAR_TYPE: TYPE_FLOAT, VAR_LIMITS: (0.0, 60.0)}, + LICENSE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (10, 1000)}, + LICENSE_SKUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + MEMBER_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 200)}, + MEMBER_MAX_RESULTS_CI_BASIC: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, + MEMBER_MAX_RESULTS_CI_FULL: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)}, + MESSAGE_BATCH_SIZE: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, + MESSAGE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 10000)}, + MOBILE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 100)}, + MULTIPROCESS_POOL_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (-1, None)}, + NEVER_TIME: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + NO_BROWSER: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'nobrowser.txt', VAR_SFFT: (FALSE, TRUE)}, + NO_CACHE: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'nocache.txt', VAR_SFFT: (FALSE, TRUE)}, + NO_SHORT_URLS: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'noshorturls.txt', VAR_SFFT: (FALSE, TRUE)}, + NO_UPDATE_CHECK: {VAR_TYPE: TYPE_BOOLEAN}, + NO_VERIFY_SSL: {VAR_TYPE: TYPE_BOOLEAN}, + NUM_TBATCH_THREADS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 1000)}, + NUM_THREADS: {VAR_TYPE: TYPE_INTEGER, VAR_ENVVAR: 'GAM_THREADS', VAR_LIMITS: (1, 1000)}, + OAUTH2_TXT: {VAR_TYPE: TYPE_FILE, VAR_ENVVAR: 'OAUTHFILE', VAR_ACCESS: os.R_OK | os.W_OK}, + OAUTH2_TXT_LOCK_MODE: {VAR_TYPE: TYPE_CHOICE, VAR_CHOICES: {'644': 0o644, '664': 0o664, '666': 0o666}}, + OAUTH2SERVICE_JSON: {VAR_TYPE: TYPE_FILE, VAR_ENVVAR: 'OAUTHSERVICEFILE', VAR_ACCESS: os.R_OK | os.W_OK}, + OUTPUT_DATEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + OUTPUT_TIMEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + PEOPLE_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, 1000)}, + PRINT_AGU_DOMAINS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + PRINT_CROS_OUS: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + PRINT_CROS_OUS_AND_CHILDREN: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + PROCESS_WAIT_LIMIT: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, None)}, + QUICK_CROS_MOVE: {VAR_TYPE: TYPE_BOOLEAN}, + QUICK_INFO_USER: {VAR_TYPE: TYPE_BOOLEAN}, + RESELLER_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + RETRY_API_SERVICE_NOT_AVAILABLE: {VAR_TYPE: TYPE_BOOLEAN}, + SECTION: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + SHOW_API_CALLS_RETRY_DATA: {VAR_TYPE: TYPE_BOOLEAN}, + SHOW_COMMANDS: {VAR_TYPE: TYPE_BOOLEAN}, + SHOW_CONVERT_CR_NL: {VAR_TYPE: TYPE_BOOLEAN}, + SHOW_COUNTS_MIN: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (0, 100)}, + SHOW_GETTINGS: {VAR_TYPE: TYPE_BOOLEAN}, + SHOW_GETTINGS_GOT_NL: {VAR_TYPE: TYPE_BOOLEAN}, + SHOW_MULTIPROCESS_INFO: {VAR_TYPE: TYPE_BOOLEAN}, + SMTP_FQDN: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + SMTP_HOST: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + SMTP_USERNAME: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + SMTP_PASSWORD: {VAR_TYPE: TYPE_PASSWORD, VAR_LIMITS: (0, None)}, + TIMEZONE: {VAR_TYPE: TYPE_TIMEZONE}, + TLS_MIN_VERSION: {VAR_TYPE: TYPE_CHOICE, VAR_ENVVAR: 'GAM_TLS_MIN_VERSION', VAR_CHOICES: TLS_CHOICE_MAP}, + TLS_MAX_VERSION: {VAR_TYPE: TYPE_CHOICE, VAR_ENVVAR: 'GAM_TLS_MAX_VERSION', VAR_CHOICES: TLS_CHOICE_MAP}, + TODRIVE_CLEARFILTER: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_CLIENTACCESS: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_CONVERSION: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_LOCALCOPY: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_LOCALE: {VAR_TYPE: TYPE_LOCALE}, + TODRIVE_NOBROWSER: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'nobrowser.txt', VAR_SFFT: (FALSE, TRUE)}, + TODRIVE_NOEMAIL: {VAR_TYPE: TYPE_BOOLEAN, VAR_SIGFILE: 'notdemail.txt', VAR_SFFT: (FALSE, TRUE)}, + TODRIVE_NO_ESCAPE_CHAR: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_PARENT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + TODRIVE_SHEET_TIMESTAMP: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_SHEET_TIMEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + TODRIVE_TIMESTAMP: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_TIMEFORMAT: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + TODRIVE_TIMEZONE: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + TODRIVE_UPLOAD_NODATA: {VAR_TYPE: TYPE_BOOLEAN}, + TODRIVE_USER: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)}, + TRUNCATE_CLIENT_ID: {VAR_TYPE: TYPE_BOOLEAN}, + UPDATE_CROS_OU_WITH_ID: {VAR_TYPE: TYPE_BOOLEAN}, + USE_CHAT_ADMIN_ACCESS: {VAR_TYPE: TYPE_BOOLEAN}, + USE_COURSE_OWNER_ACCESS: {VAR_TYPE: TYPE_BOOLEAN}, + USE_PROJECTID_AS_NAME: {VAR_TYPE: TYPE_BOOLEAN}, + USER_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 500)}, + USER_SERVICE_ACCOUNT_ACCESS_ONLY: {VAR_TYPE: TYPE_BOOLEAN}, + } diff --git a/src/gam/gamlib/skus.py b/src/gam/gamlib/skus.py new file mode 100644 index 00000000..907bbc58 --- /dev/null +++ b/src/gam/gamlib/skus.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Google SKUs + +""" + +# Products/SKUs +_PRODUCTS = { + '101001': 'Cloud Identity Free', + '101005': 'Cloud Identity Premium', + '101031': 'Google Workspace for Education', + '101033': 'Google Voice', + '101034': 'Google Workspace Archived User', + '101035': 'Cloud Search', + '101036': 'Google Meet Global Dialing', + '101037': 'Google Workspace for Education', + '101038': 'AppSheet', + '101039': 'Assured Controls', + '101040': 'Chrome Enterprise', + '101043': 'Google Workspace Additional Storage', + '101047': 'Gemini', + '101049': 'Education Endpoint Management', + '101050': 'Colab', + 'Google-Apps': 'Google Workspace', + 'Google-Chrome-Device-Management': 'Google Chrome Device Management', + 'Google-Drive-storage': 'Google Drive Storage', + 'Google-Vault': 'Google Vault', + } +_SKUS = { + '1010010001': { + 'product': '101001', 'aliases': ['identity', 'cloudidentity', 'cloudidentityfree'], 'displayName': 'Cloud Identity Free'}, + '1010050001': { + 'product': '101005', 'aliases': ['identitypremium', 'cloudidentitypremium'], 'displayName': 'Cloud Identity Premium'}, + '1010070001': { + 'product': 'Google-Apps', 'aliases': ['gwef', 'workspaceeducationfundamentals'], 'displayName': 'Google Workspace for Education Fundamentals'}, + '1010070004': { + 'product': 'Google-Apps', 'aliases': ['gwegmo', 'workspaceeducationgmailonly'], 'displayName': 'Google Workspace for Education Gmail Only'}, + '1010310002': { + 'product': '101031', 'aliases': ['gsefe', 'e4e', 'gsuiteenterpriseeducation'], 'displayName': 'Google Workspace for Education Plus - Legacy'}, + '1010310003': { + 'product': '101031', 'aliases': ['gsefes', 'e4es', 'gsuiteenterpriseeducationstudent'], 'displayName': 'Google Workspace for Education Plus - Legacy (Student)'}, + '1010310005': { + 'product': '101031', 'aliases': ['gwes', 'workspaceeducationstandard'], 'displayName': 'Google Workspace for Education Standard'}, + '1010310006': { + 'product': '101031', 'aliases': ['gwesstaff', 'workspaceeducationstandardstaff'], 'displayName': 'Google Workspace for Education Standard (Staff)'}, + '1010310007': { + 'product': '101031', 'aliases': ['gwesstudent', 'workspaceeducationstandardstudent'], 'displayName': 'Google Workspace for Education Standard (Extra Student)'}, + '1010310008': { + 'product': '101031', 'aliases': ['gwep', 'workspaceeducationplus'], 'displayName': 'Google Workspace for Education Plus'}, + '1010310009': { + 'product': '101031', 'aliases': ['gwepstaff', 'workspaceeducationplusstaff'], 'displayName': 'Google Workspace for Education Plus (Staff)'}, + '1010310010': { + 'product': '101031', 'aliases': ['gwepstudent', 'workspaceeducationplusstudent'], 'displayName': 'Google Workspace for Education Plus (Extra Student)'}, + '1010330002': { + 'product': '101033', 'aliases': ['gvpremier', 'voicepremier', 'googlevoicepremier'], 'displayName': 'Google Voice Premier'}, + '1010330003': { + 'product': '101033', 'aliases': ['gvstarter', 'voicestarter', 'googlevoicestarter'], 'displayName': 'Google Voice Starter'}, + '1010330004': { + 'product': '101033', 'aliases': ['gvstandard', 'voicestandard', 'googlevoicestandard'], 'displayName': 'Google Voice Standard'}, + '1010350001': { + 'product': '101035', 'aliases': ['cloudsearch'], 'displayName': 'Cloud Search'}, + '1010360001': { + 'product': '101036', 'aliases': ['meetdialing','googlemeetglobaldialing'], 'displayName': 'Google Meet Global Dialing'}, + '1010370001': { + 'product': '101037', 'aliases': ['gwetlu', 'workspaceeducationupgrade'], 'displayName': 'Google Workspace for Education: Teaching and Learning Upgrade'}, + '1010380001': { + 'product': '101038', 'aliases': ['appsheetcore'], 'displayName': 'AppSheet Core'}, + '1010380002': { + 'product': '101038', 'aliases': ['appsheetstandard', 'appsheetenterprisestandard'], 'displayName': 'AppSheet Enterprise Standard'}, + '1010380003': { + 'product': '101038', 'aliases': ['appsheetplus', 'appsheetenterpriseplus'], 'displayName': 'AppSheet Enterprise Plus'}, + '1010390001': { + 'product': '101039', 'aliases': ['assuredcontrols'], 'displayName': 'Assured Controls'}, + '1010390002': { + 'product': '101039', 'aliases': ['assuredcontrolsplus'], 'displayName': 'Assured Controls Plus'}, + '1010400001': { + 'product': '101040', 'aliases': ['beyondcorp', 'beyondcorpenterprise', 'bce', 'cep', 'chromeenterprisepremium'], 'displayName': 'Chrome Enterprise Premium'}, + '1010430001': { + 'product': '101043', 'aliases': ['gwas', 'plusstorage'], 'displayName': 'Google Workspace Additional Storage'}, + '1010470001': { + 'product': '101047', 'aliases': ['geminient', 'duetai'], 'displayName': 'Gemini Enterprise - Legacy'}, + '1010470002': { + 'product': '101047', 'aliases': ['gwlabs', 'workspacelabs'], 'displayName': 'Google Workspace Labs'}, + '1010470003': { + 'product': '101047', 'aliases': ['geminibiz'], 'displayName': 'Gemini Business'}, + '1010470004': { + 'product': '101047', 'aliases': ['gaiproedu', 'geminiedu'], 'displayName': 'Google AI Pro for Education'}, + '1010470005': { + 'product': '101047', 'aliases': ['geminiedupremium'], 'displayName': 'Gemini Education Premium'}, + '1010470006': { + 'product': '101047', 'aliases': ['aisecurity'], 'displayName': 'AI Security'}, + '1010470007': { + 'product': '101047', 'aliases': ['aimeetingsandmessaging'], 'displayName': 'AI Meetings and Messaging'}, + '1010470008': { + 'product': '101047', 'aliases': ['geminiultra'], 'displayName': 'Google AI Ultra for Business'}, + '1010470009': { + 'product': '101047', 'aliases': ['aiexpandedaccess'], 'displayName': 'AI Expanded Access'}, + '1010490001': { + 'product': '101049', 'aliases': ['eeu'], 'displayName': 'Endpoint Education Upgrade'}, + '1010500001': { + 'product': '101050', 'aliases': ['colabpro'], 'displayName': 'Colab Pro'}, + '1010500002': { + 'product': '101050', 'aliases': ['colabpro+', 'colabproplus'], 'displayName': 'Colab Pro+'}, + 'Google-Apps': { + 'product': 'Google-Apps', 'aliases': ['standard', 'free'], 'displayName': 'G Suite Legacy'}, + 'Google-Apps-For-Business': { + 'product': 'Google-Apps', 'aliases': ['gafb', 'gafw', 'basic', 'gsuitebasic'], 'displayName': 'G Suite Basic'}, + 'Google-Apps-For-Education': { + 'product': 'Google-Apps', 'aliases': ['gafe', 'gsuiteeducation', 'gsuiteedu'], 'displayName': 'Google Workspace for Education - Fundamentals'}, + 'Google-Apps-For-Government': { + 'product': 'Google-Apps', 'aliases': ['gafg', 'gsuitegovernment', 'gsuitegov'], 'displayName': 'Google Workspace Government'}, + 'Google-Apps-For-Postini': { + 'product': 'Google-Apps', 'aliases': ['gams', 'postini', 'gsuitegams', 'gsuitepostini', 'gsuitemessagesecurity'], 'displayName': 'Google Apps Message Security'}, + 'Google-Apps-Lite': { + 'product': 'Google-Apps', 'aliases': ['gal', 'gsl', 'lite', 'gsuitelite'], 'displayName': 'G Suite Lite'}, + 'Google-Apps-Unlimited': { + 'product': 'Google-Apps', 'aliases': ['gau', 'gsb', 'unlimited', 'gsuitebusiness'], 'displayName': 'G Suite Business'}, + '1010020020': { + 'product': 'Google-Apps', 'aliases': ['gae', 'gse', 'enterprise', 'gsuiteenterprise', + 'wsentplus', 'workspaceenterpriseplus'], 'displayName': 'Google Workspace Enterprise Plus (formerly G Suite Enterprise)'}, + '1010020025': { + 'product': 'Google-Apps', 'aliases': ['wsbizplus', 'workspacebusinessplus'], 'displayName': 'Google Workspace Business Plus'}, + '1010020026': { + 'product': 'Google-Apps', 'aliases': ['wsentstan', 'workspaceenterprisestandard'], 'displayName': 'Google Workspace Enterprise Standard'}, + '1010020027': { + 'product': 'Google-Apps', 'aliases': ['wsbizstart', 'wsbizstarter', 'workspacebusinessstarter'], 'displayName': 'Google Workspace Business Starter'}, + '1010020028': { + 'product': 'Google-Apps', 'aliases': ['wsbizstan', 'workspacebusinessstandard'], 'displayName': 'Google Workspace Business Standard'}, + '1010020029': { + 'product': 'Google-Apps', 'aliases': ['wes', 'wsentstarter', 'workspaceenterprisestarter'], 'displayName': 'Workspace Enterprise Starter'}, + '1010020030': { + 'product': 'Google-Apps', 'aliases': ['wsflw', 'workspacefrontline', 'workspacefrontlineworker'], 'displayName': 'Google Workspace Frontline Starter'}, + '1010020031': { + 'product': 'Google-Apps', 'aliases': ['wsflwstan', 'workspacefrontlinestan', 'workspacefrontlineworkerstan'], 'displayName': 'Google Workspace Frontline Standard'}, + '1010020034': { + 'product': 'Google-Apps', 'aliases': ['wsflwplus', 'workspacefrontlineplus', 'workspacefrontlineworkerplus'], 'displayName': 'Google Workspace Frontline Plus'}, + '1010340001': { + 'product': '101034', 'aliases': ['gseau', 'enterprisearchived', 'gsuiteenterprisearchived'], 'displayName': 'Google Workspace Enterprise Plus - Archived User'}, + '1010340002': { + 'product': '101034', 'aliases': ['gsbau', 'businessarchived', 'gsuitebusinessarchived'], 'displayName': 'Google Workspace Business - Archived User'}, + '1010340003': { + 'product': '101034', 'aliases': ['wsbizplusarchived', 'workspacebusinessplusarchived'], 'displayName': 'Google Workspace Business Plus - Archived User'}, + '1010340004': { + 'product': '101034', 'aliases': ['wsentstanarchived', 'workspaceenterprisestandardarchived'], 'displayName': 'Google Workspace Enterprise Standard - Archived User'}, + '1010340005': { + 'product': '101034', 'aliases': ['wsbizstarterarchived', 'workspacebusinessstarterarchived'], 'displayName': 'Google Workspace Business Starter - Archived User'}, + '1010340006': { + 'product': '101034', 'aliases': ['wsbizstanarchived', 'workspacebusinessstanarchived'], 'displayName': 'Google Workspace Business Standard - Archived User'}, + '1010340007': { + 'product': '101034', 'aliases': ['gwefau', 'gwefarchived', 'workspaceeducationfundamentalsarchived'], 'displayName': 'Google Workspace for Education Fundamentals - Archived User'}, + '1010060001': { + 'product': '101006', 'aliases': ['gsuiteessentials', 'essentials', + 'd4e', 'driveenterprise', 'drive4enterprise', + 'wsess', 'workspaceesentials'], 'displayName': 'Google Workspace Essentials (formerly G Suite Essentials)'}, + '1010060003': { + 'product': 'Google-Apps', 'aliases': ['wsentess', 'workspaceenterpriseessentials'], 'displayName': 'Google Workspace Enterprise Essentials'}, + '1010060005': { + 'product': 'Google-Apps', 'aliases': ['wsessplus', 'workspaceessentialsplus'], 'displayName': 'Google Workspace Enterprise Essentials Plus'}, + 'Google-Drive-storage-20GB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive20gb', '20gb', 'googledrivestorage20gb'], 'displayName': 'Google Drive Storage 20GB'}, + 'Google-Drive-storage-50GB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive50gb', '50gb', 'googledrivestorage50gb'], 'displayName': 'Google Drive Storage 50GB'}, + 'Google-Drive-storage-200GB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive200gb', '200gb', 'googledrivestorage200gb'], 'displayName': 'Google Drive Storage 200GB'}, + 'Google-Drive-storage-400GB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive400gb', '400gb', 'googledrivestorage400gb'], 'displayName': 'Google Drive Storage 400GB'}, + 'Google-Drive-storage-1TB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive1tb', '1tb', 'googledrivestorage1tb'], 'displayName': 'Google Drive Storage 1TB'}, + 'Google-Drive-storage-2TB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive2tb', '2tb', 'googledrivestorage2tb'], 'displayName': 'Google Drive Storage 2TB'}, + 'Google-Drive-storage-4TB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive4tb', '4tb', 'googledrivestorage4tb'], 'displayName': 'Google Drive Storage 4TB'}, + 'Google-Drive-storage-8TB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive8tb', '8tb', 'googledrivestorage8tb'], 'displayName': 'Google Drive Storage 8TB'}, + 'Google-Drive-storage-16TB': { + 'product': 'Google-Drive-storage', 'aliases': ['drive16tb', '16tb', 'googledrivestorage16tb'], 'displayName': 'Google Drive Storage 16TB'}, + 'Google-Vault': { + 'product': 'Google-Vault', 'aliases': ['vault', 'googlevault'], 'displayName': 'Google Vault'}, + 'Google-Vault-Former-Employee': { + 'product': 'Google-Vault', 'aliases': ['vfe', 'googlevaultformeremployee'], 'displayName': 'Google Vault - Former Employee'}, + 'Google-Chrome-Device-Management': { + 'product': 'Google-Chrome-Device-Management', 'aliases': ['chrome', 'cdm', 'googlechromedevicemanagement'], 'displayName': 'Google Chrome Device Management'} + } + +ARCHIVABLE_SKUS = {'1010020020', '1010020025', '1010020026', '1010020027', '1010020028', 'Google-Apps-Unlimited'} + +def getProductAndSKU(sku): + l_sku = sku.lower().replace('-', '').replace(' ', '').replace('"', '').replace("'", '').strip() + if l_sku.startswith('nv:'): + if ':' in sku[3:]: + return sku[3:].split(':', 1) + return (None, sku) + for a_sku, sku_values in list(_SKUS.items()): + if ((l_sku == a_sku.lower().replace('-', '')) or + (l_sku in sku_values['aliases']) or + (l_sku == sku_values['displayName'].lower().replace(' ', ''))): + return (sku_values['product'], a_sku) + return (None, sku) + +def productIdToDisplayName(productId): + return _PRODUCTS.get(productId, productId) + +def formatProductIdDisplayName(productId): + productIdDisplay = productIdToDisplayName(productId) + if productId == productIdDisplay: + return productId + return f'{productId} ({productIdDisplay})' + +def normalizeProductId(product): + l_product = product.lower().replace('-', '').replace(' ', '').strip() + if l_product.startswith('nv:'): + return (True, product[3:]) + for a_sku, sku_values in list(_SKUS.items()): + if ((l_product == sku_values['product'].lower().replace('-', '')) or + (l_product == a_sku.lower().replace('-', '')) or + (l_product in sku_values['aliases']) or + (l_product == sku_values['displayName'].lower().replace(' ', ''))): + return (True, sku_values['product']) + return (False, product) + +def getSortedProductList(): + return sorted(_PRODUCTS) + +def skuIdToDisplayName(skuId): + return _SKUS[skuId]['displayName'] if skuId in _SKUS else skuId + +def formatSKUIdDisplayName(skuId): + skuIdDisplay = skuIdToDisplayName(skuId) + if skuId == skuIdDisplay: + return skuId + return f'{skuId} ({skuIdDisplay})' + +def getSortedSKUList(): + return sorted(_SKUS) + +def convertProductListToSKUList(productList): + skuList = [] + for productId in productList: + skuList += [(productId, skuId) for skuId in _SKUS if _SKUS[skuId]['product'] == productId] + return skuList + +def getAllSKUs(): + return convertProductListToSKUList(sorted(_PRODUCTS)) + +def getGSuiteSKUs(): + return convertProductListToSKUList(['Google-Apps', '101031']) diff --git a/src/gam/gamlib/state.py b/src/gam/gamlib/state.py new file mode 100644 index 00000000..10f034a1 --- /dev/null +++ b/src/gam/gamlib/state.py @@ -0,0 +1,329 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM global variables + +""" + +# The following GM_XXX constants are arbitrary but must be unique +# Most errors print a message and bail out with a return code +# Some commands want to set a non-zero return code but not bail +# GAM admin user from oauth2.txt or oauth2service.json +ADMIN = 'admn' +# Number/length of API call retries +API_CALLS_RETRY_DATA = 'rtry' +# GAM cache directory. If no_cache is True, this variable will be set to None +CACHE_DIR = 'gacd' +# Reset GAM cache directory after discovery +CACHE_DISCOVERY_ONLY = 'gcdo' +# Classroom owner service object +CLASSROOM_OWNER_SA = 'cosa' +# Classroom service not available +CLASSROOM_SERVICE_NOT_AVAILABLE = 'csna' +# Command logging +CMDLOG_HANDLER = 'clha' +CMDLOG_LOGGER = 'cllo' +# Convert to local time +CONVERT_TO_LOCAL_TIME = 'ctlt' +# Credentials scopes +CREDENTIALS_SCOPES = 'crsc' +# csvfile keyfield [delimiter ] (matchfield )* [datafield (:*) [delimiter ]] +CSVFILE = 'csvf' +# { key: [datafieldvalues]} +CSV_DATA_DICT = 'csdd' +CSV_KEY_FIELD = 'cskf' +CSV_SUBKEY_FIELD = 'cssk' +CSV_DATA_FIELD = 'csdf' +# Filter for input column drop values +CSV_INPUT_ROW_DROP_FILTER = 'cird' +# Mode (and|or) for input column drop values +CSV_INPUT_ROW_DROP_FILTER_MODE = 'cidm' +# Filter for input column values +CSV_INPUT_ROW_FILTER = 'cirf' +# Mode (and|or) for input column values +CSV_INPUT_ROW_FILTER_MODE = 'cirm' +# Limit number of input rows +CSV_INPUT_ROW_LIMIT = 'cirl' +# Column delimiter in CSV output file +CSV_OUTPUT_COLUMN_DELIMITER = 'codl' +# Filter for output column headers to drop +CSV_OUTPUT_HEADER_DROP_FILTER = 'cohd' +# Filter for output column headers +CSV_OUTPUT_HEADER_FILTER = 'cohf' +# Force output column headers +CSV_OUTPUT_HEADER_FORCE = 'cofh' +# Order output column headers +CSV_OUTPUT_HEADER_ORDER = 'coho' +# Required output column headers +CSV_OUTPUT_HEADER_REQUIRED = 'corh' +# No escape character in CSV output file +CSV_OUTPUT_NO_ESCAPE_CHAR = 'cone' +# Quote character in CSV output file +CSV_OUTPUT_QUOTE_CHAR = 'coqc' +# Filter for output column drop values +CSV_OUTPUT_ROW_DROP_FILTER = 'cord' +# Mode (and|or) for output column drop values +CSV_OUTPUT_ROW_DROP_FILTER_MODE = 'codm' +# Filter for output column values +CSV_OUTPUT_ROW_FILTER = 'corf' +# Mode (and|or) for output column values +CSV_OUTPUT_ROW_FILTER_MODE = 'corm' +# Limit number of output rows +CSV_OUTPUT_ROW_LIMIT = 'corl' +# Add timestamp column to CSV output file +CSV_OUTPUT_TIMESTAMP_COLUMN = 'cotc' +# Transpose output rows/columns +CSV_OUTPUT_TRANSPOSE = 'cotr' +# Output sort headers +CSV_OUTPUT_SORT_HEADERS = 'cosh' +# CSV todrive options +CSV_TODRIVE = 'todr' +# Current API services +CURRENT_API_SERVICES = 'caps' +# Current Client API +CURRENT_CLIENT_API = 'ccap' +# Current Client API scopes +CURRENT_CLIENT_API_SCOPES = 'ccas' +# Current Service Account API +CURRENT_SVCACCT_API = 'csap' +# Current Service Account API scopes +CURRENT_SVCACCT_API_SCOPES = 'csas' +# Current Service Account user +CURRENT_SVCACCT_USER = 'csa' +# datetime.datetime.now +DATETIME_NOW = 'dtno' +# If debug_level > 0: extra_args['prettyPrint'] = True, httplib2.debuglevel = gam_debug_level, appsObj.debug = True +DEBUG_LEVEL = 'dbgl' +# Whether debug output should redact sensitive credentials +DEBUG_REDACTION = 'dbrd' +# Decoded ID token +DECODED_ID_TOKEN = 'didt' +# Developer Preview APIs +DEVELOPER_PREVIEW_APIS = 'dapi' +# Index of start of in command line +ENTITY_CL_DELAY_START = 'ecld' +ENTITY_CL_START = 'ecls' +# Extra arguments to pass to GAPI functions +EXTRA_ARGS_LIST = 'exad' +# gam.cfg file +GAM_CFG_FILE = 'gcfi' +GAM_CFG_PATH = 'gcpa' +GAM_CFG_SECTION = 'gcse' +GAM_CFG_SECTION_NAME = 'gcsn' +# Path to gam +GAM_PATH = 'gpth' +# Python source, PyInstaller or StaticX? +GAM_TYPE = 'gtyp' +# Shared Service Account HTTP Object +HTTP_OBJECT = 'http' +# Are we on Global Compute Engine +IS_ON_GCE = 'ogce' +# Length of last Got message +LAST_GOT_MSG_LEN = 'lgml' +# License SKUs +LICENSE_SKUS = 'lsku' +# Make Building ID/Name map +MAKE_BUILDING_ID_NAME_MAP = 'mkbm' +# Dictionary mapping Building ID to Name +MAP_BUILDING_ID_TO_NAME = 'bi2n' +# Dictionary mapping Building Name to ID +MAP_BUILDING_NAME_TO_ID = 'bn2i' +# Dictionary mapping OrgUnit ID to Name +MAP_ORGUNIT_ID_TO_NAME = 'oi2n' +# Dictionary mapping Shared Drive ID to Name +MAP_SHAREDDRIVE_ID_TO_NAME = 'si2n' +# Make Role ID/Name map +MAKE_ROLE_ID_NAME_MAP = 'mkrm' +# Dictionary mapping Role ID to Name +MAP_ROLE_ID_TO_NAME = 'ri2n' +# Dictionary mapping Role Name to ID +MAP_ROLE_NAME_TO_ID = 'rn2i' +# Dictionary mapping User ID to Name +MAP_USER_ID_TO_NAME = 'ui2n' +# Multiprocess exit condition +MULTIPROCESS_EXIT_CONDITION = 'mpec' +# Multiprocess exit processing +MULTIPROCESS_EXIT_PROCESSING = 'mpep' +# Number of batch items +NUM_BATCH_ITEMS = 'nbat' +# Values retrieved from oauth2service.json +OAUTH2SERVICE_CLIENT_ID = 'osci' +OAUTH2SERVICE_JSON_DATA = 'osjd' +# Values retrieved from oauth2.txt +OAUTH2_CLIENT_ID = 'oaci' +# oauth2.txt lock file +OAUTH2_TXT_LOCK = 'oatl' +# Output date format, empty defalts to ISOFormat +OUTPUT_DATEFORMAT = 'oudf' +# Output time format, empty defalts to ISOFormat +OUTPUT_TIMEFORMAT = 'outf' +# gam.cfg parser +PARSER = 'pars' +# Process ID +PID = 'pid ' +# Domains for print alises|groups|users +PRINT_AGU_DOMAINS = 'pagu' +# OrgUnits for print cros +PRINT_CROS_OUS = 'pcou' +# OrgUnits and children for print cros +PRINT_CROS_OUS_AND_CHILDREN = 'pcoc' +# Check API calls rate +RATE_CHECK_COUNT = 'rccn' +RATE_CHECK_START = 'rcst' +# Section name from outer gam, passed to inner gams +SECTION = 'sect' +# Enable/disable "Getting ... " messages +SHOW_GETTINGS = 'shog' +# Enable/disable NL at end of "Got ..." messages +SHOW_GETTINGS_GOT_NL = 'shgn' +# redirected files +SAVED_STDOUT = 'svso' +STDERR = 'stde' +STDOUT = 'stdo' +# Scopes values retrieved from oauth2service.json +SVCACCT_SCOPES = 'sasc' +# Were scopes values retrieved from oauth2service.json +SVCACCT_SCOPES_DEFINED = 'sasd' +# Most errors print a message and bail out with a return code +# Some commands want to set a non-zero return code but not bail +SYSEXITRC = 'sxrc' +# Encodings +SYS_ENCODING = 'syen' +# Shared by threadBatchWorker and threadBatchGAMCommands +TBATCH_QUEUE = 'batq' +# redirected file fields: name, mode, encoding, write header, multiproces, queue +REDIRECT_NAME = 'rdfn' +REDIRECT_MODE = 'rdmo' +REDIRECT_FD = 'rdfd' +REDIRECT_MULTI_FD = 'rdmf' +REDIRECT_STD = 'rdst' +REDIRECT_ENCODING = 'rden' +REDIRECT_WRITE_HEADER = 'rdwh' +REDIRECT_MULTIPROCESS = 'rdmp' +REDIRECT_QUEUE = 'rdq' +REDIRECT_QUEUE_NAME = 'name' +REDIRECT_QUEUE_CLEAR_ROW_FILTERS = 'clearRowFilters' +REDIRECT_QUEUE_TODRIVE = 'todrive' +REDIRECT_QUEUE_CSVPF = 'csvpf' +REDIRECT_QUEUE_DATA = 'rows' +REDIRECT_QUEUE_ARGS = 'args' +REDIRECT_QUEUE_GLOBALS = 'globals' +REDIRECT_QUEUE_VALUES = 'values' +REDIRECT_QUEUE_START = 'start' +REDIRECT_QUEUE_END = 'end' +REDIRECT_QUEUE_EOF = 'eof' +# +Globals = { + ADMIN: None, + API_CALLS_RETRY_DATA: {}, + CACHE_DIR: None, + CACHE_DISCOVERY_ONLY: True, + CLASSROOM_OWNER_SA: {}, + CLASSROOM_SERVICE_NOT_AVAILABLE: False, + CMDLOG_HANDLER: None, + CMDLOG_LOGGER: None, + CONVERT_TO_LOCAL_TIME: False, + CREDENTIALS_SCOPES: set(), + CSVFILE: {}, + CSV_DATA_DICT: {}, + CSV_KEY_FIELD: None, + CSV_SUBKEY_FIELD: None, + CSV_DATA_FIELD: None, + CSV_INPUT_ROW_DROP_FILTER: [], + CSV_INPUT_ROW_DROP_FILTER_MODE: False, + CSV_INPUT_ROW_FILTER: [], + CSV_INPUT_ROW_FILTER_MODE: True, + CSV_INPUT_ROW_LIMIT: 0, + CSV_OUTPUT_COLUMN_DELIMITER: None, + CSV_OUTPUT_HEADER_DROP_FILTER: [], + CSV_OUTPUT_HEADER_FILTER: [], + CSV_OUTPUT_HEADER_FORCE: [], + CSV_OUTPUT_HEADER_ORDER: [], + CSV_OUTPUT_HEADER_REQUIRED: [], + CSV_OUTPUT_NO_ESCAPE_CHAR: None, + CSV_OUTPUT_QUOTE_CHAR: None, + CSV_OUTPUT_ROW_DROP_FILTER: [], + CSV_OUTPUT_ROW_DROP_FILTER_MODE: False, + CSV_OUTPUT_ROW_FILTER: [], + CSV_OUTPUT_ROW_FILTER_MODE: True, + CSV_OUTPUT_ROW_LIMIT: 0, + CSV_OUTPUT_SORT_HEADERS: [], + CSV_OUTPUT_TIMESTAMP_COLUMN: None, + CSV_OUTPUT_TRANSPOSE: False, + CSV_TODRIVE: {}, + CURRENT_API_SERVICES: {}, + CURRENT_CLIENT_API: None, + CURRENT_CLIENT_API_SCOPES: set(), + CURRENT_SVCACCT_API: None, + CURRENT_SVCACCT_API_SCOPES: set(), + CURRENT_SVCACCT_USER: None, + DATETIME_NOW: None, + DEBUG_LEVEL: 0, + DEBUG_REDACTION: True, + DECODED_ID_TOKEN: None, + DEVELOPER_PREVIEW_APIS: set(), + ENTITY_CL_DELAY_START: 1, + ENTITY_CL_START: 1, + EXTRA_ARGS_LIST: [], + GAM_CFG_FILE: '', + GAM_CFG_PATH: '', + GAM_CFG_SECTION: '', + GAM_CFG_SECTION_NAME: '', + GAM_PATH: '.', + GAM_TYPE: '', + HTTP_OBJECT: None, + IS_ON_GCE: False, + LAST_GOT_MSG_LEN: 0, + LICENSE_SKUS: [], + MAKE_BUILDING_ID_NAME_MAP: True, + MAKE_ROLE_ID_NAME_MAP: True, + MAP_BUILDING_ID_TO_NAME: {}, + MAP_BUILDING_NAME_TO_ID: {}, + MAP_ORGUNIT_ID_TO_NAME: {}, + MAP_SHAREDDRIVE_ID_TO_NAME: {}, + MAP_ROLE_ID_TO_NAME: {}, + MAP_ROLE_NAME_TO_ID: {}, + MAP_USER_ID_TO_NAME: {}, + MULTIPROCESS_EXIT_CONDITION: None, + MULTIPROCESS_EXIT_PROCESSING: False, + NUM_BATCH_ITEMS: 0, + OAUTH2SERVICE_CLIENT_ID: None, + OAUTH2SERVICE_JSON_DATA: {}, + OAUTH2_CLIENT_ID: None, + OAUTH2_TXT_LOCK: None, + OUTPUT_DATEFORMAT: '', + OUTPUT_TIMEFORMAT: '', + PARSER: None, + PID: 0, + PRINT_AGU_DOMAINS: '', + PRINT_CROS_OUS: '', + PRINT_CROS_OUS_AND_CHILDREN: '', + RATE_CHECK_COUNT: 0, + RATE_CHECK_START: 0, + SECTION: None, + SHOW_GETTINGS: True, + SHOW_GETTINGS_GOT_NL: False, + SAVED_STDOUT: None, + STDERR: {}, + STDOUT: {}, + SVCACCT_SCOPES: {}, + SVCACCT_SCOPES_DEFINED: False, + SYSEXITRC: 0, + SYS_ENCODING: 'utf-8', + TBATCH_QUEUE: None + } diff --git a/src/gam/gamlib/uprop.py b/src/gam/gamlib/uprop.py new file mode 100644 index 00000000..dcc3310e --- /dev/null +++ b/src/gam/gamlib/uprop.py @@ -0,0 +1,287 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2026 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM user properties + +""" + +# notes +# a|b|c +# getKeywordAttribute(CUSTOM_TYPE_NOCUSTOM, attrdict) + +#CUSTOM_TYPE_NOCUSTOM = { +# PTKW_CL_TYPE_KEYWORD: 'type', +# PTKW_CL_CUSTOM_KEYWORD: None, +# PTKW_ATTR_TYPE_KEYWORD: 'type', +# PTKW_ATTR_TYPE_CUSTOM_VALUE: None, +# PTKW_ATTR_CUSTOMTYPE_KEYWORD: None, +# PTKW_KEYWORD_LIST: ['a', 'b', 'c'] +# } + +# addresses, ims +# type a|b|c|([custom] ) +# getChoice([CUSTOM_TYPE_CUSTOM[PTKW_CL_TYPE_KEYWORD]]) +# getKeywordAttribute(CUSTOM_TYPE_CUSTOM, attrdict) + +# emails, externalids, relations, websites +# [type] a|b|c|([custom] ) +# getChoice([CUSTOM_TYPE_CUSTOM[PTKW_CL_TYPE_KEYWORD]], defaultChoice=None) +# getKeywordAttribute(CUSTOM_TYPE_IMPLICIT, attrdict) + +# locations, phones +# type a|b|c|([custom] ) +# if argument == CUSTOM_TYPE_CUSTOM[PTKW_CL_TYPE_KEYWORD]: +# getKeywordAttribute(CUSTOM_TYPE_CUSTOM, attrdict) + +#CUSTOM_TYPE_CUSTOM = { +# PTKW_CL_TYPE_KEYWORD: 'type', +# PTKW_CL_CUSTOM_KEYWORD: 'custom', +# PTKW_ATTR_TYPE_KEYWORD: 'type', +# PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', +# PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', +# PTKW_KEYWORD_LIST: ['custom', 'a', 'b', 'c'] +# } + +# organizations +# (type a|b|c|([custom] )) | (custom_type ) +# if argument == CUSTOM_TYPE_DIFFERENT_KEYWORD[PTKW_CL_TYPE_KEYWORD]: +# getKeywordAttribute(CUSTOM_TYPE_DIFFERENT_KEYWORD, attrdict) +# elif argument == CUSTOM_TYPE_DIFFERENT_KEYWORD[PTKW_CL_CUSTOM_KEYWORD]: +# attrdict[CUSTOM_TYPE_DIFFERENT_KEYWORD[PTKW_ATTR_CUSTOMTYPE_KEYWORD]] = getValue() + +#CUSTOM_TYPE_DIFFERENT_KEYWORD = { +# PTKW_CL_TYPE_KEYWORD: 'type', +# PTKW_CL_CUSTOM_KEYWORD: 'custom', +# PTKW_CL_CUSTOMTYPE_KEYWORD: 'custom_type', +# PTKW_ATTR_TYPE_KEYWORD: 'type', +# PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', +# PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', +# PTKW_KEYWORD_LIST: ['custom', 'a', 'b', 'c'] +# } + +# Keys into USER_PROPERTIES +CLASS = 'clas' +TITLE = 'titl' +TYPE_KEYWORDS = 'tykw' +PTKW_CL_TYPE_KEYWORD = 'ctkw' +PTKW_CL_CUSTOM_KEYWORD = 'ccuk' +PTKW_CL_CUSTOMTYPE_KEYWORD = 'cctk' +PTKW_ATTR_TYPE_KEYWORD = 'atkw' +PTKW_ATTR_TYPE_CUSTOM_VALUE = 'atcv' +PTKW_ATTR_CUSTOMTYPE_KEYWORD = 'actk' +PTKW_KEYWORD_LIST = 'kwli' +# +PC_ADDRESSES = 'addr' +PC_ALIASES = 'alia' +PC_ARRAY = 'arry' +PC_BOOLEAN = 'bool' +PC_EMAILS = 'emai' +PC_GENDER = 'gndr' +PC_IMS = 'ims ' +PC_LANGUAGES = 'lang' +PC_LOCATIONS = 'loca' +PC_NAME = 'name' +PC_NOTES = 'note' +PC_ORGANIZATIONS = 'orga' +PC_POSIX = 'posi' +PC_SCHEMAS = 'schm' +PC_SSH = 'ssh ' +PC_STRING = 'stri' +PC_TIME = 'time' + +PROPERTIES = { + 'primaryEmail': + {CLASS: PC_STRING, TITLE: 'User',}, + 'name': + {CLASS: PC_NAME, TITLE: 'Name',}, + 'givenName': + {CLASS: PC_STRING, TITLE: 'First Name',}, + 'familyName': + {CLASS: PC_STRING, TITLE: 'Last Name',}, + 'fullName': + {CLASS: PC_STRING, TITLE: 'Full Name',}, + 'displayName': + {CLASS: PC_STRING, TITLE: 'Display Name',}, + 'primaryGuestEmail': + {CLASS: PC_STRING, TITLE: 'Primary Guest Email',}, + 'languages': + {CLASS: PC_LANGUAGES, TITLE: 'Languages',}, + 'languageCode': + {CLASS: PC_LANGUAGES, TITLE: 'Languages',}, + 'customLanguage': + {CLASS: PC_LANGUAGES, TITLE: 'Custom Languages',}, + 'password': + {CLASS: PC_STRING, TITLE: 'Password',}, + 'hashFunction': + {CLASS: PC_STRING, TITLE: 'Hash Function',}, + 'isAdmin': + {CLASS: PC_BOOLEAN, TITLE: 'Is a Super Admin',}, + 'isDelegatedAdmin': + {CLASS: PC_BOOLEAN, TITLE: 'Is Delegated Admin',}, + 'isGuestUser': + {CLASS: PC_BOOLEAN, TITLE: 'Is a Guest User',}, + 'isEnrolledIn2Sv': + {CLASS: PC_BOOLEAN, TITLE: '2-step enrolled',}, + 'isEnforcedIn2Sv': + {CLASS: PC_BOOLEAN, TITLE: '2-step enforced',}, + 'agreedToTerms': + {CLASS: PC_BOOLEAN, TITLE: 'Has Agreed to Terms',}, + 'ipWhitelisted': + {CLASS: PC_BOOLEAN, TITLE: 'IP Whitelisted',}, + 'archived': + {CLASS: PC_BOOLEAN, TITLE: 'Is Archived',}, + 'archivalTime': + {CLASS: PC_TIME, TITLE: 'Archival Time',}, + 'suspended': + {CLASS: PC_BOOLEAN, TITLE: 'Account Suspended',}, + 'suspensionReason': + {CLASS: PC_STRING, TITLE: 'Suspension Reason',}, + 'suspensionTime': + {CLASS: PC_TIME, TITLE: 'Suspension Time',}, + 'changePasswordAtNextLogin': + {CLASS: PC_BOOLEAN, TITLE: 'Must Change Password',}, + 'recoveryEmail': + {CLASS: PC_STRING, TITLE: 'Recovery Email',}, + 'recoveryPhone': + {CLASS: PC_STRING, TITLE: 'Recovery Phone',}, + 'id': + {CLASS: PC_STRING, TITLE: 'Google Unique ID',}, + 'customerId': + {CLASS: PC_STRING, TITLE: 'Customer ID',}, + 'isMailboxSetup': + {CLASS: PC_BOOLEAN, TITLE: 'Mailbox is setup',}, + 'includeInGlobalAddressList': + {CLASS: PC_BOOLEAN, TITLE: 'Included in GAL',}, + 'creationTime': + {CLASS: PC_TIME, TITLE: 'Creation Time',}, + 'lastLoginTime': + {CLASS: PC_TIME, TITLE: 'Last login time',}, + 'deletionTime': + {CLASS: PC_TIME, TITLE: 'Deletion Time',}, + 'orgUnitPath': + {CLASS: PC_STRING, TITLE: 'Google Org Unit Path',}, + 'thumbnailPhotoUrl': + {CLASS: PC_STRING, TITLE: 'Photo URL',}, + 'addresses': + {CLASS: PC_ADDRESSES, TITLE: 'Addresses', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'other', 'work'],},}, + 'emails': + {CLASS: PC_EMAILS, TITLE: 'Other Emails', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'other', 'work'],},}, + 'externalIds': + {CLASS: PC_ARRAY, TITLE: 'External IDs', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'account', 'customer', 'login_id', 'network', 'organization'],},}, + 'gender': + {CLASS: PC_GENDER, TITLE: 'Gender', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'other', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'other', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customGender', + PTKW_KEYWORD_LIST: ['male', 'female', 'other', 'unknown'],},}, + 'ims': + {CLASS: PC_IMS, TITLE: 'IMs', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'other', 'work'],},}, + 'keywords': + {CLASS: PC_ARRAY, TITLE: 'Keywords', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'mission', 'occupation', 'outlook'],},}, + 'locations': + {CLASS: PC_LOCATIONS, TITLE: 'Locations', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'default', 'desk'],},}, + 'notes': + {CLASS: PC_NOTES, TITLE: 'Notes', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: None, + PTKW_ATTR_TYPE_KEYWORD: 'contentType', PTKW_ATTR_TYPE_CUSTOM_VALUE: None, PTKW_ATTR_CUSTOMTYPE_KEYWORD: None, + PTKW_KEYWORD_LIST: ['text_plain', 'text_html'],},}, + 'organizations': + {CLASS: PC_ORGANIZATIONS, TITLE: 'Organizations', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', PTKW_CL_CUSTOMTYPE_KEYWORD: 'customtype', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: None, PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'domain_only', 'school', 'unknown', 'work'],},}, + 'phones': + {CLASS: PC_ARRAY, TITLE: 'Phones', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'work', 'other', + 'home_fax', 'work_fax', 'other_fax', + 'mobile', 'pager', + 'company_main', 'assistant', + 'car', 'radio', 'isdn', 'callback', + 'telex', 'tty_tdd', 'work_mobile', + 'work_pager', 'main', 'grand_central'],},}, + 'posixAccounts': + {CLASS: PC_POSIX, TITLE: 'Posix Accounts',}, + 'relations': + {CLASS: PC_ARRAY, TITLE: 'Relations', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'spouse', 'child', 'mother', + 'father', 'parent', 'brother', + 'sister', 'friend', 'relative', + 'domestic_partner', 'partner', + 'manager', 'dotted_line_manager', + 'assistant', 'admin_assistant', 'exec_assistant', + 'referred_by'],},}, + 'sshPublicKeys': + {CLASS: PC_SSH, TITLE: 'SSH Public Keys',}, + 'websites': + {CLASS: PC_ARRAY, TITLE: 'Websites', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'work', + 'home_page', 'ftp', 'blog', + 'profile', 'other', 'reservations', + 'app_install_page', 'resume'],},}, + 'customSchemas': + {CLASS: PC_SCHEMAS, TITLE: 'Custom Schemas', + TYPE_KEYWORDS: + {PTKW_CL_TYPE_KEYWORD: 'type', PTKW_CL_CUSTOM_KEYWORD: 'custom', + PTKW_ATTR_TYPE_KEYWORD: 'type', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customType', + PTKW_KEYWORD_LIST: ['custom', 'home', 'other', 'work'],},}, + 'aliases': { + CLASS: PC_ALIASES, TITLE: 'Email Aliases',}, + 'nonEditableAliases': { + CLASS: PC_ALIASES, TITLE: 'NonEditable Aliases',}, + } +# +IM_PROTOCOLS = { + PTKW_CL_TYPE_KEYWORD: 'protocol', PTKW_CL_CUSTOM_KEYWORD: 'custom_protocol', + PTKW_ATTR_TYPE_KEYWORD: 'protocol', PTKW_ATTR_TYPE_CUSTOM_VALUE: 'custom_protocol', PTKW_ATTR_CUSTOMTYPE_KEYWORD: 'customProtocol', + PTKW_KEYWORD_LIST: ['custom_protocol', 'aim', 'gtalk', 'icq', 'jabber', 'msn', 'net_meeting', 'qq', 'skype', 'xmpp', 'yahoo'] + } diff --git a/src/gam/gamlib/verlibs.py b/src/gam/gamlib/verlibs.py new file mode 100644 index 00000000..67f499f3 --- /dev/null +++ b/src/gam/gamlib/verlibs.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2025 Ross Scroggs All Rights Reserved. +# +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""GAM extended library versions + +""" + +GAM_VER_LIBS = [ + 'arrow', + 'chardet', + 'cryptography', + 'filelock', + 'google-api-python-client', + 'google-auth-httplib2', + 'google-auth-oauthlib', + 'google-auth', + 'lxml', + 'httplib2', + 'passlib', + 'pathvalidate', + 'pyscard', + 'yubikey-manager', +] diff --git a/src/gam/gamlib/yubikey.py b/src/gam/gamlib/yubikey.py index 98fb8bd2..5fc8bc38 100644 --- a/src/gam/gamlib/yubikey.py +++ b/src/gam/gamlib/yubikey.py @@ -27,7 +27,7 @@ import sys from gam.util.output import systemErrorExit, readStdin, writeStdout -from gam.gamlib import glmsgs as Msg +from gam.gamlib import msgs as Msg from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding diff --git a/src/gam/util/access.py b/src/gam/util/access.py index dec24263..31a4cfa2 100644 --- a/src/gam/util/access.py +++ b/src/gam/util/access.py @@ -6,14 +6,14 @@ and entity warning functions. import sys -from gamlib import glaction -from gamlib import glapi as API -from gamlib import glcfg as GC -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 +from gamlib import action +from gamlib import api as API +from gamlib import settings as GC +from gamlib import entity +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import indent +from gamlib import msgs as Msg from gam.constants import API_ACCESS_DENIED_RC, INVALID_DOMAIN_RC from util.api import _getAdminEmail, _getSvcAcctData, buildGAPIObject, callGAPI, APIAccessDeniedExit, ClientAPIAccessDeniedExit, SvcAcctAPIAccessDeniedExit, SvcAcctAPIDisabledExit from util.args import getEmailAddressDomain, getPhraseDNEorSNA @@ -24,9 +24,9 @@ from util.output import currentCountNL, formatKeyValueList, setSysExitRC, stderr -Act = glaction.GamAction() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() +Act = action.GamAction() +Ent = entity.GamEntity() +Ind = indent.GamIndent() # Something's wrong with CustomerID?? diff --git a/src/gam/util/api.py b/src/gam/util/api.py index 5b2f389a..7c1956d8 100644 --- a/src/gam/util/api.py +++ b/src/gam/util/api.py @@ -40,12 +40,12 @@ try: except ImportError: pass -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glgdata as GDATA -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import gdata as GDATA +from gamlib import state as GM +from gamlib import msgs as Msg from gamlib import yubikey from gam.var import Ent, Ind from gam.constants import API_ACCESS_DENIED_RC, GOOGLE_API_ERROR_RC, HTTP_ERROR_RC, NETWORK_ERROR_RC, NO_SCOPES_FOR_API_RC, REFRESH_EXPIRY, SOCKET_ERROR_RC, SYSTEM_ERROR_RC @@ -1411,6 +1411,14 @@ def buildGAPIObject(api, credentials=None): GM.Globals[GM.OAUTH2_CLIENT_ID] = credentials.client_id return service +def getSaUser(user): + currentClientAPI = GM.Globals[GM.CURRENT_CLIENT_API] + currentClientAPIScopes = GM.Globals[GM.CURRENT_CLIENT_API_SCOPES] + from util.uid import convertUIDtoEmailAddress # local to avoid api↔uid cycle + userEmail = convertUIDtoEmailAddress(user) if user else None + GM.Globals[GM.CURRENT_CLIENT_API] = currentClientAPI + GM.Globals[GM.CURRENT_CLIENT_API_SCOPES] = currentClientAPIScopes + return userEmail def chooseSaAPI(api1, api2): _getSvcAcctData() @@ -1550,6 +1558,3 @@ def APIAccessDeniedExit(): systemErrorExit(API_ACCESS_DENIED_RC, Msg.API_ACCESS_DENIED) -# Late import: uid.py imports callGAPI/buildGAPIObject from this module, -# so we import from uid after those are defined to avoid circular ImportError. -from util.uid import getSaUser # noqa: E402 diff --git a/src/gam/util/args.py b/src/gam/util/args.py index 29741dec..928adb02 100644 --- a/src/gam/util/args.py +++ b/src/gam/util/args.py @@ -81,11 +81,11 @@ import sys import arrow -from gamlib import glcfg as GC +from gamlib import settings as GC from gam.util.fileio import setFilePath -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg -from gamlib import glskus as SKU +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import skus as SKU from util.errors import ( diff --git a/src/gam/util/batch.py b/src/gam/util/batch.py index 9efdd6d8..5c44a69a 100644 --- a/src/gam/util/batch.py +++ b/src/gam/util/batch.py @@ -16,13 +16,13 @@ import sys import threading import time -from gamlib import glapi as API -from gamlib import glclargs -from gamlib import glcfg as GC -from gamlib import glentity -Ent = glentity.GamEntity() -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import clargs +from gamlib import settings as GC +from gamlib import entity +Ent = entity.GamEntity() +from gamlib import state as GM +from gamlib import msgs as Msg from util.csv_pf import CSVPrintFile from gam.constants import HARD_ERROR_RC, KEYBOARD_INTERRUPT_RC @@ -99,7 +99,7 @@ def CSVFileQueueHandler(mpQueue, mpQueueStdout, mpQueueStderr, csvPF, datetimeNo clearRowFilters = False if multiprocessing.get_start_method() != 'fork': signal.signal(signal.SIGINT, signal.SIG_IGN) - Cmd = glclargs.GamCLArgs() + Cmd = clargs.GamCLArgs() else: csvPF.SetColumnDelimiter(GC.Values[GC.CSV_OUTPUT_COLUMN_DELIMITER]) csvPF.SetNoEscapeChar(GC.Values[GC.CSV_OUTPUT_NO_ESCAPE_CHAR]) diff --git a/src/gam/util/config.py b/src/gam/util/config.py index b7c1c5be..7cbe9c3a 100644 --- a/src/gam/util/config.py +++ b/src/gam/util/config.py @@ -19,12 +19,12 @@ import httplib2 import arrow from gam.var import Act, Cmd, Ent, Ind -from gamlib import glapi as API -from gamlib import glcfg as GC +from gamlib import api as API +from gamlib import settings as GC from gam.util.fileio import setFilePath, readFile, writeFile, openFile -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg -from gamlib import glskus as SKU +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import skus as SKU from util.args import getRowFilterDateOrDeltaFromNow from util.args import getRowFilterTimeOrDeltaFromNow diff --git a/src/gam/util/connection.py b/src/gam/util/connection.py index e9a410eb..2ba3c347 100644 --- a/src/gam/util/connection.py +++ b/src/gam/util/connection.py @@ -15,11 +15,11 @@ from cryptography.hazmat.backends import default_backend from importlib.metadata import version as lib_version from urllib.parse import urlparse -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg -from gamlib import glverlibs +from gamlib import api as API +from gamlib import settings as GC +from gamlib import state as GM +from gamlib import msgs as Msg +from gamlib import verlibs from gam.constants import ( FN_GAMCOMMANDS_TXT, GAM, GAM_URL, GAM_WIKI, @@ -332,7 +332,7 @@ def doVersion(checkForArgs=True): if extended: printKeyValueList([ssl.OPENSSL_VERSION]) tls_ver, cipher_name = _getServerTLSUsed(testLocation) - for lib in glverlibs.GAM_VER_LIBS: + for lib in verlibs.GAM_VER_LIBS: try: writeStdout(f'{lib} {lib_version(lib)}\n') except: diff --git a/src/gam/util/csv_pf.py b/src/gam/util/csv_pf.py index 6d79f77c..2e6c2179 100644 --- a/src/gam/util/csv_pf.py +++ b/src/gam/util/csv_pf.py @@ -13,11 +13,11 @@ import webbrowser import arrow import googleapiclient.http -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import DEFAULT_FILE_APPEND_MODE, INSUFFICIENT_PERMISSIONS_RC, MAX_GOOGLE_SHEET_CELLS, NO_CSV_DATA_TO_UPLOAD_RC, ROOT from tempfile import TemporaryFile from util.api import _getAdminEmail, buildGAPIObject, buildGAPIServiceObject, callGAPI, callGAPIpages, chooseSaAPI diff --git a/src/gam/util/display.py b/src/gam/util/display.py index 2719ff33..edb28da9 100644 --- a/src/gam/util/display.py +++ b/src/gam/util/display.py @@ -7,9 +7,9 @@ util.output. import sys -from gamlib import glcfg as GC -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import settings as GC +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Ent, Ind diff --git a/src/gam/util/domain_filters.py b/src/gam/util/domain_filters.py index ca6a9cf6..b67ce08c 100644 --- a/src/gam/util/domain_filters.py +++ b/src/gam/util/domain_filters.py @@ -3,12 +3,12 @@ Moved here to break circular dependencies between cmd/ modules. """ -from gamlib import glcfg as GC -from gamlib import glclargs +from gamlib import settings as GC +from gamlib import clargs from gam.util.entity import getEntityList, getQueries -Cmd = glclargs.GamCLArgs() +Cmd = clargs.GamCLArgs() def initUserGroupDomainQueryFilters(): diff --git a/src/gam/util/email.py b/src/gam/util/email.py index c86e5241..72d5e458 100644 --- a/src/gam/util/email.py +++ b/src/gam/util/email.py @@ -18,9 +18,9 @@ from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from gam.var import Act, Ent -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI from util.api import _getAdminEmail, buildGAPIObject, buildGAPIServiceObject, callGAPI from util.args import NAME_EMAIL_ADDRESS_PATTERN, UTF8, normalizeEmailAddressOrUID from util.display import entityActionFailedWarning, entityActionPerformed, entityActionPerformedMessage diff --git a/src/gam/util/entity.py b/src/gam/util/entity.py index 08e22230..0a3b23ea 100644 --- a/src/gam/util/entity.py +++ b/src/gam/util/entity.py @@ -15,11 +15,11 @@ import warnings from cryptography import x509 from cryptography.hazmat.backends import default_backend -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg @@ -127,7 +127,7 @@ def convertOrgUnitIDtoPath(cd, orgUnitId): from util.args import shlexSplitList, shlexSplitListStatus # noqa: E402,F401 - moved to args, re-exported for compat from util.uid import convertUIDtoEmailAddress, convertUIDtoEmailAddressWithType, convertEmailAddressToUID # noqa: F401 - re-export from gam.constants import DATA_ERROR_RC, INVALID_ENTITY_RC, NO_ENTITIES_FOUND_RC, UNKNOWN_ERROR_RC -from gamlib import glskus as SKU +from gamlib import skus as SKU from util.args import ARCHIVED_ARGUMENTS, FALSE_VALUES, SUSPENDED_ARGUMENTS, TRUE_VALUES, _getIsArchived, _getIsSuspended, checkArgumentPresent, checkDataField, checkMatchSkipFields, checkSubkeyField, getArgument, getCharSet, getChoice, getDelimiter, getMatchSkipFields, getPhraseDNEorSNA, getREPattern, getString, makeOrgUnitPathAbsolute, normalizeEmailAddressOrUID, orgUnitPathQuery, removeCourseIdScope, splitEmailAddress, validateEmailAddressOrUID from util.display import ENTITY_DOES_NOT_EXIST_RC, entityActionFailedWarning, entityActionNotPerformedWarning, entityDoesNotExistWarning, entityPerformActionNumItems, getPageMessage, getPageMessageForWhom, printGettingAllAccountEntities, printGettingAllEntityItemsForWhom, printGotEntityItemsForWhom, setGettingAllEntityItemsForWhom from util.errors import csvDataAlreadySavedErrorExit, csvFieldErrorExit, entityDoesNotExistExit, invalidArgumentExit, invalidChoiceExit, missingArgumentExit, usageErrorExit diff --git a/src/gam/util/errors.py b/src/gam/util/errors.py index f97f5fad..d0023b41 100644 --- a/src/gam/util/errors.py +++ b/src/gam/util/errors.py @@ -3,9 +3,9 @@ import os import sys -from gamlib import glcfg as GC -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import settings as GC +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Cmd, Ent, Ind diff --git a/src/gam/util/fileio.py b/src/gam/util/fileio.py index 027605c8..00e16362 100644 --- a/src/gam/util/fileio.py +++ b/src/gam/util/fileio.py @@ -13,10 +13,10 @@ from logging.handlers import RotatingFileHandler from pathvalidate import sanitize_filename, sanitize_filepath -from gamlib import glcfg as GC -from gamlib import glentity -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import settings as GC +from gamlib import entity +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Act, Ent, Ind @@ -45,7 +45,7 @@ WARNING_PREFIX = WARNING + ': ' # Ent is an instance of GamEntity created in __init__.py. # For the default parameter value of fileErrorMessage, we use the # class-level constant directly. -_ENT_FILE = glentity.GamEntity.FILE +_ENT_FILE = entity.GamEntity.FILE diff --git a/src/gam/util/gdoc.py b/src/gam/util/gdoc.py index be237f7c..94497401 100644 --- a/src/gam/util/gdoc.py +++ b/src/gam/util/gdoc.py @@ -15,13 +15,13 @@ import googleapiclient.http import httplib2 import google.auth.exceptions -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glentity -Ent = glentity.GamEntity() -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import entity +Ent = entity.GamEntity() +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Cmd from gam.constants import DEFAULT_CSV_READ_MODE, NO_ENTITIES_FOUND_RC from util.args import UTF8, checkArgumentPresent, getBoolean, getCharSet, getCharacter, getEmailAddress, getSheetEntity, getSheetIdFromSheetEntity, getString, shlexSplitList diff --git a/src/gam/util/group_parents.py b/src/gam/util/group_parents.py index efade97a..c4ae5b6e 100644 --- a/src/gam/util/group_parents.py +++ b/src/gam/util/group_parents.py @@ -3,9 +3,9 @@ Moved here to break circular dependencies between cmd/ modules. """ -from gamlib import glentity -from gamlib import glgapi as GAPI -from gamlib import glindent +from gamlib import entity +from gamlib import gapi as GAPI +from gamlib import indent from gam.util.access import accessErrorExit from gam.util.api import callGAPIpages @@ -13,8 +13,8 @@ from gam.util.csv_pf import flattenJSON from gam.util.display import badRequestWarning, printKeyValueListWithCount from gam.util.domain_filters import _setUserGroupArgs -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() +Ent = entity.GamEntity() +Ind = indent.GamIndent() def getGroupParents(cd, groupParents, groupEmail, groupName, kwargs): diff --git a/src/gam/util/orgunits.py b/src/gam/util/orgunits.py index f8cd434d..d4ec5c2e 100644 --- a/src/gam/util/orgunits.py +++ b/src/gam/util/orgunits.py @@ -5,10 +5,10 @@ OrgUnit path/ID resolution and parent OrgUnit traversal. import sys -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM from util.access import accessErrorExit, checkEntityAFDNEorAccessErrorExit from util.api import buildGAPIObject, callGAPI from util.args import encodeOrgUnitPath, makeOrgUnitPathAbsolute, makeOrgUnitPathRelative diff --git a/src/gam/util/output.py b/src/gam/util/output.py index d7b2a828..eef79338 100644 --- a/src/gam/util/output.py +++ b/src/gam/util/output.py @@ -11,9 +11,9 @@ import time import arrow -from gamlib import glcfg as GC -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import settings as GC +from gamlib import state as GM +from gamlib import msgs as Msg from gam.constants import DEBUG_REDACTION_PATTERNS from gam.var import Ind diff --git a/src/gam/util/schema_utils.py b/src/gam/util/schema_utils.py index 6263feae..6d7ea321 100644 --- a/src/gam/util/schema_utils.py +++ b/src/gam/util/schema_utils.py @@ -3,10 +3,10 @@ Moved here to break circular dependencies between cmd/ modules. """ -from gamlib import glclargs +from gamlib import clargs from gam.util.args import getString -Cmd = glclargs.GamCLArgs() +Cmd = clargs.GamCLArgs() def _initSchemaParms(projection): diff --git a/src/gam/util/tags.py b/src/gam/util/tags.py index fde19d70..7de31649 100644 --- a/src/gam/util/tags.py +++ b/src/gam/util/tags.py @@ -2,12 +2,12 @@ import re -from gamlib import glapi as API -from gamlib import glclargs -from gamlib import glentity -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import clargs +from gamlib import entity +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.util.access import entityUnknownWarning from gam.util.api import buildGAPIObject, callGAPI from gam.util.args import ( @@ -28,8 +28,8 @@ from gam.util.errors import ( usageErrorExit, ) -Ent = glentity.GamEntity() -Cmd = glclargs.GamCLArgs() +Ent = entity.GamEntity() +Cmd = clargs.GamCLArgs() def _substituteForUser(field, user, userName): diff --git a/src/gam/util/uid.py b/src/gam/util/uid.py index 2f0f5afa..40e9279b 100644 --- a/src/gam/util/uid.py +++ b/src/gam/util/uid.py @@ -4,11 +4,11 @@ Convert UIDs to email addresses by querying the Directory/CI APIs. Extracted from entity.py to break the entity↔api circular dependency. """ -from gamlib import glapi as API -from gamlib import glcfg as GC -from gamlib import glgapi as GAPI -from gamlib import glglobals as GM -from gamlib import glmsgs as Msg +from gamlib import api as API +from gamlib import settings as GC +from gamlib import gapi as GAPI +from gamlib import state as GM +from gamlib import msgs as Msg from gam.var import Ent from util.api import buildGAPIObject, callGAPI from util.args import normalizeEmailAddressOrUID @@ -21,7 +21,7 @@ NON_EMAIL_MEMBER_PREFIXES = ( "chrome-os-device.", ) -def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd, sal=None, emailTypes=None, +def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd=None, sal=None, emailTypes=None, checkForCustomerId=False, ciGroupsAPI=False, aliasAllowed=True): if emailTypes is None: emailTypes = ['user'] @@ -34,6 +34,8 @@ def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd, sal=None, emailTypes return emailAddressOrUID if normalizedEmailAddressOrUID.find('@') > 0 and aliasAllowed: return (normalizedEmailAddressOrUID, 'email') + if cd is None: + cd = buildGAPIObject(API.DIRECTORY) if 'user' in emailTypes and 'group' in emailTypes: # Google User IDs *TEND* to be integers while groups tend to have letters # thus we can optimize which check we try first. We'll still check @@ -77,7 +79,7 @@ def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd, sal=None, emailTypes return (normalizedEmailAddressOrUID, 'unknown') -def convertUIDtoEmailAddress(emailAddressOrUID, cd, emailTypes=None, +def convertUIDtoEmailAddress(emailAddressOrUID, cd=None, emailTypes=None, checkForCustomerId=False, ciGroupsAPI=False, aliasAllowed=True): if ciGroupsAPI: if emailAddressOrUID.startswith(NON_EMAIL_MEMBER_PREFIXES): @@ -90,10 +92,12 @@ def convertUIDtoEmailAddress(emailAddressOrUID, cd, emailTypes=None, return email -def convertEmailAddressToUID(emailAddressOrUID, cd, emailType='user', savedLocation=None): +def convertEmailAddressToUID(emailAddressOrUID, cd=None, emailType='user', savedLocation=None): normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(emailAddressOrUID) if normalizedEmailAddressOrUID.find('@') == -1: return normalizedEmailAddressOrUID + if cd is None: + cd = buildGAPIObject(API.DIRECTORY) if emailType != 'group': try: return callGAPI(cd.users(), 'get', @@ -115,15 +119,3 @@ def convertEmailAddressToUID(emailAddressOrUID, cd, emailType='user', savedLocat entityDoesNotExistExit([Ent.USER, Ent.GROUP][emailType == 'group'], normalizedEmailAddressOrUID, errMsg=getPhraseDNEorSNA(normalizedEmailAddressOrUID)) -def getSaUser(user): - """Resolve a user UID/email for service account impersonation.""" - currentClientAPI = GM.Globals[GM.CURRENT_CLIENT_API] - currentClientAPIScopes = GM.Globals[GM.CURRENT_CLIENT_API_SCOPES] - if user: - cd = buildGAPIObject(API.DIRECTORY) - userEmail = convertUIDtoEmailAddress(user, cd) - else: - userEmail = None - GM.Globals[GM.CURRENT_CLIENT_API] = currentClientAPI - GM.Globals[GM.CURRENT_CLIENT_API_SCOPES] = currentClientAPIScopes - return userEmail diff --git a/src/gam/var.py b/src/gam/var.py index f95a18e4..4399ba2a 100644 --- a/src/gam/var.py +++ b/src/gam/var.py @@ -7,12 +7,12 @@ set here and import everywhere. This module has no dependencies on gam/ or util/, only on gamlib/. """ -from gamlib import glaction -from gamlib import glclargs -from gamlib import glentity -from gamlib import glindent +from gamlib import action +from gamlib import clargs +from gamlib import entity +from gamlib import indent -Act = glaction.GamAction() -Cmd = glclargs.GamCLArgs() -Ent = glentity.GamEntity() -Ind = glindent.GamIndent() +Act = action.GamAction() +Cmd = clargs.GamCLArgs() +Ent = entity.GamEntity() +Ind = indent.GamIndent()