gam7 7.10.10__py3-none-any.whl → 7.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gam7 might be problematic. Click here for more details.
- gam/__init__.py +173 -55
- gam/gamlib/glclargs.py +3 -0
- {gam7-7.10.10.dist-info → gam7-7.11.0.dist-info}/METADATA +1 -1
- {gam7-7.10.10.dist-info → gam7-7.11.0.dist-info}/RECORD +7 -7
- {gam7-7.10.10.dist-info → gam7-7.11.0.dist-info}/WHEEL +0 -0
- {gam7-7.10.10.dist-info → gam7-7.11.0.dist-info}/entry_points.txt +0 -0
- {gam7-7.10.10.dist-info → gam7-7.11.0.dist-info}/licenses/LICENSE +0 -0
gam/__init__.py
CHANGED
|
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
|
28
|
-
__version__ = '7.
|
|
28
|
+
__version__ = '7.11.00'
|
|
29
29
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
|
30
30
|
|
|
31
31
|
#pylint: disable=wrong-import-position
|
|
@@ -46776,6 +46776,13 @@ COURSE_STATE_MAPS = {
|
|
|
46776
46776
|
'published': 'PUBLISHED',
|
|
46777
46777
|
'deleted': 'DELETED',
|
|
46778
46778
|
},
|
|
46779
|
+
Cmd.OB_COURSE_ANNOUNCEMENT_ADD_STATE_LIST: {
|
|
46780
|
+
'draft': 'DRAFT',
|
|
46781
|
+
'published': 'PUBLISHED',
|
|
46782
|
+
},
|
|
46783
|
+
Cmd.OB_COURSE_ANNOUNCEMENT_UPDATE_STATE_LIST: {
|
|
46784
|
+
'published': 'PUBLISHED',
|
|
46785
|
+
},
|
|
46779
46786
|
Cmd.OB_COURSE_WORK_STATE_LIST: {
|
|
46780
46787
|
'draft': 'DRAFT',
|
|
46781
46788
|
'published': 'PUBLISHED',
|
|
@@ -48923,7 +48930,7 @@ def doPrintCourseParticipants():
|
|
|
48923
48930
|
csvPF.SetSortTitles(COURSE_PARTICIPANTS_SORT_TITLES)
|
|
48924
48931
|
csvPF.writeCSVfile('Course Participants')
|
|
48925
48932
|
|
|
48926
|
-
def _batchAddItemsToCourse(croom, courseId, i, count,
|
|
48933
|
+
def _batchAddItemsToCourse(croom, courseId, i, count, addItems, addType):
|
|
48927
48934
|
_ADD_PART_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST,
|
|
48928
48935
|
GAPI.ALREADY_EXISTS: Msg.DUPLICATE,
|
|
48929
48936
|
GAPI.FAILED_PRECONDITION: Msg.NOT_ALLOWED}
|
|
@@ -48939,7 +48946,7 @@ def _batchAddItemsToCourse(croom, courseId, i, count, addParticipants, role):
|
|
|
48939
48946
|
else:
|
|
48940
48947
|
errMsg = getHTTPError(_ADD_PART_REASON_TO_MESSAGE_MAP, http_status, reason, message)
|
|
48941
48948
|
if (reason == GAPI.PERMISSION_DENIED) and (ri[RI_ROLE] in {Ent.STUDENT, Ent.TEACHER}) and ('CannotDirectAddUser' in errMsg):
|
|
48942
|
-
errMsg += f' Add external user with: gam user {ri[RI_ITEM]} create classroominvitation courses {ri[RI_ENTITY]}
|
|
48949
|
+
errMsg += f' Add external user with: gam user {ri[RI_ITEM]} create classroominvitation courses {ri[RI_ENTITY]} addType {Ent.Singular(ri[RI_ROLE])}'
|
|
48943
48950
|
entityActionFailedWarning([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], errMsg, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
|
48944
48951
|
return
|
|
48945
48952
|
waitOnFailure(1, 10, reason, message)
|
|
@@ -48961,39 +48968,44 @@ def _batchAddItemsToCourse(croom, courseId, i, count, addParticipants, role):
|
|
|
48961
48968
|
except (GAPI.quotaExceeded, GAPI.serviceNotAvailable) as e:
|
|
48962
48969
|
entityActionFailedWarning([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
|
48963
48970
|
|
|
48964
|
-
if
|
|
48971
|
+
if addType == Ent.STUDENT:
|
|
48965
48972
|
service = croom.courses().students()
|
|
48966
48973
|
attribute = 'userId'
|
|
48967
|
-
elif
|
|
48974
|
+
elif addType == Ent.TEACHER:
|
|
48968
48975
|
service = croom.courses().teachers()
|
|
48969
48976
|
attribute = 'userId'
|
|
48970
|
-
elif
|
|
48977
|
+
elif addType == Ent.COURSE_ALIAS:
|
|
48971
48978
|
service = croom.courses().aliases()
|
|
48972
48979
|
attribute = 'alias'
|
|
48973
|
-
|
|
48980
|
+
elif addType == Ent.COURSE_TOPIC:
|
|
48974
48981
|
service = croom.courses().topics()
|
|
48975
48982
|
attribute = 'name'
|
|
48983
|
+
else: # addType == Ent.COURSE_ANNOUNCEMENT:
|
|
48984
|
+
service = croom.courses().announcements()
|
|
48985
|
+
attribute = 'text'
|
|
48976
48986
|
method = getattr(service, 'create')
|
|
48977
48987
|
Act.Set(Act.ADD)
|
|
48978
|
-
jcount = len(
|
|
48988
|
+
jcount = len(addItems)
|
|
48979
48989
|
noScopeCourseId = removeCourseIdScope(courseId)
|
|
48980
|
-
entityPerformActionNumItems([Ent.COURSE, noScopeCourseId], jcount,
|
|
48990
|
+
entityPerformActionNumItems([Ent.COURSE, noScopeCourseId], jcount, addType, i, count)
|
|
48981
48991
|
Ind.Increment()
|
|
48982
48992
|
svcargs = dict([('courseId', courseId), ('body', {attribute: None}), ('fields', '')]+GM.Globals[GM.EXTRA_ARGS_LIST])
|
|
48983
48993
|
dbatch = croom.new_batch_http_request(callback=_callbackAddItemsToCourse)
|
|
48984
48994
|
bcount = 0
|
|
48985
48995
|
j = 0
|
|
48986
|
-
for
|
|
48996
|
+
for addItem in addItems:
|
|
48987
48997
|
j += 1
|
|
48988
48998
|
svcparms = svcargs.copy()
|
|
48989
|
-
if
|
|
48990
|
-
svcparms['body'][attribute] = cleanItem = normalizeEmailAddressOrUID(
|
|
48991
|
-
elif
|
|
48992
|
-
svcparms['body'][attribute] = addCourseAliasScope(
|
|
48999
|
+
if addType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49000
|
+
svcparms['body'][attribute] = cleanItem = normalizeEmailAddressOrUID(addItem)
|
|
49001
|
+
elif addType == Ent.COURSE_ALIAS:
|
|
49002
|
+
svcparms['body'][attribute] = addCourseAliasScope(addItem)
|
|
48993
49003
|
cleanItem = removeCourseAliasScope(svcparms['body'][attribute])
|
|
48994
|
-
|
|
48995
|
-
svcparms['body'][attribute] = cleanItem =
|
|
48996
|
-
|
|
49004
|
+
elif addType == Ent.COURSE_TOPIC:
|
|
49005
|
+
svcparms['body'][attribute] = cleanItem = addItem
|
|
49006
|
+
else: # addType == Ent.COURSE_ANNOUNCEMENT:
|
|
49007
|
+
svcparms['body'] = cleanItem = addItem
|
|
49008
|
+
dbatch.add(method(**svcparms), request_id=batchRequestID(noScopeCourseId, 0, 0, j, jcount, cleanItem, addType))
|
|
48997
49009
|
bcount += 1
|
|
48998
49010
|
if bcount >= GC.Values[GC.BATCH_SIZE]:
|
|
48999
49011
|
executeBatch(dbatch)
|
|
@@ -49003,7 +49015,7 @@ def _batchAddItemsToCourse(croom, courseId, i, count, addParticipants, role):
|
|
|
49003
49015
|
dbatch.execute()
|
|
49004
49016
|
Ind.Decrement()
|
|
49005
49017
|
|
|
49006
|
-
def _batchRemoveItemsFromCourse(croom, courseId, i, count,
|
|
49018
|
+
def _batchRemoveItemsFromCourse(croom, courseId, i, count, removeItems, removeType):
|
|
49007
49019
|
_REMOVE_PART_REASON_TO_MESSAGE_MAP = {GAPI.NOT_FOUND: Msg.DOES_NOT_EXIST,
|
|
49008
49020
|
GAPI.FORBIDDEN: Msg.FORBIDDEN,
|
|
49009
49021
|
GAPI.PERMISSION_DENIED: Msg.PERMISSION_DENIED}
|
|
@@ -49024,7 +49036,7 @@ def _batchRemoveItemsFromCourse(croom, courseId, i, count, removeParticipants, r
|
|
|
49024
49036
|
try:
|
|
49025
49037
|
callGAPI(service, 'delete',
|
|
49026
49038
|
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED,
|
|
49027
|
-
GAPI.QUOTA_EXCEEDED, GAPI.SERVICE_NOT_AVAILABLE],
|
|
49039
|
+
GAPI.QUOTA_EXCEEDED, GAPI.SERVICE_NOT_AVAILABLE, GAPI.FAILED_PRECONDITION],
|
|
49028
49040
|
retryReasons=[GAPI.NOT_FOUND, GAPI.SERVICE_NOT_AVAILABLE], triesLimit=0 if reason != GAPI.NOT_FOUND else 3,
|
|
49029
49041
|
courseId=addCourseIdScope(ri[RI_ENTITY]),
|
|
49030
49042
|
body={attribute: ri[RI_ITEM] if ri[RI_ROLE] != Ent.COURSE_ALIAS else addCourseAliasScope(ri[RI_ITEM])},
|
|
@@ -49035,42 +49047,47 @@ def _batchRemoveItemsFromCourse(croom, courseId, i, count, removeParticipants, r
|
|
|
49035
49047
|
entityActionFailedWarning([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], Msg.FORBIDDEN, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
|
49036
49048
|
except GAPI.permissionDenied:
|
|
49037
49049
|
entityActionFailedWarning([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], Msg.PERMISSION_DENIED, int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
|
49038
|
-
except (GAPI.quotaExceeded, GAPI.serviceNotAvailable) as e:
|
|
49050
|
+
except (GAPI.quotaExceeded, GAPI.serviceNotAvailable, GAPI.failedPrecondition) as e:
|
|
49039
49051
|
entityActionFailedWarning([Ent.COURSE, ri[RI_ENTITY], ri[RI_ROLE], ri[RI_ITEM]], str(e), int(ri[RI_J]), int(ri[RI_JCOUNT]))
|
|
49040
49052
|
|
|
49041
|
-
if
|
|
49053
|
+
if removeType == Ent.STUDENT:
|
|
49042
49054
|
service = croom.courses().students()
|
|
49043
49055
|
attribute = 'userId'
|
|
49044
|
-
elif
|
|
49056
|
+
elif removeType == Ent.TEACHER:
|
|
49045
49057
|
service = croom.courses().teachers()
|
|
49046
49058
|
attribute = 'userId'
|
|
49047
|
-
elif
|
|
49059
|
+
elif removeType == Ent.COURSE_ALIAS:
|
|
49048
49060
|
service = croom.courses().aliases()
|
|
49049
49061
|
attribute = 'alias'
|
|
49050
|
-
|
|
49062
|
+
elif removeType == Ent.COURSE_TOPIC:
|
|
49051
49063
|
service = croom.courses().topics()
|
|
49052
49064
|
attribute = 'id'
|
|
49065
|
+
else: # removeType == Ent.COURSE_ANNOUNCEMENT:
|
|
49066
|
+
service = croom.courses().announcements()
|
|
49067
|
+
attribute = 'id'
|
|
49053
49068
|
method = getattr(service, 'delete')
|
|
49054
49069
|
Act.Set(Act.REMOVE)
|
|
49055
|
-
jcount = len(
|
|
49070
|
+
jcount = len(removeItems)
|
|
49056
49071
|
noScopeCourseId = removeCourseIdScope(courseId)
|
|
49057
|
-
entityPerformActionNumItems([Ent.COURSE, noScopeCourseId], jcount,
|
|
49072
|
+
entityPerformActionNumItems([Ent.COURSE, noScopeCourseId], jcount, removeType, i, count)
|
|
49058
49073
|
Ind.Increment()
|
|
49059
49074
|
svcargs = dict([('courseId', courseId), ('fields', ''), (attribute, None)]+GM.Globals[GM.EXTRA_ARGS_LIST])
|
|
49060
49075
|
dbatch = croom.new_batch_http_request(callback=_callbackRemoveItemsFromCourse)
|
|
49061
49076
|
bcount = 0
|
|
49062
49077
|
j = 0
|
|
49063
|
-
for
|
|
49078
|
+
for removeItem in removeItems:
|
|
49064
49079
|
j += 1
|
|
49065
49080
|
svcparms = svcargs.copy()
|
|
49066
|
-
if
|
|
49067
|
-
svcparms[attribute] = cleanItem = normalizeEmailAddressOrUID(
|
|
49068
|
-
elif
|
|
49069
|
-
svcparms[attribute] = addCourseAliasScope(
|
|
49081
|
+
if removeType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49082
|
+
svcparms[attribute] = cleanItem = normalizeEmailAddressOrUID(removeItem)
|
|
49083
|
+
elif removeType == Ent.COURSE_ALIAS:
|
|
49084
|
+
svcparms[attribute] = addCourseAliasScope(removeItem)
|
|
49070
49085
|
cleanItem = removeCourseAliasScope(svcparms[attribute])
|
|
49071
|
-
|
|
49072
|
-
svcparms[attribute] = cleanItem =
|
|
49073
|
-
|
|
49086
|
+
elif removeType == Ent.COURSE_TOPIC:
|
|
49087
|
+
svcparms[attribute] = cleanItem = removeItem
|
|
49088
|
+
else: # removeType == Ent.COURSE_ANNOUNCEMENT:
|
|
49089
|
+
svcparms[attribute] = cleanItem = removeItem
|
|
49090
|
+
dbatch.add(method(**svcparms), request_id=batchRequestID(noScopeCourseId, 0, 0, j, jcount, cleanItem, removeType))
|
|
49074
49091
|
bcount += 1
|
|
49075
49092
|
if bcount >= GC.Values[GC.BATCH_SIZE]:
|
|
49076
49093
|
executeBatch(dbatch)
|
|
@@ -49100,9 +49117,28 @@ def _updateCourseOwner(croom, courseId, owner, i, count):
|
|
|
49100
49117
|
entityActionPerformedMessage([Ent.COURSE, removeCourseIdScope(courseId), Ent.TEACHER, owner], Msg.ALREADY_WAS_OWNER, i, count)
|
|
49101
49118
|
Act.Set(action)
|
|
49102
49119
|
|
|
49103
|
-
|
|
49120
|
+
def getCourseAnnouncement(createCmd):
|
|
49121
|
+
body = {}
|
|
49122
|
+
while Cmd.ArgumentsRemaining():
|
|
49123
|
+
myarg = getArgument()
|
|
49124
|
+
if myarg == 'text':
|
|
49125
|
+
body['text'] = getString(Cmd.OB_STRING, minLen=1, maxLen=30000)
|
|
49126
|
+
elif myarg == 'scheduledtime':
|
|
49127
|
+
body['scheduledTime'] = getTimeOrDeltaFromNow()
|
|
49128
|
+
elif myarg == 'state':
|
|
49129
|
+
body['state'] = getChoice(COURSE_STATE_MAPS[Cmd.OB_COURSE_ANNOUNCEMENT_ADD_STATE_LIST if createCmd else Cmd.OB_COURSE_ANNOUNCEMENT_UPDATE_STATE_LIST],
|
|
49130
|
+
mapChoice=True)
|
|
49131
|
+
else:
|
|
49132
|
+
unknownArgumentExit()
|
|
49133
|
+
if createCmd and 'text' not in body:
|
|
49134
|
+
missingArgumentExit('text <String>')
|
|
49135
|
+
return body
|
|
49136
|
+
|
|
49137
|
+
ADD_REMOVE_UPDATE_ITEM_TYPES_MAP = {
|
|
49104
49138
|
'alias': Ent.COURSE_ALIAS,
|
|
49105
49139
|
'aliases': Ent.COURSE_ALIAS,
|
|
49140
|
+
'announcement': Ent.COURSE_ANNOUNCEMENT,
|
|
49141
|
+
'announcements': Ent.COURSE_ANNOUNCEMENT,
|
|
49106
49142
|
'student': Ent.STUDENT,
|
|
49107
49143
|
'students': Ent.STUDENT,
|
|
49108
49144
|
'teacher': Ent.TEACHER,
|
|
@@ -49123,6 +49159,10 @@ PARTICIPANT_EN_MAP = {
|
|
|
49123
49159
|
|
|
49124
49160
|
# gam courses <CourseEntity> create alias <CourseAliasEntity>
|
|
49125
49161
|
# gam course <CourseID> create alias <CourseAlias>
|
|
49162
|
+
# gam courses <CourseEntity> create announcement
|
|
49163
|
+
# text <String> [scheduledtime <Time>] [state draft|published]
|
|
49164
|
+
# gam course <CourseID> create announcement
|
|
49165
|
+
# text <String> [scheduledtime <Time>] [state draft|published]
|
|
49126
49166
|
# gam courses <CourseEntity> create topic <CourseTopicEntity>
|
|
49127
49167
|
# gam course <CourseID> create topic <CourseTopic>
|
|
49128
49168
|
# gam courses <CourseEntity> create students <UserTypeEntity>
|
|
@@ -49131,35 +49171,39 @@ PARTICIPANT_EN_MAP = {
|
|
|
49131
49171
|
# gam course <CourseID> create teacher [makefirstteacherowner] <EmailAddress>
|
|
49132
49172
|
def doCourseAddItems(courseIdList, getEntityListArg):
|
|
49133
49173
|
croom = buildGAPIObject(API.CLASSROOM)
|
|
49134
|
-
|
|
49135
|
-
if
|
|
49174
|
+
addType = getChoice(ADD_REMOVE_UPDATE_ITEM_TYPES_MAP, mapChoice=True)
|
|
49175
|
+
if addType == Ent.TEACHER:
|
|
49136
49176
|
makeFirstTeacherOwner = checkArgumentPresent(['makefirstteacherowner'])
|
|
49137
49177
|
else:
|
|
49138
49178
|
makeFirstTeacherOwner = False
|
|
49139
49179
|
if not getEntityListArg:
|
|
49140
|
-
if
|
|
49180
|
+
if addType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49141
49181
|
addItems = getStringReturnInList(Cmd.OB_EMAIL_ADDRESS)
|
|
49142
|
-
elif
|
|
49182
|
+
elif addType == Ent.COURSE_ALIAS:
|
|
49143
49183
|
addItems = getStringReturnInList(Cmd.OB_COURSE_ALIAS)
|
|
49144
|
-
|
|
49184
|
+
elif addType == Ent.COURSE_TOPIC:
|
|
49145
49185
|
addItems = getStringReturnInList(Cmd.OB_COURSE_TOPIC)
|
|
49186
|
+
else: # addType == Ent.COURSE_ANNOUNCEMENT:
|
|
49187
|
+
addItems = [getCourseAnnouncement(True)]
|
|
49146
49188
|
courseParticipantLists = None
|
|
49147
49189
|
else:
|
|
49148
|
-
if
|
|
49190
|
+
if addType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49149
49191
|
_, addItems = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS,
|
|
49150
|
-
typeMap={Cmd.ENTITY_COURSEPARTICIPANTS: PARTICIPANT_EN_MAP[
|
|
49192
|
+
typeMap={Cmd.ENTITY_COURSEPARTICIPANTS: PARTICIPANT_EN_MAP[addType]},
|
|
49151
49193
|
isSuspended=False, isArchived=False)
|
|
49152
|
-
elif
|
|
49194
|
+
elif addType == Ent.COURSE_ALIAS:
|
|
49153
49195
|
addItems = getEntityList(Cmd.OB_COURSE_ALIAS_ENTITY, shlexSplit=True)
|
|
49154
|
-
|
|
49196
|
+
elif addType == Ent.COURSE_TOPIC:
|
|
49155
49197
|
addItems = getEntityList(Cmd.OB_COURSE_TOPIC_ENTITY, shlexSplit=True)
|
|
49198
|
+
else: # addType == Ent.COURSE_ANNOUNCEMENT:
|
|
49199
|
+
addItems = getCourseAnnouncement(True)
|
|
49156
49200
|
courseParticipantLists = addItems if isinstance(addItems, dict) else None
|
|
49157
49201
|
if courseParticipantLists is None:
|
|
49158
49202
|
firstTeacher = None
|
|
49159
49203
|
if makeFirstTeacherOwner and addItems:
|
|
49160
49204
|
firstTeacher = normalizeEmailAddressOrUID(addItems[0])
|
|
49161
49205
|
checkForExtraneousArguments()
|
|
49162
|
-
i, count, coursesInfo = _getCoursesOwnerInfo(croom, courseIdList,
|
|
49206
|
+
i, count, coursesInfo = _getCoursesOwnerInfo(croom, courseIdList, addType in {Ent.COURSE_TOPIC, Ent.COURSE_ANNOUNCEMENT},
|
|
49163
49207
|
addCIIdScope=courseParticipantLists is None)
|
|
49164
49208
|
for courseId, courseInfo in coursesInfo.items():
|
|
49165
49209
|
i += 1
|
|
@@ -49169,43 +49213,51 @@ def doCourseAddItems(courseIdList, getEntityListArg):
|
|
|
49169
49213
|
if makeFirstTeacherOwner and addItems:
|
|
49170
49214
|
firstTeacher = normalizeEmailAddressOrUID(addItems[0])
|
|
49171
49215
|
courseId = addCourseIdScope(courseId)
|
|
49172
|
-
_batchAddItemsToCourse(courseInfo['croom'], courseId, i, count, addItems,
|
|
49216
|
+
_batchAddItemsToCourse(courseInfo['croom'], courseId, i, count, addItems, addType)
|
|
49173
49217
|
if makeFirstTeacherOwner and firstTeacher:
|
|
49174
49218
|
_updateCourseOwner(courseInfo['croom'], courseId, firstTeacher, i, count)
|
|
49175
49219
|
|
|
49176
49220
|
# gam courses <CourseEntity> remove alias <CourseAliasEntity>
|
|
49177
49221
|
# gam course <CourseID> remove alias <CourseAlias>
|
|
49222
|
+
# gam courses <CourseEntity> remove announcement <CourseAnnouncementIDEntity>
|
|
49223
|
+
# gam course <CourseID> remove announcement <CourseAnnouncementID>
|
|
49178
49224
|
# gam courses <CourseEntity> remove topic <CourseTopicIDEntity>
|
|
49179
49225
|
# gam course <CourseID> remove topic <CourseTopicID>
|
|
49180
49226
|
# gam courses <CourseEntity> remove teachers|students [owneracccess] <UserTypeEntity>
|
|
49181
49227
|
# gam course <CourseID> remove teacher|student [owneracccess] <EmailAddress>
|
|
49182
49228
|
def doCourseRemoveItems(courseIdList, getEntityListArg):
|
|
49183
49229
|
croom = buildGAPIObject(API.CLASSROOM)
|
|
49184
|
-
|
|
49230
|
+
removeType = getChoice(ADD_REMOVE_UPDATE_ITEM_TYPES_MAP, mapChoice=True)
|
|
49185
49231
|
if not getEntityListArg:
|
|
49186
|
-
if
|
|
49232
|
+
if removeType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49187
49233
|
useOwnerAccess = GC.Values[GC.USE_COURSE_OWNER_ACCESS]
|
|
49188
49234
|
if checkArgumentPresent(OWNER_ACCESS_OPTIONS):
|
|
49189
49235
|
useOwnerAccess = True
|
|
49190
49236
|
removeItems = getStringReturnInList(Cmd.OB_EMAIL_ADDRESS)
|
|
49191
|
-
elif
|
|
49237
|
+
elif removeType == Ent.COURSE_ALIAS:
|
|
49192
49238
|
useOwnerAccess = False
|
|
49193
49239
|
removeItems = getStringReturnInList(Cmd.OB_COURSE_ALIAS)
|
|
49194
|
-
|
|
49240
|
+
elif removeType == Ent.COURSE_TOPIC:
|
|
49195
49241
|
useOwnerAccess = True
|
|
49196
49242
|
removeItems = getStringReturnInList(Cmd.OB_COURSE_TOPIC_ID)
|
|
49243
|
+
else: # removeType == Ent.COURSE_ANNOUNCEMENT:
|
|
49244
|
+
useOwnerAccess = True
|
|
49245
|
+
removeItems = getStringReturnInList(Cmd.OB_COURSE_ANNOUNCEMENT_ID)
|
|
49197
49246
|
courseParticipantLists = None
|
|
49198
49247
|
else:
|
|
49199
|
-
if
|
|
49248
|
+
if removeType in {Ent.STUDENT, Ent.TEACHER}:
|
|
49200
49249
|
useOwnerAccess = checkArgumentPresent(OWNER_ACCESS_OPTIONS)
|
|
49201
49250
|
_, removeItems = getEntityToModify(defaultEntityType=Cmd.ENTITY_USERS,
|
|
49202
|
-
typeMap={Cmd.ENTITY_COURSEPARTICIPANTS: PARTICIPANT_EN_MAP[
|
|
49203
|
-
elif
|
|
49251
|
+
typeMap={Cmd.ENTITY_COURSEPARTICIPANTS: PARTICIPANT_EN_MAP[removeType]})
|
|
49252
|
+
elif removeType == Ent.COURSE_ALIAS:
|
|
49204
49253
|
useOwnerAccess = False
|
|
49205
49254
|
removeItems = getEntityList(Cmd.OB_COURSE_ALIAS_ENTITY, shlexSplit=True)
|
|
49206
|
-
|
|
49255
|
+
elif removeType == Ent.COURSE_TOPIC:
|
|
49207
49256
|
useOwnerAccess = True
|
|
49208
49257
|
removeItems = getEntityList(Cmd.OB_COURSE_TOPIC_ID_ENTITY, shlexSplit=True)
|
|
49258
|
+
else: # removeType == Ent.COURSE_ANNOUNCEMENT:
|
|
49259
|
+
useOwnerAccess = True
|
|
49260
|
+
removeItems = getEntityList(Cmd.OB_COURSE_ANNOUNCEMENT_ID_ENTITY, shlexSplit=True)
|
|
49209
49261
|
courseParticipantLists = removeItems if isinstance(removeItems, dict) else None
|
|
49210
49262
|
checkForExtraneousArguments()
|
|
49211
49263
|
i, count, coursesInfo = _getCoursesOwnerInfo(croom, courseIdList, useOwnerAccess,
|
|
@@ -49215,7 +49267,72 @@ def doCourseRemoveItems(courseIdList, getEntityListArg):
|
|
|
49215
49267
|
if courseParticipantLists:
|
|
49216
49268
|
removeItems = courseParticipantLists[courseId]
|
|
49217
49269
|
courseId = addCourseIdScope(courseId)
|
|
49218
|
-
_batchRemoveItemsFromCourse(courseInfo['croom'], courseId, i, count, removeItems,
|
|
49270
|
+
_batchRemoveItemsFromCourse(courseInfo['croom'], courseId, i, count, removeItems, removeType)
|
|
49271
|
+
|
|
49272
|
+
# gam courses <CourseEntity> update announcement <CourseAnnouncemntIDEntity>
|
|
49273
|
+
# [text <String>] [scheduledtime <Time>] [state published]
|
|
49274
|
+
# gam course <CourseID> update announcement <CourseAnnouncementID>
|
|
49275
|
+
# [text <String>] [scheduledtime <Time>] [state published]
|
|
49276
|
+
# gam courses <CourseEntity> update topic <CourseTopicIDEntity> <CourseTopic>
|
|
49277
|
+
# gam course <CourseID> update topic <CourseTopicID> <CourseTopic>
|
|
49278
|
+
def doCourseUpdateItems(courseIdList, getEntityListArg):
|
|
49279
|
+
croom = buildGAPIObject(API.CLASSROOM)
|
|
49280
|
+
updateType = getChoice(ADD_REMOVE_UPDATE_ITEM_TYPES_MAP, mapChoice=True)
|
|
49281
|
+
if not getEntityListArg:
|
|
49282
|
+
if updateType == Ent.COURSE_TOPIC:
|
|
49283
|
+
useOwnerAccess = True
|
|
49284
|
+
updateItems = getStringReturnInList(Cmd.OB_COURSE_TOPIC_ID)
|
|
49285
|
+
body = {'name': getString(Cmd.OB_COURSE_TOPIC)}
|
|
49286
|
+
else: # updateType == Ent.COURSE_ANNOUNCEMENT:
|
|
49287
|
+
useOwnerAccess = True
|
|
49288
|
+
updateItems = getStringReturnInList(Cmd.OB_COURSE_ANNOUNCEMENT_ID)
|
|
49289
|
+
body = getCourseAnnouncement(False)
|
|
49290
|
+
courseItemLists = None
|
|
49291
|
+
else:
|
|
49292
|
+
if updateType == Ent.COURSE_TOPIC:
|
|
49293
|
+
useOwnerAccess = True
|
|
49294
|
+
updateItems = getEntityList(Cmd.OB_COURSE_TOPIC_ID_ENTITY, shlexSplit=True)
|
|
49295
|
+
body = {'name': getString(Cmd.OB_COURSE_TOPIC)}
|
|
49296
|
+
else: # updateType == Ent.COURSE_ANNOUNCEMENT:
|
|
49297
|
+
useOwnerAccess = True
|
|
49298
|
+
updateItems = getEntityList(Cmd.OB_COURSE_ANNOUNCEMENT_ID_ENTITY, shlexSplit=True)
|
|
49299
|
+
body = getCourseAnnouncement(False)
|
|
49300
|
+
courseItemLists = updateItems if isinstance(updateItems, dict) else None
|
|
49301
|
+
checkForExtraneousArguments()
|
|
49302
|
+
i, count, coursesInfo = _getCoursesOwnerInfo(croom, courseIdList, useOwnerAccess,
|
|
49303
|
+
addCIIdScope=courseItemLists is None)
|
|
49304
|
+
for courseId, courseInfo in coursesInfo.items():
|
|
49305
|
+
i += 1
|
|
49306
|
+
if courseItemLists:
|
|
49307
|
+
updateItems = courseItemLists[courseId]
|
|
49308
|
+
courseId = addCourseIdScope(courseId)
|
|
49309
|
+
jcount = len(updateItems)
|
|
49310
|
+
noScopeCourseId = removeCourseIdScope(courseId)
|
|
49311
|
+
if updateType == Ent.COURSE_TOPIC:
|
|
49312
|
+
service = courseInfo['croom'].courses().topics()
|
|
49313
|
+
else: # updateType == Ent.COURSE_ANNOUNCEMENT:
|
|
49314
|
+
service = courseInfo['croom'].courses().announcements()
|
|
49315
|
+
entityPerformActionNumItems([Ent.COURSE, noScopeCourseId], jcount, updateType, i, count)
|
|
49316
|
+
Ind.Increment()
|
|
49317
|
+
j = 0
|
|
49318
|
+
for updateItem in updateItems:
|
|
49319
|
+
j += 1
|
|
49320
|
+
try:
|
|
49321
|
+
callGAPI(service, 'patch',
|
|
49322
|
+
throwReasons=[GAPI.NOT_FOUND, GAPI.FORBIDDEN, GAPI.PERMISSION_DENIED,
|
|
49323
|
+
GAPI.QUOTA_EXCEEDED, GAPI.SERVICE_NOT_AVAILABLE],
|
|
49324
|
+
retryReasons=[GAPI.NOT_FOUND, GAPI.SERVICE_NOT_AVAILABLE],
|
|
49325
|
+
courseId=addCourseIdScope(courseId), id=updateItem, updateMask=','.join(body.keys()), body=body, fields='')
|
|
49326
|
+
entityActionPerformed([Ent.COURSE, courseId, updateType, updateItem], j, jcount)
|
|
49327
|
+
except GAPI.notFound:
|
|
49328
|
+
entityActionFailedWarning([Ent.COURSE, courseId, updateType, updateItem], Msg.DOES_NOT_EXIST, j, jcount)
|
|
49329
|
+
except GAPI.forbidden:
|
|
49330
|
+
entityActionFailedWarning([Ent.COURSE, courseId, updateType, updateItem], Msg.FORBIDDEN, j, jcount)
|
|
49331
|
+
except GAPI.permissionDenied:
|
|
49332
|
+
entityActionFailedWarning([Ent.COURSE, courseId, updateType, updateItem], Msg.PERMISSION_DENIED, j, jcount)
|
|
49333
|
+
except (GAPI.quotaExceeded, GAPI.serviceNotAvailable) as e:
|
|
49334
|
+
entityActionFailedWarning([Ent.COURSE, courseId, updateType, updateItem], str(e), j, jcount)
|
|
49335
|
+
Ind.Decrement()
|
|
49219
49336
|
|
|
49220
49337
|
# gam courses <CourseEntity> clear teachers|students
|
|
49221
49338
|
# gam course <CourseID> clear teacher|student
|
|
@@ -77165,6 +77282,7 @@ COURSE_SUBCOMMANDS = {
|
|
|
77165
77282
|
'add': (Act.ADD, doCourseAddItems),
|
|
77166
77283
|
'clear': (Act.REMOVE, doCourseClearParticipants),
|
|
77167
77284
|
'remove': (Act.REMOVE, doCourseRemoveItems),
|
|
77285
|
+
'update': (Act.UPDATE, doCourseUpdateItems),
|
|
77168
77286
|
'sync': (Act.SYNC, doCourseSyncParticipants),
|
|
77169
77287
|
}
|
|
77170
77288
|
|
gam/gamlib/glclargs.py
CHANGED
|
@@ -875,8 +875,11 @@ class GamCLArgs():
|
|
|
875
875
|
OB_CONTACT_GROUP_ITEM = 'ContactGroupItem'
|
|
876
876
|
OB_COURSE_ALIAS = 'CourseAlias'
|
|
877
877
|
OB_COURSE_ALIAS_ENTITY = 'CourseAliasEntity'
|
|
878
|
+
OB_COURSE_ANNOUNCEMENT_ID = "CourseAnnouncementID"
|
|
878
879
|
OB_COURSE_ANNOUNCEMENT_ID_ENTITY = "CourseAnnouncementIDEntity"
|
|
879
880
|
OB_COURSE_ANNOUNCEMENT_STATE_LIST = "CourseAnnouncementStateList"
|
|
881
|
+
OB_COURSE_ANNOUNCEMENT_ADD_STATE_LIST = "CourseAnnouncementAddStateList"
|
|
882
|
+
OB_COURSE_ANNOUNCEMENT_UPDATE_STATE_LIST = "CourseAnnouncementUpdateStateList"
|
|
880
883
|
OB_COURSE_ENTITY = 'CourseEntity'
|
|
881
884
|
OB_COURSE_ID = 'CourseID'
|
|
882
885
|
OB_COURSE_MATERIAL_ID_ENTITY = 'CourseMaterialIDEntity'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
gam/__init__.py,sha256=
|
|
1
|
+
gam/__init__.py,sha256=LGOfPmsfDfMeTyC8wEv38P4K-9Tp5OQpvhBjul5puL4,3541795
|
|
2
2
|
gam/__main__.py,sha256=amz0-959ph6zkZKqjaar4n60yho-T37w6qWI36qx0CA,1049
|
|
3
3
|
gam/cacerts.pem,sha256=82Ak7btW_2XvocLUvAwPmpx8Chi0oqtZUG1gseLK_t4,50235
|
|
4
4
|
gam/cbcm-v1.1beta1.json,sha256=xO5XloCQQULmPbFBx5bckdqmbLFQ7sJ2TImhE1ysDIY,19439
|
|
@@ -25,7 +25,7 @@ gam/gamlib/__init__.py,sha256=z5mF-y0j8pm-YNFBaiuxB4M_GAUPG-cXWwrhYwrVReM,679
|
|
|
25
25
|
gam/gamlib/glaction.py,sha256=1Il_HrChVnPkzZwiZs5au4mFQVtq4K1Z42uIuR6qdnI,9419
|
|
26
26
|
gam/gamlib/glapi.py,sha256=27NW2etvdNK4jfR699eqFzhV4gPotijXIQeX-wxCvHA,35319
|
|
27
27
|
gam/gamlib/glcfg.py,sha256=bNTckxzIM_HruxO2DfYsDbEgqOIz1RX6CbU6XOQQQyg,28296
|
|
28
|
-
gam/gamlib/glclargs.py,sha256=
|
|
28
|
+
gam/gamlib/glclargs.py,sha256=Q0aaKTFYna18cdnPMrwQYThCEgYXgGby9UngnXBGZjY,42681
|
|
29
29
|
gam/gamlib/glentity.py,sha256=c9-7MAp0HruXEUVq8Nwkllxc4KypFeZRUFkvVzPwrwk,33760
|
|
30
30
|
gam/gamlib/glgapi.py,sha256=2mu7DQGGYmF7ZGXeBQu_mT1FNZgXbEQqcddJjHzbvE4,39833
|
|
31
31
|
gam/gamlib/glgdata.py,sha256=weRppttWm6uRyqtBoGPKoHiNZ2h28nhfUV4J_mbCszY,2707
|
|
@@ -65,8 +65,8 @@ gam/googleapiclient/discovery_cache/base.py,sha256=yCDPtxnbNN-p5_9fzBacC6P3wcUPl
|
|
|
65
65
|
gam/googleapiclient/discovery_cache/file_cache.py,sha256=sim3Mg4HgRYo3vX75jvcKy_aV568EvIrtBfvfbw-044,4774
|
|
66
66
|
gam/iso8601/__init__.py,sha256=Z2PsYbXgAH5a5xzUvgczCboPzqWpm65kRcIngCnhViU,1218
|
|
67
67
|
gam/iso8601/iso8601.py,sha256=Li2FHZ4sBTWuthuQhyCvmvj0j6At8JbGzkSv2fc2RHU,4384
|
|
68
|
-
gam7-7.
|
|
69
|
-
gam7-7.
|
|
70
|
-
gam7-7.
|
|
71
|
-
gam7-7.
|
|
72
|
-
gam7-7.
|
|
68
|
+
gam7-7.11.0.dist-info/METADATA,sha256=Gj9pwsrYzuf2IHM4qxcRWLPhz65GTySIa92YiFAaxjg,2978
|
|
69
|
+
gam7-7.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
70
|
+
gam7-7.11.0.dist-info/entry_points.txt,sha256=HVUM5J7dA8YwvJfG30jiLefR19ExMs387TWugWd9sf4,42
|
|
71
|
+
gam7-7.11.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
72
|
+
gam7-7.11.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|