mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Rebranded license SKU 1010470004; student group updates
This commit is contained in:
@@ -275,8 +275,8 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
colabpro | 1010500001 | Colab Pro |
|
colabpro | 1010500001 | Colab Pro |
|
||||||
colabpro+ | colabproplus | 1010500002 | Colab Pro+ |
|
colabpro+ | colabproplus | 1010500002 | Colab Pro+ |
|
||||||
eeu | 1010490001 | SKU Endpoint Education Upgrade |
|
eeu | 1010490001 | SKU Endpoint Education Upgrade |
|
||||||
|
gaiproedu | geminiedu | 1010470004 | Google AI Pro for Education |
|
||||||
geminibiz | 1010470003 | Gemini Business |
|
geminibiz | 1010470003 | Gemini Business |
|
||||||
geminiedu | 1010470004 | Gemini Education |
|
|
||||||
geminiedupremium| 1010470005 | Gemini Education Premium |
|
geminiedupremium| 1010470005 | Gemini Education Premium |
|
||||||
geminient| duetai | 1010470001 | Gemini Enterprise |
|
geminient| duetai | 1010470001 | Gemini Enterprise |
|
||||||
geminiultra | 1010470008 | Google AI Ultra for Business |
|
geminiultra | 1010470008 | Google AI Ultra for Business |
|
||||||
@@ -316,12 +316,12 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
wsbizstarter | workspacebusinessstarter | wsbizstart | 1010020027 | Google Workspace Business Starter |
|
wsbizstarter | workspacebusinessstarter | wsbizstart | 1010020027 | Google Workspace Business Starter |
|
||||||
wsbizstarterarchived | workspacebusinessstarterarchived | 1010340005 | Google Workspace Business Starter - Archived User |
|
wsbizstarterarchived | workspacebusinessstarterarchived | 1010340005 | Google Workspace Business Starter - Archived User |
|
||||||
wsentess | workspaceenterpriseessentials | 1010060003 | Google Workspace Enterprise Essentials |
|
wsentess | workspaceenterpriseessentials | 1010060003 | Google Workspace Enterprise Essentials |
|
||||||
wsentplus | workspaceenterpriseplus | gae | gse | enterprise | gsuiteenterprise | 1010020020 | Google Workspace Enterprise Plus |
|
wsentplus | workspaceenterpriseplus | gae | gse | enterprise | gsuiteenterprise | 1010020020 | Google Workspace Enterprise Plus (formerly G Suite Enterprise) |
|
||||||
wsentstan | workspaceenterprisestandard | 1010020026 | Google Workspace Enterprise Standard |
|
wsentstan | workspaceenterprisestandard | 1010020026 | Google Workspace Enterprise Standard |
|
||||||
wsentstanarchived | workspaceenterprisestandardarchived | 1010340004 | Google Workspace Enterprise Standard - Archived User |
|
wsentstanarchived | workspaceenterprisestandardarchived | 1010340004 | Google Workspace Enterprise Standard - Archived User |
|
||||||
wsentstarter | workspaceenterprisestarter | wes | 1010020029 | Workspace Enterprise Starter |
|
wsentstarter | workspaceenterprisestarter | wes | 1010020029 | Workspace Enterprise Starter |
|
||||||
wsess | workspaceesentials | gsuiteessentials | essentials | d4e | driveenterprise | drive4enterprise | 1010060001 | Google Workspace Essentials |
|
wsess | workspaceesentials | gsuiteessentials | essentials | d4e | driveenterprise | drive4enterprise | 1010060001 | Google Workspace Essentials (formerly G Suite Essentials) |
|
||||||
wsessplus | workspaceessentialsplus | 1010060005 | Google Workspace Essentials Plus |
|
wsessplus | workspaceessentialsplus | 1010060005 | Google Workspace Enterprise Essentials Plus |
|
||||||
wsflw | workspacefrontline | workspacefrontlineworker | 1010020030 | Google Workspace Frontline Starter |
|
wsflw | workspacefrontline | workspacefrontlineworker | 1010020030 | Google Workspace Frontline Starter |
|
||||||
wsflwstan | workspacefrontlinestan | workspacefrontlineworkerstan | 1010020031 | Google Workspace Frontline Standard |
|
wsflwstan | workspacefrontlinestan | workspacefrontlineworkerstan | 1010020031 | Google Workspace Frontline Standard |
|
||||||
wsflwplus | workspacefrontlineplus | workspacefrontlineworkerplus | 1010020034 | Google Workspace Frontline Plus
|
wsflwplus | workspacefrontlineplus | workspacefrontlineworkerplus | 1010020034 | Google Workspace Frontline Plus
|
||||||
@@ -5096,7 +5096,7 @@ gam create|add drivefileacl <SharedDriveEntityAdmin>
|
|||||||
anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>)
|
anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>)
|
||||||
(role <DriveFileACLRole>) [withlink|(allowfilediscovery|discoverable [<Boolean>])]
|
(role <DriveFileACLRole>) [withlink|(allowfilediscovery|discoverable [<Boolean>])]
|
||||||
(mappermissionsdomain <DomainName> <DomainName>)*
|
(mappermissionsdomain <DomainName> <DomainName>)*
|
||||||
[expiration <Time>] [sendemail] [emailmessage <String>]
|
[expiration <Time>] [sendemail|sendnotification] [emailmessage <String>]
|
||||||
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
||||||
gam update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
|
gam update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
|
||||||
(role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]]
|
(role <DriveFileACLRole>) [expires|expiration <Time>] [removeexpiration [<Boolean>]]
|
||||||
@@ -5123,7 +5123,7 @@ gam print drivefileacls <SharedDriveEntityAdmin> [todrive <ToDriveAttribute>*]
|
|||||||
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
gam create|add permissions <SharedDriveEntityAdmin> <DriveFilePermissionEntity>
|
gam create|add permissions <SharedDriveEntityAdmin> <DriveFilePermissionEntity>
|
||||||
[expires|expiration <Time>] [sendemail] [emailmessage <String>]
|
[expires|expiration <Time>] [sendemail|sendnotification] [emailmessage <String>]
|
||||||
<PermissionMatch>* [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchAction>]
|
||||||
gam delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity>
|
gam delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity>
|
||||||
<PermissionMatch>* [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchAction>]
|
||||||
@@ -5136,7 +5136,7 @@ gam <UserTypeEntity> create|add drivefileacl <SharedDriveEntityAdmin>
|
|||||||
(role <DriveFileACLRole>) [withlink|(allowfilediscovery|discoverable [<Boolean>])]
|
(role <DriveFileACLRole>) [withlink|(allowfilediscovery|discoverable [<Boolean>])]
|
||||||
(mappermissionsdomain <DomainName> <DomainName>)*
|
(mappermissionsdomain <DomainName> <DomainName>)*
|
||||||
[movetonewownersroot [<Boolean>]]
|
[movetonewownersroot [<Boolean>]]
|
||||||
[expiration <Time>] [sendemail] [emailmessage <String>]
|
[expiration <Time>] [sendemail|sendnotification] [emailmessage <String>]
|
||||||
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
||||||
adminaccess
|
adminaccess
|
||||||
gam <UserTypeEntity> update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
|
gam <UserTypeEntity> update drivefileacl <SharedDriveEntityAdmin> <DriveFilePermissionIDorEmail>
|
||||||
@@ -5167,7 +5167,7 @@ gam <UserTypeEntity> print drivefileacls <SharedDriveEntityAdmin> [todrive <ToDr
|
|||||||
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
gam <UserTypeEntity> create|add permissions <SharedDriveEntityAdmin> <DriveFilePermissionEntity>
|
gam <UserTypeEntity> create|add permissions <SharedDriveEntityAdmin> <DriveFilePermissionEntity>
|
||||||
[expires|expiration <Time>] [sendemail] [emailmessage <String>] adminaccess
|
[expires|expiration <Time>] [sendemail|sendnotification] [emailmessage <String>] adminaccess
|
||||||
<PermissionMatch>* [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchAction>]
|
||||||
gam <UserTypeEntity> delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity> adminaccess
|
gam <UserTypeEntity> delete permissions <SharedDriveEntityAdmin> <DriveFilePermissionIDEntity> adminaccess
|
||||||
<PermissionMatch>* [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchAction>]
|
||||||
@@ -6896,7 +6896,7 @@ gam <UserTypeEntity> create|add drivefileacl <DriveFileEntity> [adminaccess|asad
|
|||||||
anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>) (role <DriveFileACLRole>)
|
anyone|(user <UserItem>)|(group <GroupItem>)|(domain <DomainName>) (role <DriveFileACLRole>)
|
||||||
[withlink|(allowfilediscovery|discoverable [<Boolean>])] [expiration <Time>]
|
[withlink|(allowfilediscovery|discoverable [<Boolean>])] [expiration <Time>]
|
||||||
[moveToNewOwnersRoot [<Boolean>]]
|
[moveToNewOwnersRoot [<Boolean>]]
|
||||||
[sendemail] [emailmessage <String>]
|
[sendemail|sendnotification] [emailmessage <String>]
|
||||||
[updatesheetprotectedranges [<Boolean>]]
|
[updatesheetprotectedranges [<Boolean>]]
|
||||||
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
[showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
||||||
gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
|
gam <UserTypeEntity> update drivefileacl <DriveFileEntity> <DriveFilePermissionIDorEmail>
|
||||||
@@ -6922,7 +6922,7 @@ gam <UserTypeEntity> print drivefileacls <DriveFileEntity> [todrive <ToDriveAttr
|
|||||||
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
(orderby <DriveFileOrderByFieldName> [ascending|descending])*
|
||||||
[formatjson [quotechar <Character>]]
|
[formatjson [quotechar <Character>]]
|
||||||
gam <UserTypeEntity> create|add permissions <DriveFileEntity> <DriveFilePermissionEntity>
|
gam <UserTypeEntity> create|add permissions <DriveFileEntity> <DriveFilePermissionEntity>
|
||||||
[expires|expiration <Time>] [sendemail] [emailmessage <String>]
|
[expires|expiration <Time>] [sendemail|sendnotification] [emailmessage <String>]
|
||||||
[movetonewownersroot [<Boolean>]]
|
[movetonewownersroot [<Boolean>]]
|
||||||
<PermissionMatch>* [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchAction>]
|
||||||
gam <UserTypeEntity> delete permissions <DriveFileEntity> <DriveFilePermissionIDEntity>
|
gam <UserTypeEntity> delete permissions <DriveFileEntity> <DriveFilePermissionIDEntity>
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
7.20.03
|
||||||
|
|
||||||
|
Rebranded license SKU `1010470004` from `Gemini Education` to `Google AI Pro for Education`.
|
||||||
|
|
||||||
|
Additional updates to student groups in Google Classroom.
|
||||||
|
|
||||||
7.20.02
|
7.20.02
|
||||||
|
|
||||||
Upgraded `gam create course-studentgroups` to allow specification of multiple student group titles;
|
Upgraded `gam create course-studentgroups` to allow specification of multiple student group titles;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.20.02'
|
__version__ = '7.20.03'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
#pylint: disable=wrong-import-position
|
#pylint: disable=wrong-import-position
|
||||||
@@ -51247,7 +51247,7 @@ def doCreateCourseStudentGroups():
|
|||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if myarg == 'title':
|
if myarg == 'title':
|
||||||
titles.append(getString(Cmd.OB_STRING))
|
titles.append(getString(Cmd.OB_STRING, maxLen=100))
|
||||||
elif myarg == 'select':
|
elif myarg == 'select':
|
||||||
titles.extend(getEntityList(Cmd.OB_STRING_ENTITY, shlexSplit=True))
|
titles.extend(getEntityList(Cmd.OB_STRING_ENTITY, shlexSplit=True))
|
||||||
elif _getCourseSelectionParameters(myarg, courseSelectionParameters):
|
elif _getCourseSelectionParameters(myarg, courseSelectionParameters):
|
||||||
@@ -51515,7 +51515,7 @@ def doPrintCourseStudentGroups(showMembers=False):
|
|||||||
row['JSON'] = json.dumps(cleanJSON(studentGroup), ensure_ascii=False, sort_keys=False)
|
row['JSON'] = json.dumps(cleanJSON(studentGroup), ensure_ascii=False, sort_keys=False)
|
||||||
csvPF.WriteRowTitles(row)
|
csvPF.WriteRowTitles(row)
|
||||||
continue
|
continue
|
||||||
printGettingEntityItemForWhom(Ent.USER, formatKeyValueList('', [Ent.Singular(Ent.COURSE_STUDENTGROUP), studentGroupId],
|
printGettingEntityItemForWhom(Ent.STUDENT, formatKeyValueList('', [Ent.Singular(Ent.COURSE_STUDENTGROUP), studentGroupId],
|
||||||
currentCount(i, count)))
|
currentCount(i, count)))
|
||||||
pageMessage = getPageMessage()
|
pageMessage = getPageMessage()
|
||||||
try:
|
try:
|
||||||
@@ -51562,8 +51562,32 @@ def doPrintCourseStudentGroups(showMembers=False):
|
|||||||
# gam sync course-studentgroup-members <CourseID> <StudentGroupID> <UserTypeEntity>
|
# gam sync course-studentgroup-members <CourseID> <StudentGroupID> <UserTypeEntity>
|
||||||
# gam clear course-studentgroup-members <CourseID> <StudentGroupID>
|
# gam clear course-studentgroup-members <CourseID> <StudentGroupID>
|
||||||
def doProcessCourseStudentGroupMembers():
|
def doProcessCourseStudentGroupMembers():
|
||||||
def _getCurrentStudents():
|
def _getCourseStudents():
|
||||||
printGettingEntityItemForWhom(Ent.USER, Ent.Singular(Ent.COURSE_STUDENTGROUP), studentGroupId)
|
studentIdEmailMap = {}
|
||||||
|
studentEmailIdMap = {}
|
||||||
|
printGettingEntityItemForWhom(Ent.STUDENT, formatKeyValueList('', [Ent.Singular(Ent.COURSE), courseId], ''))
|
||||||
|
pageMessage = getPageMessage()
|
||||||
|
try:
|
||||||
|
students = callGAPIpages(ocroom.courses().students(), 'list', 'students',
|
||||||
|
pageMessage=pageMessage,
|
||||||
|
throwReasons=[GAPI.NOT_FOUND, GAPI.SERVICE_NOT_AVAILABLE,
|
||||||
|
GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED],
|
||||||
|
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||||
|
courseId=courseId, fields='nextPageToken,students(profile(id,emailAddress))',
|
||||||
|
pageSize=GC.Values[GC.CLASSROOM_MAX_RESULTS])
|
||||||
|
for student in students:
|
||||||
|
studentIdEmailMap[student['profile']['id']] = student['profile']['emailAddress'].lower()
|
||||||
|
studentEmailIdMap[student['profile']['emailAddress'].lower()] = student['profile']['id']
|
||||||
|
return (studentIdEmailMap, studentEmailIdMap)
|
||||||
|
except GAPI.notFound as e:
|
||||||
|
entityActionFailedExit([Ent.COURSE, courseId, studentGroupId], str(e))
|
||||||
|
except (GAPI.serviceNotAvailable, GAPI.notImplemented) as e:
|
||||||
|
entityActionFailedExit([Ent.COURSE, courseId], str(e))
|
||||||
|
except (GAPI.forbidden, GAPI.permissionDenied) as e:
|
||||||
|
ClientAPIAccessDeniedExit(str(e))
|
||||||
|
|
||||||
|
def _getGroupCurrentStudents():
|
||||||
|
printGettingEntityItemForWhom(Ent.STUDENT, formatKeyValueList('', [Ent.Singular(Ent.COURSE_STUDENTGROUP), studentGroupId], ''))
|
||||||
pageMessage = getPageMessage()
|
pageMessage = getPageMessage()
|
||||||
try:
|
try:
|
||||||
return callGAPIpages(ocroom.courses().studentGroups().studentGroupMembers(), 'list', 'studentGroupMembers',
|
return callGAPIpages(ocroom.courses().studentGroups().studentGroupMembers(), 'list', 'studentGroupMembers',
|
||||||
@@ -51581,18 +51605,24 @@ def doProcessCourseStudentGroupMembers():
|
|||||||
except (GAPI.forbidden, GAPI.permissionDenied) as e:
|
except (GAPI.forbidden, GAPI.permissionDenied) as e:
|
||||||
ClientAPIAccessDeniedExit(str(e))
|
ClientAPIAccessDeniedExit(str(e))
|
||||||
|
|
||||||
def _getStudentUserId(kvList, student, i, count):
|
def _validateClStudents(clStudents):
|
||||||
normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(student)
|
status = True
|
||||||
if normalizedEmailAddressOrUID.find('@') == -1:
|
clStudentIds = []
|
||||||
return normalizedEmailAddressOrUID
|
count = len(clStudents)
|
||||||
try:
|
i = 0
|
||||||
return callGAPI(cd.users(), 'get',
|
kvList = [Ent.COURSE, courseId, Ent.STUDENT, '']
|
||||||
throwReasons=GAPI.USER_GET_THROW_REASONS,
|
for student in clStudents:
|
||||||
userKey=normalizedEmailAddressOrUID, fields='id')['id']
|
i += 1
|
||||||
except (GAPI.userNotFound, GAPI.domainNotFound, GAPI.domainCannotUseApis, GAPI.forbidden,
|
student = normalizeEmailAddressOrUID(student)
|
||||||
GAPI.badRequest, GAPI.backendError, GAPI.systemError) as e:
|
if student in studentIdEmailMap:
|
||||||
entityActionFailedWarning(kvList, str(e), i, count)
|
clStudentIds.append(student)
|
||||||
return None
|
elif student in studentEmailIdMap:
|
||||||
|
clStudentIds.append(studentEmailIdMap[student])
|
||||||
|
else:
|
||||||
|
kvList[-1] = student
|
||||||
|
entityActionFailedWarning(kvList, Msg.STUDENT_NOT_IN_COURSE, i, count)
|
||||||
|
status = False
|
||||||
|
return clStudentIds if status else None
|
||||||
|
|
||||||
def _processStudent(function, kvList, kwargs, i, count):
|
def _processStudent(function, kvList, kwargs, i, count):
|
||||||
try:
|
try:
|
||||||
@@ -51611,85 +51641,69 @@ def doProcessCourseStudentGroupMembers():
|
|||||||
except (GAPI.forbidden, GAPI.permissionDenied) as e:
|
except (GAPI.forbidden, GAPI.permissionDenied) as e:
|
||||||
ClientAPIAccessDeniedExit(str(e))
|
ClientAPIAccessDeniedExit(str(e))
|
||||||
|
|
||||||
def _addStudents(students, getUserIds):
|
def _addStudents(students):
|
||||||
count = len(students)
|
count = len(students)
|
||||||
i = 0
|
i = 0
|
||||||
entityPerformActionNumItems([Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId], count, Ent.USER)
|
entityPerformActionNumItems([Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId], count, Ent.STUDENT)
|
||||||
kvList = [Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId, Ent.USER, '']
|
kvList = [Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId, Ent.STUDENT, '']
|
||||||
kwargs = {'courseId': courseId, 'studentGroupId': studentGroupId, 'body': {'userId': ''}}
|
kwargs = {'courseId': courseId, 'studentGroupId': studentGroupId, 'body': {'userId': ''}}
|
||||||
|
Ind.Increment()
|
||||||
for student in students:
|
for student in students:
|
||||||
i += 1
|
i += 1
|
||||||
if getUserIds:
|
kvList[-1] = studentIdEmailMap[student]
|
||||||
userId = _getStudentUserId(kvList, student, i, count)
|
kwargs['body']['userId'] = student
|
||||||
if userId is None:
|
|
||||||
continue
|
|
||||||
kvList[-1] = student
|
|
||||||
else:
|
|
||||||
userId = student
|
|
||||||
kvList[-1] = convertUIDtoEmailAddress(f"id:{userId}", cd=cd, emailTypes=['user'])
|
|
||||||
kwargs['body']['userId'] = userId
|
|
||||||
_processStudent('create', kvList, kwargs, i, count)
|
_processStudent('create', kvList, kwargs, i, count)
|
||||||
|
Ind.Decrement()
|
||||||
|
|
||||||
def _removeStudents(students, getUserIds):
|
def _removeStudents(students):
|
||||||
count = len(students)
|
count = len(students)
|
||||||
i = 0
|
i = 0
|
||||||
entityPerformActionNumItems([Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId], count, Ent.USER)
|
entityPerformActionNumItems([Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId], count, Ent.STUDENT)
|
||||||
kvList = [Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId, Ent.USER, '']
|
kvList = [Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId, Ent.STUDENT, '']
|
||||||
kwargs = {'courseId': courseId, 'studentGroupId': studentGroupId, 'userId': ''}
|
kwargs = {'courseId': courseId, 'studentGroupId': studentGroupId, 'userId': ''}
|
||||||
|
Ind.Increment()
|
||||||
for student in students:
|
for student in students:
|
||||||
i += 1
|
i += 1
|
||||||
if getUserIds:
|
kvList[-1] = studentIdEmailMap[student]
|
||||||
userId = _getStudentUserId(kvList, student, i, count)
|
kwargs['userId'] = student
|
||||||
if userId is None:
|
|
||||||
continue
|
|
||||||
kvList[-1] = student
|
|
||||||
else:
|
|
||||||
userId = student
|
|
||||||
kvList[-1] = convertUIDtoEmailAddress(f"id:{userId}", cd=cd, emailTypes=['user'])
|
|
||||||
kwargs['userId'] = userId
|
|
||||||
_processStudent('delete', kvList, kwargs, i, count)
|
_processStudent('delete', kvList, kwargs, i, count)
|
||||||
|
Ind.Decrement()
|
||||||
|
|
||||||
croom = buildGAPIObject(API.CLASSROOM)
|
croom = buildGAPIObject(API.CLASSROOM)
|
||||||
cd = buildGAPIObject(API.DIRECTORY)
|
|
||||||
action = Act.Get()
|
action = Act.Get()
|
||||||
courseId = getString(Cmd.OB_COURSE_ID)
|
courseId = getString(Cmd.OB_COURSE_ID)
|
||||||
studentGroupId = getString(Cmd.OB_STUDENTGROUP_ID)
|
studentGroupId = getString(Cmd.OB_STUDENTGROUP_ID)
|
||||||
if action != Act.CLEAR:
|
if action != Act.CLEAR:
|
||||||
_, clStudents = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS, groupMemberType=Ent.TYPE_USER)
|
_, clStudents = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS, groupMemberType=Ent.TYPE_USER)
|
||||||
clStudents = [normalizeEmailAddressOrUID(student) for student in clStudents]
|
clStudentIds = []
|
||||||
checkForExtraneousArguments()
|
checkForExtraneousArguments()
|
||||||
_, count, coursesInfo = _getCoursesOwnerInfo(croom, [courseId], GC.Values[GC.USE_COURSE_OWNER_ACCESS])
|
_, count, coursesInfo = _getCoursesOwnerInfo(croom, [courseId], GC.Values[GC.USE_COURSE_OWNER_ACCESS])
|
||||||
if count == 0:
|
if count == 0:
|
||||||
return
|
return
|
||||||
ocroom = coursesInfo[courseId]['croom']
|
ocroom = coursesInfo[courseId]['croom']
|
||||||
courseId = coursesInfo[courseId]['id']
|
courseId = coursesInfo[courseId]['id']
|
||||||
|
studentIdEmailMap, studentEmailIdMap = _getCourseStudents()
|
||||||
if action in {Act.SYNC, Act.CLEAR}:
|
if action in {Act.SYNC, Act.CLEAR}:
|
||||||
currentStudents = [student['userId'] for student in _getCurrentStudents()]
|
currentStudents = [student['userId'] for student in _getGroupCurrentStudents()]
|
||||||
|
if action != Act.CLEAR:
|
||||||
|
clStudentIds = _validateClStudents(clStudents)
|
||||||
|
if clStudentIds is None:
|
||||||
|
return
|
||||||
if action == Act.CLEAR:
|
if action == Act.CLEAR:
|
||||||
_removeStudents(currentStudents, False)
|
_removeStudents(currentStudents)
|
||||||
elif action == Act.DELETE:
|
elif action == Act.DELETE:
|
||||||
_removeStudents(clStudents, True)
|
_removeStudents(clStudentIds)
|
||||||
elif action in {Act.ADD, Act.CREATE}:
|
elif action in {Act.ADD, Act.CREATE}:
|
||||||
_addStudents(clStudents, True)
|
_addStudents(clStudentIds)
|
||||||
else: # elif action == Act.SYNC:
|
else: # elif action == Act.SYNC:
|
||||||
currentMembersSet = set(currentStudents)
|
currentMembersSet = set(currentStudents)
|
||||||
syncMembersSet = set()
|
syncMembersSet = set(clStudentIds)
|
||||||
count = len(clStudents)
|
|
||||||
i = 0
|
|
||||||
kvList = [Ent.COURSE, courseId, Ent.COURSE_STUDENTGROUP, studentGroupId, Ent.USER, '']
|
|
||||||
for student in clStudents:
|
|
||||||
i += 1
|
|
||||||
kvList[-1] = student
|
|
||||||
userId = _getStudentUserId(kvList, student, i, count)
|
|
||||||
if userId is None:
|
|
||||||
continue
|
|
||||||
syncMembersSet.add(userId)
|
|
||||||
removeStudentsSet = currentMembersSet-syncMembersSet
|
removeStudentsSet = currentMembersSet-syncMembersSet
|
||||||
addStudentsSet = syncMembersSet-currentMembersSet
|
addStudentsSet = syncMembersSet-currentMembersSet
|
||||||
Act.Set(Act.DELETE)
|
Act.Set(Act.DELETE)
|
||||||
_removeStudents(removeStudentsSet, False)
|
_removeStudents(removeStudentsSet)
|
||||||
Act.Set(Act.ADD)
|
Act.Set(Act.ADD)
|
||||||
_addStudents(addStudentsSet, False)
|
_addStudents(addStudentsSet)
|
||||||
|
|
||||||
# gam print course-studentgroup-members [todrive <ToDriveAttribute>*]
|
# gam print course-studentgroup-members [todrive <ToDriveAttribute>*]
|
||||||
# (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
|
# (course|class <CourseEntity>)*|([teacher <UserItem>] [student <UserItem>] [states <CourseStateList>])
|
||||||
@@ -65073,7 +65087,7 @@ def _checkFileIdEntityDomainAccess(fileIdEntity, useDomainAdminAccess):
|
|||||||
# (mappermissionsdomain <DomainName> <DomainName>)*
|
# (mappermissionsdomain <DomainName> <DomainName>)*
|
||||||
# [moveToNewOwnersRoot [<Boolean>]]
|
# [moveToNewOwnersRoot [<Boolean>]]
|
||||||
# [updatesheetprotectedranges [<Boolean>]]
|
# [updatesheetprotectedranges [<Boolean>]]
|
||||||
# [sendemail] [emailmessage <String>]
|
# [sendemail|sendnotification] [emailmessage <String>]
|
||||||
# [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
# [showtitles] [nodetails|(csv [todrive <ToDriveAttribute>*] [formatjson [quotechar <Character>]])]
|
||||||
def createDriveFileACL(users, useDomainAdminAccess=False):
|
def createDriveFileACL(users, useDomainAdminAccess=False):
|
||||||
moveToNewOwnersRoot = False
|
moveToNewOwnersRoot = False
|
||||||
@@ -65117,7 +65131,7 @@ def createDriveFileACL(users, useDomainAdminAccess=False):
|
|||||||
elif myarg in {'expiration', 'expires'}:
|
elif myarg in {'expiration', 'expires'}:
|
||||||
expirationLocation = Cmd.Location()
|
expirationLocation = Cmd.Location()
|
||||||
body['expirationTime'] = getTimeOrDeltaFromNow()
|
body['expirationTime'] = getTimeOrDeltaFromNow()
|
||||||
elif myarg == 'sendemail':
|
elif myarg in {'sendemail', 'sendnotification'}:
|
||||||
sendNotificationEmail = True
|
sendNotificationEmail = True
|
||||||
elif myarg == 'emailmessage':
|
elif myarg == 'emailmessage':
|
||||||
sendNotificationEmail = True
|
sendNotificationEmail = True
|
||||||
@@ -65373,7 +65387,7 @@ def doUpdateDriveFileACLs():
|
|||||||
updateDriveFileACLs([_getAdminEmail()], True)
|
updateDriveFileACLs([_getAdminEmail()], True)
|
||||||
|
|
||||||
# gam [<UserTypeEntity>] create permissions <DriveFileEntity> <DriveFilePermissionsEntity> [asadmin]
|
# gam [<UserTypeEntity>] create permissions <DriveFileEntity> <DriveFilePermissionsEntity> [asadmin]
|
||||||
# [expiration <Time>] [sendmail] [emailmessage <String>]
|
# [expiration <Time>] [sendemail|sendnotification] [emailmessage <String>]
|
||||||
# [moveToNewOwnersRoot [<Boolean>]]
|
# [moveToNewOwnersRoot [<Boolean>]]
|
||||||
# <PermissionMatch>* [<PermissionMatchAction>]
|
# <PermissionMatch>* [<PermissionMatchAction>]
|
||||||
def createDriveFilePermissions(users, useDomainAdminAccess=False):
|
def createDriveFilePermissions(users, useDomainAdminAccess=False):
|
||||||
@@ -65491,7 +65505,7 @@ def createDriveFilePermissions(users, useDomainAdminAccess=False):
|
|||||||
moveToNewOwnersRoot = getBoolean()
|
moveToNewOwnersRoot = getBoolean()
|
||||||
elif myarg in {'expiration', 'expires'}:
|
elif myarg in {'expiration', 'expires'}:
|
||||||
expiration = getTimeOrDeltaFromNow()
|
expiration = getTimeOrDeltaFromNow()
|
||||||
elif myarg == 'sendemail':
|
elif myarg in {'sendemail', 'sendnotification'}:
|
||||||
sendNotificationEmail = True
|
sendNotificationEmail = True
|
||||||
elif myarg == 'emailmessage':
|
elif myarg == 'emailmessage':
|
||||||
sendNotificationEmail = True
|
sendNotificationEmail = True
|
||||||
|
|||||||
@@ -499,6 +499,7 @@ STATISTICS_MOVE_FILE = 'Total: {0}, Moved: {1}, Shortcut created {2}, Shortcut e
|
|||||||
STATISTICS_MOVE_FOLDER = 'Total: {0}, Moved: {1}, Shortcut created {2}, Shortcut exists {3}, Duplicate: {4}, Merged: {5}, Move Failed: {6}, Not writable: {7}'
|
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}'
|
STATISTICS_USER_NOT_ORGANIZER = 'User not organizer: {0}'
|
||||||
STRING_LENGTH = 'string length'
|
STRING_LENGTH = 'string length'
|
||||||
|
STUDENT_NOT_IN_COURSE = 'Student not in course'
|
||||||
SUBKEY_FIELD_MISMATCH = 'subkeyfield {0} does not match saved subkeyfield {1}'
|
SUBKEY_FIELD_MISMATCH = 'subkeyfield {0} does not match saved subkeyfield {1}'
|
||||||
SUBSCRIPTION_NOT_FOUND = 'Could not find subscription'
|
SUBSCRIPTION_NOT_FOUND = 'Could not find subscription'
|
||||||
SUFFIX_NOT_ALLOWED_WITH_CUSTOMLANGUAGE = 'Suffix {0} not allowed with customLanguage {1}'
|
SUFFIX_NOT_ALLOWED_WITH_CUSTOMLANGUAGE = 'Suffix {0} not allowed with customLanguage {1}'
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ _SKUS = {
|
|||||||
'1010470003': {
|
'1010470003': {
|
||||||
'product': '101047', 'aliases': ['geminibiz'], 'displayName': 'Gemini Business'},
|
'product': '101047', 'aliases': ['geminibiz'], 'displayName': 'Gemini Business'},
|
||||||
'1010470004': {
|
'1010470004': {
|
||||||
'product': '101047', 'aliases': ['geminiedu'], 'displayName': 'Gemini Education'},
|
'product': '101047', 'aliases': ['gaiproedu', 'geminiedu'], 'displayName': 'Google AI Pro for Education'},
|
||||||
'1010470005': {
|
'1010470005': {
|
||||||
'product': '101047', 'aliases': ['geminiedupremium'], 'displayName': 'Gemini Education Premium'},
|
'product': '101047', 'aliases': ['geminiedupremium'], 'displayName': 'Gemini Education Premium'},
|
||||||
'1010470006': {
|
'1010470006': {
|
||||||
|
|||||||
Reference in New Issue
Block a user