mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-10 14:43:34 +00:00
Multiple small fixes (#800)
* Multiple small fixes Allow mixed case when creating/updating/deleting alias: 362/378, 8068, 8622, 10162 Recode callGAPIpages for future benefits: 890/940 Handle out of range start_time end_time values in gam report: 1441/1444 Work around API bug where primary can't be used as calendarId: 2979/2980 Code cleanup in doCalendarAddEvent: 3507/3600 Get integers with subroutine: 228-236, multiple calls Minimize data download in doDeleteGuardian: 2330/2348 Add contentmanager/fileorganizer role: 3984/4074 * Fix typos * Code cleanup calendar ACL commands; add sendnotifications * Correct documentation error * Add operatingSystemType to user posix attribute * Add Jay's changes group member delivery settings, check max sheet bytes on CSV upload * Cleanup writeCSVfile sheet size checking * Revert "Add Jay's changes" This reverts commit9eb90ba7d7
. * Revert "Cleanup writeCSVfile sheet size checking" This reverts commit139a2f7f4c
. * More reverting
This commit is contained in:
@ -147,7 +147,7 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
<CrOSID> ::= <String>
|
<CrOSID> ::= <String>
|
||||||
<CustomerID> ::= <String>
|
<CustomerID> ::= <String>
|
||||||
<DomainAlias> ::= <String>
|
<DomainAlias> ::= <String>
|
||||||
<DriveFileACLRole> ::= commenter|editor|organizer|owner|reader|writer
|
<DriveFileACLRole> ::= commenter|contentmanager|editor|fileorganizer|organizer|owner|reader|writer
|
||||||
<DriveFileID> ::= <String>
|
<DriveFileID> ::= <String>
|
||||||
<DriveFileURL> ::= https://docs.google.com/a/<DomainName>/document/d/<DriveFileID>/<String>
|
<DriveFileURL> ::= https://docs.google.com/a/<DomainName>/document/d/<DriveFileID>/<String>
|
||||||
<DriveFileItem> ::= <DriveFileID>|<DriveFileURL>
|
<DriveFileItem> ::= <DriveFileID>|<DriveFileURL>
|
||||||
@ -388,8 +388,8 @@ If an item contains spaces, it should be surrounded by ".
|
|||||||
<MembersFieldName> ::=
|
<MembersFieldName> ::=
|
||||||
email|
|
email|
|
||||||
id|
|
id|
|
||||||
name|
|
|
||||||
role|
|
role|
|
||||||
|
status|
|
||||||
type
|
type
|
||||||
|
|
||||||
<MobileFieldName> ::=
|
<MobileFieldName> ::=
|
||||||
@ -580,9 +580,9 @@ Specify a collection of Users by directly specifying them or by specifiying item
|
|||||||
(user <UserItem>)|
|
(user <UserItem>)|
|
||||||
(users <UserList>)|
|
(users <UserList>)|
|
||||||
(group|group_ns|group_susp <GroupItem)|
|
(group|group_ns|group_susp <GroupItem)|
|
||||||
(ou|org <OrgUnitPath)|
|
(ou|org <OrgUnitPath>)|
|
||||||
(ou_ns|org_ns <OrgUnitPath)|
|
(ou_ns|org_ns <OrgUnitPath>)|
|
||||||
(ou_susp|org_susp <OrgUnitPath)|
|
(ou_susp|org_susp <OrgUnitPath>)|
|
||||||
(ou_and_children|ou_and_child <OrgUnitPath>)|
|
(ou_and_children|ou_and_child <OrgUnitPath>)|
|
||||||
(ou_and_children_ns|ou_and_child_ns <OrgUnitPath>)|
|
(ou_and_children_ns|ou_and_child_ns <OrgUnitPath>)|
|
||||||
(ou_and_children_susp|ou_and_child_susp <OrgUnitPath>)|
|
(ou_and_children_susp|ou_and_child_susp <OrgUnitPath>)|
|
||||||
@ -881,8 +881,8 @@ gam delete alias|nickname [user|group|target] <UniqueID>|<EmailAddress>
|
|||||||
gam info alias|nickname <EmailAddress>
|
gam info alias|nickname <EmailAddress>
|
||||||
gam print aliases|nicknames [todrive] [shownoneditable] [nogroups] [nousers] [(query <QueryUser>)|(queries <QueryUserList)]
|
gam print aliases|nicknames [todrive] [shownoneditable] [nogroups] [nousers] [(query <QueryUser>)|(queries <QueryUserList)]
|
||||||
|
|
||||||
gam calendar <CalendarItem> add <CalendarACLRole> ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default
|
gam calendar <CalendarItem> add <CalendarACLRole> ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default [sendnotifications <Boolean>]
|
||||||
gam calendar <CalendarItem> update <CalendarACLRole> ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default
|
gam calendar <CalendarItem> update <CalendarACLRole> ([user] <EmailAddress>)|(group <EmailAddress>)|(domain [<DomainName>])|default [sendnotifications <Boolean>]
|
||||||
gam calendar <CalendarItem> del|delete <CalendarACLRole> <EmailAddress>|(domain [<DomainName>])|default
|
gam calendar <CalendarItem> del|delete <CalendarACLRole> <EmailAddress>|(domain [<DomainName>])|default
|
||||||
gam calendar <CalendarItem> showacl
|
gam calendar <CalendarItem> showacl
|
||||||
|
|
||||||
@ -1015,18 +1015,21 @@ gam delete user <UserItem>
|
|||||||
gam undelete user <UserItem> [org|ou <OrgUnitPath>]
|
gam undelete user <UserItem> [org|ou <OrgUnitPath>]
|
||||||
gam info user [<UserItem>] [noaliases] [nogroups] [nolicenses|nolicences] [noschemas] [schemas|custom <SchemaNameList>] [userview] [skus|sku <SKUIDList>]
|
gam info user [<UserItem>] [noaliases] [nogroups] [nolicenses|nolicences] [noschemas] [schemas|custom <SchemaNameList>] [userview] [skus|sku <SKUIDList>]
|
||||||
|
|
||||||
gam print users [todrive] ([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)] [deleted_only|only_deleted])
|
Print fields for selected users; use domain, query/queries and deleted_only to select users to print;
|
||||||
|
if none of these options are specified, all users are printed.
|
||||||
|
The first column will always be primaryEmail; the remaining field names will be sorted if allfields, basic, full or sortheaders is specified;
|
||||||
|
otherwise, the remaining field names will appear in the order specified.
|
||||||
|
|
||||||
|
gam print users [todrive]
|
||||||
|
([domain <DomainName>] [(query <QueryUser>)|(queries <QueryUserList>)] [deleted_only|only_deleted])
|
||||||
[groups] [license|licenses|licence|licences] [emailpart|emailparts|username]
|
[groups] [license|licenses|licence|licences] [emailpart|emailparts|username]
|
||||||
[orderby <UserOrderByFieldName> [ascending|descending]] [userview]
|
[orderby <UserOrderByFieldName> [ascending|descending]] [userview]
|
||||||
[allfields|basic|full | ((<UserFieldName>* | fields <UserFieldNameList>) [schemas|custom all|<SchemaNameList>])]
|
[allfields|basic|full | ((<UserFieldName>* | fields <UserFieldNameList>) [schemas|custom all|<SchemaNameList>])]
|
||||||
[delimiter <Character>] [sortheaders]
|
[delimiter <Character>] [sortheaders]
|
||||||
gam <UserTypeEntity> print
|
|
||||||
|
|
||||||
Summary of printing:
|
Print no header row and primaryEmail for specified users.
|
||||||
gam print users
|
|
||||||
Prints a header row and primaryEmail for all users.
|
|
||||||
gam <UserTypeEntity> print
|
gam <UserTypeEntity> print
|
||||||
Prints no header row and primaryEmail for specified users.
|
|
||||||
|
|
||||||
gam create verify|verification <DomainName>
|
gam create verify|verification <DomainName>
|
||||||
gam update verify|verification <DomainName> cname|txt|text|site|file
|
gam update verify|verification <DomainName> cname|txt|text|site|file
|
||||||
@ -1128,7 +1131,7 @@ gam <UserTypeEntity> print calendars [todrive]
|
|||||||
|
|
||||||
gam <UserTypeEntity> show calsettings
|
gam <UserTypeEntity> show calsettings
|
||||||
gam <UserTypeEntity> update calattendees csv <FileName> [dryrun] [start <Date>] [end <Date>] [allevents]
|
gam <UserTypeEntity> update calattendees csv <FileName> [dryrun] [start <Date>] [end <Date>] [allevents]
|
||||||
gam <UserTypeEntity> transfer seccals <UserItem> [keepuser]
|
gam <UserTypeEntity> transfer seccals <UserItem> [keepuser] [sendnotifications <Boolean>]
|
||||||
|
|
||||||
gam <UserTypeEntity> print|show driveactivity [todrive] [fileid <DriveFileID>] [folderid <DriveFolderID>]
|
gam <UserTypeEntity> print|show driveactivity [todrive] [fileid <DriveFileID>] [folderid <DriveFolderID>]
|
||||||
gam <UserTypeEntity> print|show drivesettings [todrive]
|
gam <UserTypeEntity> print|show drivesettings [todrive]
|
||||||
|
388
src/gam.py
388
src/gam.py
@ -225,6 +225,15 @@ def integerLimits(minVal, maxVal, item=u'integer'):
|
|||||||
return u'{0} x<={1}'.format(item, maxVal)
|
return u'{0} x<={1}'.format(item, maxVal)
|
||||||
return u'{0} x'.format(item)
|
return u'{0} x'.format(item)
|
||||||
|
|
||||||
|
def getInteger(value, item, minVal=None, maxVal=None):
|
||||||
|
try:
|
||||||
|
number = int(value.strip())
|
||||||
|
if ((minVal is None) or (number >= minVal)) and ((maxVal is None) or (number <= maxVal)):
|
||||||
|
return number
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
systemErrorExit(2, u'expected {0} in range <{1}>, got {2}'.format(item, integerLimits(minVal, maxVal), value))
|
||||||
|
|
||||||
def removeCourseIdScope(courseId):
|
def removeCourseIdScope(courseId):
|
||||||
if courseId.startswith(u'd:'):
|
if courseId.startswith(u'd:'):
|
||||||
return courseId[2:]
|
return courseId[2:]
|
||||||
@ -350,7 +359,7 @@ def splitEmailAddress(emailAddress):
|
|||||||
# foo@ -> foo@domain
|
# foo@ -> foo@domain
|
||||||
# foo@bar.com -> foo@bar.com
|
# foo@bar.com -> foo@bar.com
|
||||||
# @domain -> domain
|
# @domain -> domain
|
||||||
def normalizeEmailAddressOrUID(emailAddressOrUID, noUid=False, checkForCustomerId=False):
|
def normalizeEmailAddressOrUID(emailAddressOrUID, noUid=False, checkForCustomerId=False, noLower=False):
|
||||||
if checkForCustomerId and (emailAddressOrUID == GC_Values[GC_CUSTOMER_ID]):
|
if checkForCustomerId and (emailAddressOrUID == GC_Values[GC_CUSTOMER_ID]):
|
||||||
return emailAddressOrUID
|
return emailAddressOrUID
|
||||||
if (not noUid) and (emailAddressOrUID.find(u':') != -1):
|
if (not noUid) and (emailAddressOrUID.find(u':') != -1):
|
||||||
@ -360,13 +369,13 @@ def normalizeEmailAddressOrUID(emailAddressOrUID, noUid=False, checkForCustomerI
|
|||||||
return emailAddressOrUID[3:]
|
return emailAddressOrUID[3:]
|
||||||
atLoc = emailAddressOrUID.find(u'@')
|
atLoc = emailAddressOrUID.find(u'@')
|
||||||
if atLoc == 0:
|
if atLoc == 0:
|
||||||
return emailAddressOrUID[1:].lower()
|
return emailAddressOrUID[1:].lower() if not noLower else emailAddressOrUID[1:]
|
||||||
if (atLoc == -1) or (atLoc == len(emailAddressOrUID)-1) and GC_Values[GC_DOMAIN]:
|
if (atLoc == -1) or (atLoc == len(emailAddressOrUID)-1) and GC_Values[GC_DOMAIN]:
|
||||||
if atLoc == -1:
|
if atLoc == -1:
|
||||||
emailAddressOrUID = u'{0}@{1}'.format(emailAddressOrUID, GC_Values[GC_DOMAIN])
|
emailAddressOrUID = u'{0}@{1}'.format(emailAddressOrUID, GC_Values[GC_DOMAIN])
|
||||||
else:
|
else:
|
||||||
emailAddressOrUID = u'{0}{1}'.format(emailAddressOrUID, GC_Values[GC_DOMAIN])
|
emailAddressOrUID = u'{0}{1}'.format(emailAddressOrUID, GC_Values[GC_DOMAIN])
|
||||||
return emailAddressOrUID.lower()
|
return emailAddressOrUID.lower() if not noLower else emailAddressOrUID
|
||||||
|
|
||||||
# Normalize student/guardian email address/uid
|
# Normalize student/guardian email address/uid
|
||||||
# 12345678 -> 12345678
|
# 12345678 -> 12345678
|
||||||
@ -878,6 +887,41 @@ def callGAPI(service, function,
|
|||||||
except httplib2.ServerNotFoundError as e:
|
except httplib2.ServerNotFoundError as e:
|
||||||
systemErrorExit(4, str(e))
|
systemErrorExit(4, str(e))
|
||||||
|
|
||||||
|
def _processGAPIpagesResult(this_page, items, all_pages, total_items, page_message, message_attribute):
|
||||||
|
if this_page:
|
||||||
|
pageToken = this_page.get(u'nextPageToken')
|
||||||
|
if items in this_page:
|
||||||
|
page_items = len(this_page[items])
|
||||||
|
total_items += page_items
|
||||||
|
if all_pages is not None:
|
||||||
|
all_pages.extend(this_page[items])
|
||||||
|
else:
|
||||||
|
this_page = {items: []}
|
||||||
|
page_items = 0
|
||||||
|
else:
|
||||||
|
pageToken = None
|
||||||
|
this_page = {items: []}
|
||||||
|
page_items = 0
|
||||||
|
if page_message:
|
||||||
|
show_message = page_message.replace(u'%%num_items%%', str(page_items))
|
||||||
|
show_message = show_message.replace(u'%%total_items%%', str(total_items))
|
||||||
|
if message_attribute:
|
||||||
|
try:
|
||||||
|
show_message = show_message.replace(u'%%first_item%%', str(this_page[items][0][message_attribute]))
|
||||||
|
show_message = show_message.replace(u'%%last_item%%', str(this_page[items][-1][message_attribute]))
|
||||||
|
except (IndexError, KeyError):
|
||||||
|
show_message = show_message.replace(u'%%first_item%%', u'')
|
||||||
|
show_message = show_message.replace(u'%%last_item%%', u'')
|
||||||
|
sys.stderr.write(u'\r')
|
||||||
|
sys.stderr.flush()
|
||||||
|
sys.stderr.write(show_message)
|
||||||
|
return (pageToken, total_items)
|
||||||
|
|
||||||
|
def _finalizeGAPIpagesResult(page_message):
|
||||||
|
if page_message and (page_message[-1] != u'\n'):
|
||||||
|
sys.stderr.write(u'\r\n')
|
||||||
|
sys.stderr.flush()
|
||||||
|
|
||||||
def callGAPIpages(service, function, items,
|
def callGAPIpages(service, function, items,
|
||||||
page_message=None, message_attribute=None,
|
page_message=None, message_attribute=None,
|
||||||
soft_errors=False, throw_reasons=None, retry_reasons=None,
|
soft_errors=False, throw_reasons=None, retry_reasons=None,
|
||||||
@ -889,37 +933,11 @@ def callGAPIpages(service, function, items,
|
|||||||
while True:
|
while True:
|
||||||
this_page = callGAPI(service, function, soft_errors=soft_errors,
|
this_page = callGAPI(service, function, soft_errors=soft_errors,
|
||||||
throw_reasons=throw_reasons, retry_reasons=retry_reasons, **kwargs)
|
throw_reasons=throw_reasons, retry_reasons=retry_reasons, **kwargs)
|
||||||
if this_page:
|
pageToken, total_items = _processGAPIpagesResult(this_page, items, all_pages, total_items, page_message, message_attribute)
|
||||||
if items in this_page:
|
if not pageToken:
|
||||||
page_items = len(this_page[items])
|
_finalizeGAPIpagesResult(page_message)
|
||||||
total_items += page_items
|
|
||||||
all_pages.extend(this_page[items])
|
|
||||||
else:
|
|
||||||
this_page = {items: []}
|
|
||||||
page_items = 0
|
|
||||||
else:
|
|
||||||
this_page = {items: []}
|
|
||||||
page_items = 0
|
|
||||||
if page_message:
|
|
||||||
show_message = page_message.replace(u'%%num_items%%', str(page_items))
|
|
||||||
show_message = show_message.replace(u'%%total_items%%', str(total_items))
|
|
||||||
if message_attribute:
|
|
||||||
try:
|
|
||||||
show_message = show_message.replace(u'%%first_item%%', str(this_page[items][0][message_attribute]))
|
|
||||||
show_message = show_message.replace(u'%%last_item%%', str(this_page[items][-1][message_attribute]))
|
|
||||||
except (IndexError, KeyError):
|
|
||||||
show_message = show_message.replace(u'%%first_item%%', u'')
|
|
||||||
show_message = show_message.replace(u'%%last_item%%', u'')
|
|
||||||
sys.stderr.write(u'\r')
|
|
||||||
sys.stderr.flush()
|
|
||||||
sys.stderr.write(show_message)
|
|
||||||
if this_page and this_page.get(u'nextPageToken'):
|
|
||||||
kwargs[u'pageToken'] = this_page[u'nextPageToken']
|
|
||||||
else:
|
|
||||||
if page_message and (page_message[-1] != u'\n'):
|
|
||||||
sys.stderr.write(u'\r\n')
|
|
||||||
sys.stderr.flush()
|
|
||||||
return all_pages
|
return all_pages
|
||||||
|
kwargs[u'pageToken'] = pageToken
|
||||||
|
|
||||||
def callGAPIitems(service, function, items,
|
def callGAPIitems(service, function, items,
|
||||||
throw_reasons=None, retry_reasons=None,
|
throw_reasons=None, retry_reasons=None,
|
||||||
@ -1420,8 +1438,10 @@ def showReport():
|
|||||||
if item[u'name'] in [u'start_time', u'end_time']:
|
if item[u'name'] in [u'start_time', u'end_time']:
|
||||||
val = item.get(u'intValue')
|
val = item.get(u'intValue')
|
||||||
if val is not None:
|
if val is not None:
|
||||||
item[u'dateTimeValue'] = datetime.datetime.fromtimestamp(int(val)-62135683200).isoformat()
|
val = int(val)
|
||||||
item.pop(u'intValue')
|
if val >= 62135683200:
|
||||||
|
item[u'dateTimeValue'] = datetime.datetime.fromtimestamp(val-62135683200).isoformat()
|
||||||
|
item.pop(u'intValue')
|
||||||
row = flatten_json(event)
|
row = flatten_json(event)
|
||||||
row.update(activity_row)
|
row.update(activity_row)
|
||||||
for item in row:
|
for item in row:
|
||||||
@ -1773,6 +1793,7 @@ def doGetCustomerInfo():
|
|||||||
if customerId == MY_CUSTOMER:
|
if customerId == MY_CUSTOMER:
|
||||||
customerId = None
|
customerId = None
|
||||||
rep = buildGAPIObject(u'reports')
|
rep = buildGAPIObject(u'reports')
|
||||||
|
usage = None
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
usage = callGAPIpages(rep.customerUsageReports(), u'get', u'usageReports', throw_reasons=[GAPI_INVALID],
|
usage = callGAPIpages(rep.customerUsageReports(), u'get', u'usageReports', throw_reasons=[GAPI_INVALID],
|
||||||
@ -2306,10 +2327,11 @@ def doDeleteGuardian():
|
|||||||
try:
|
try:
|
||||||
results = callGAPIpages(croom.userProfiles().guardians(), u'list', u'guardians',
|
results = callGAPIpages(croom.userProfiles().guardians(), u'list', u'guardians',
|
||||||
throw_reasons=[GAPI_FORBIDDEN],
|
throw_reasons=[GAPI_FORBIDDEN],
|
||||||
studentId=studentId, invitedEmailAddress=guardianId)
|
studentId=studentId, invitedEmailAddress=guardianId,
|
||||||
|
fields=u'nextPageToken,guardians(studentId,guardianId)')
|
||||||
if len(results) > 0:
|
if len(results) > 0:
|
||||||
for result in results:
|
for result in results:
|
||||||
_deleteGuardian(croom, studentId, result[u'guardianId'], guardianId)
|
_deleteGuardian(croom, result[u'studentId'], result[u'guardianId'], guardianId)
|
||||||
return
|
return
|
||||||
except GAPI_forbidden:
|
except GAPI_forbidden:
|
||||||
entityUnknownWarning(u'Student', studentId, 0, 0)
|
entityUnknownWarning(u'Student', studentId, 0, 0)
|
||||||
@ -2322,10 +2344,11 @@ def doDeleteGuardian():
|
|||||||
try:
|
try:
|
||||||
results = callGAPIpages(croom.userProfiles().guardianInvitations(), u'list', u'guardianInvitations',
|
results = callGAPIpages(croom.userProfiles().guardianInvitations(), u'list', u'guardianInvitations',
|
||||||
throw_reasons=[GAPI_FORBIDDEN],
|
throw_reasons=[GAPI_FORBIDDEN],
|
||||||
studentId=studentId, invitedEmailAddress=guardianId, states=[u'PENDING',])
|
studentId=studentId, invitedEmailAddress=guardianId, states=[u'PENDING',],
|
||||||
|
fields=u'nextPageToken,guardianInvitations(studentId,invitationId)')
|
||||||
if len(results) > 0:
|
if len(results) > 0:
|
||||||
for result in results:
|
for result in results:
|
||||||
status = _cancelGuardianInvitation(croom, studentId, result[u'invitationId'])
|
status = _cancelGuardianInvitation(croom, result[u'studentId'], result[u'invitationId'])
|
||||||
sys.exit(status)
|
sys.exit(status)
|
||||||
except GAPI_forbidden:
|
except GAPI_forbidden:
|
||||||
entityUnknownWarning(u'Student', studentId, 0, 0)
|
entityUnknownWarning(u'Student', studentId, 0, 0)
|
||||||
@ -2675,7 +2698,7 @@ def doPrintPrintJobs():
|
|||||||
owner = sys.argv[i+1]
|
owner = sys.argv[i+1]
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'limit':
|
elif myarg == u'limit':
|
||||||
jobLimit = max(0, int(sys.argv[i+1]))
|
jobLimit = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
else:
|
else:
|
||||||
systemErrorExit(2, '%s is not a valid argument for "gam print printjobs"' % sys.argv[i])
|
systemErrorExit(2, '%s is not a valid argument for "gam print printjobs"' % sys.argv[i])
|
||||||
@ -2867,6 +2890,14 @@ def deleteCalendar(users):
|
|||||||
continue
|
continue
|
||||||
callGAPI(cal.calendarList(), u'delete', soft_errors=True, calendarId=calendarId)
|
callGAPI(cal.calendarList(), u'delete', soft_errors=True, calendarId=calendarId)
|
||||||
|
|
||||||
|
CALENDAR_REMINDER_MAX_MINUTES = 40320
|
||||||
|
|
||||||
|
CALENDAR_MIN_COLOR_INDEX = 1
|
||||||
|
CALENDAR_MAX_COLOR_INDEX = 24
|
||||||
|
|
||||||
|
CALENDAR_EVENT_MIN_COLOR_INDEX = 1
|
||||||
|
CALENDAR_EVENT_MAX_COLOR_INDEX = 11
|
||||||
|
|
||||||
def getCalendarAttributes(i, body, function):
|
def getCalendarAttributes(i, body, function):
|
||||||
colorRgbFormat = False
|
colorRgbFormat = False
|
||||||
while i < len(sys.argv):
|
while i < len(sys.argv):
|
||||||
@ -2881,7 +2912,7 @@ def getCalendarAttributes(i, body, function):
|
|||||||
body[u'summaryOverride'] = sys.argv[i+1]
|
body[u'summaryOverride'] = sys.argv[i+1]
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'colorindex':
|
elif myarg == u'colorindex':
|
||||||
body[u'colorId'] = str(sys.argv[i+1])
|
body[u'colorId'] = getInteger(sys.argv[i+1], myarg, minVal=CALENDAR_MIN_COLOR_INDEX, maxVal=CALENDAR_MAX_COLOR_INDEX)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'backgroundcolor':
|
elif myarg == u'backgroundcolor':
|
||||||
body[u'backgroundColor'] = getColor(sys.argv[i+1])
|
body[u'backgroundColor'] = getColor(sys.argv[i+1])
|
||||||
@ -2897,10 +2928,7 @@ def getCalendarAttributes(i, body, function):
|
|||||||
if method not in CLEAR_NONE_ARGUMENT:
|
if method not in CLEAR_NONE_ARGUMENT:
|
||||||
if method not in CALENDAR_REMINDER_METHODS:
|
if method not in CALENDAR_REMINDER_METHODS:
|
||||||
systemErrorExit(2, 'Method must be one of %s; got %s' % (u', '.join(CALENDAR_REMINDER_METHODS+CLEAR_NONE_ARGUMENT), method))
|
systemErrorExit(2, 'Method must be one of %s; got %s' % (u', '.join(CALENDAR_REMINDER_METHODS+CLEAR_NONE_ARGUMENT), method))
|
||||||
try:
|
minutes = getInteger(sys.argv[i+2], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES)
|
||||||
minutes = int(sys.argv[i+2])
|
|
||||||
except ValueError:
|
|
||||||
systemErrorExit(2, 'Reminder time must be specified in minutes; got %s' % sys.argv[i+2])
|
|
||||||
body[u'defaultReminders'].append({u'method': method, u'minutes': minutes})
|
body[u'defaultReminders'].append({u'method': method, u'minutes': minutes})
|
||||||
i += 3
|
i += 3
|
||||||
else:
|
else:
|
||||||
@ -2948,7 +2976,8 @@ def updateCalendar(users):
|
|||||||
if not cal:
|
if not cal:
|
||||||
continue
|
continue
|
||||||
print u"Updating %s's subscription to calendar %s (%s/%s)" % (user, calendarId, i, count)
|
print u"Updating %s's subscription to calendar %s (%s/%s)" % (user, calendarId, i, count)
|
||||||
callGAPI(cal.calendarList(), u'patch', soft_errors=True, calendarId=calendarId, body=body, colorRgbFormat=colorRgbFormat)
|
calId = calendarId if calendarId != u'primary' else user
|
||||||
|
callGAPI(cal.calendarList(), u'patch', soft_errors=True, calendarId=calId, body=body, colorRgbFormat=colorRgbFormat)
|
||||||
|
|
||||||
def doPrinterShowACL():
|
def doPrinterShowACL():
|
||||||
cp = buildGAPIObject(u'cloudprint')
|
cp = buildGAPIObject(u'cloudprint')
|
||||||
@ -3097,7 +3126,7 @@ def doPrintJobFetch():
|
|||||||
owner = sys.argv[i+1]
|
owner = sys.argv[i+1]
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'limit':
|
elif myarg == u'limit':
|
||||||
jobLimit = max(0, int(sys.argv[i+1]))
|
jobLimit = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'drivedir':
|
elif myarg == u'drivedir':
|
||||||
targetFolder = GC_Values[GC_DRIVE_DIR]
|
targetFolder = GC_Values[GC_DRIVE_DIR]
|
||||||
@ -3339,6 +3368,11 @@ def checkCloudPrintResult(result):
|
|||||||
if not result[u'success']:
|
if not result[u'success']:
|
||||||
systemErrorExit(result[u'errorCode'], '%s: %s' % (result[u'errorCode'], result[u'message']))
|
systemErrorExit(result[u'errorCode'], '%s: %s' % (result[u'errorCode'], result[u'message']))
|
||||||
|
|
||||||
|
def formatACLScope(rule):
|
||||||
|
if rule[u'scope'][u'type'] != u'default':
|
||||||
|
return u'(Scope: {0}:{1})'.format(rule[u'scope'][u'type'], rule[u'scope'][u'value'])
|
||||||
|
return u'(Scope: {0})'.format(rule[u'scope'][u'type'])
|
||||||
|
|
||||||
def formatACLRule(rule):
|
def formatACLRule(rule):
|
||||||
if rule[u'scope'][u'type'] != u'default':
|
if rule[u'scope'][u'type'] != u'default':
|
||||||
return u'(Scope: {0}:{1}, Role: {2})'.format(rule[u'scope'][u'type'], rule[u'scope'][u'value'], rule[u'role'])
|
return u'(Scope: {0}:{1}, Role: {2})'.format(rule[u'scope'][u'type'], rule[u'scope'][u'value'], rule[u'role'])
|
||||||
@ -3355,70 +3389,64 @@ def doCalendarShowACL():
|
|||||||
i += 1
|
i += 1
|
||||||
print u'Calendar: {0}, ACL: {1}{2}'.format(calendarId, formatACLRule(rule), currentCount(i, count))
|
print u'Calendar: {0}, ACL: {1}{2}'.format(calendarId, formatACLRule(rule), currentCount(i, count))
|
||||||
|
|
||||||
def doCalendarAddACL(calendarId=None, act_as=None, role=None, scope=None, entity=None):
|
def _getCalendarACLScope(i, body):
|
||||||
if calendarId is None:
|
body[u'scope'] = {}
|
||||||
calendarId = sys.argv[2]
|
myarg = sys.argv[i].lower()
|
||||||
if not act_as:
|
body[u'scope'][u'type'] = myarg
|
||||||
calendarId = normalizeCalendarId(calendarId)
|
i += 1
|
||||||
act_as = calendarId
|
if myarg in [u'user', u'group']:
|
||||||
_, cal = buildCalendarDataGAPIObject(act_as)
|
body[u'scope'][u'value'] = normalizeEmailAddressOrUID(sys.argv[i], noUid=True)
|
||||||
body = {u'scope': {}}
|
i += 1
|
||||||
if role is not None:
|
elif myarg == u'domain':
|
||||||
body[u'role'] = role
|
if i < len(sys.argv) and sys.argv[i].lower().replace(u'_', u'') != u'sendnotifications':
|
||||||
else:
|
|
||||||
body[u'role'] = sys.argv[4].lower()
|
|
||||||
if body[u'role'] not in [u'freebusy', u'read', u'reader', u'editor', u'writer', u'owner', u'none']:
|
|
||||||
systemErrorExit(2, 'Role must be one of freebusy, reader, editor, writer, owner, none; got %s' % body[u'role'])
|
|
||||||
if body[u'role'] == u'freebusy':
|
|
||||||
body[u'role'] = u'freeBusyReader'
|
|
||||||
elif body[u'role'] in [u'read', u'reader']:
|
|
||||||
body[u'role'] = u'reader'
|
|
||||||
elif body[u'role'] == u'editor':
|
|
||||||
body[u'role'] = u'writer'
|
|
||||||
if scope is not None:
|
|
||||||
body[u'scope'][u'type'] = scope
|
|
||||||
else:
|
|
||||||
body[u'scope'][u'type'] = sys.argv[5].lower()
|
|
||||||
i = 6
|
|
||||||
if body[u'scope'][u'type'] not in [u'default', u'user', u'group', u'domain']:
|
|
||||||
body[u'scope'][u'type'] = u'user'
|
|
||||||
i = 5
|
|
||||||
try:
|
|
||||||
if entity is not None and body[u'scope'][u'type'] != u'default':
|
|
||||||
body[u'scope'][u'value'] = entity
|
|
||||||
else:
|
|
||||||
body[u'scope'][u'value'] = sys.argv[i].lower()
|
body[u'scope'][u'value'] = sys.argv[i].lower()
|
||||||
if (body[u'scope'][u'type'] in [u'user', u'group']) and body[u'scope'][u'value'].find(u'@') == -1:
|
i += 1
|
||||||
body[u'scope'][u'value'] = u'%s@%s' % (body[u'scope'][u'value'], GC_Values[GC_DOMAIN])
|
else:
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
if body[u'scope'][u'type'] == u'domain':
|
|
||||||
try:
|
|
||||||
body[u'scope'][u'value'] = sys.argv[6].lower()
|
|
||||||
except IndexError:
|
|
||||||
body[u'scope'][u'value'] = GC_Values[GC_DOMAIN]
|
body[u'scope'][u'value'] = GC_Values[GC_DOMAIN]
|
||||||
callGAPI(cal.acl(), u'insert', calendarId=calendarId, body=body)
|
elif myarg != u'default':
|
||||||
|
body[u'scope'][u'type'] = u'user'
|
||||||
|
body[u'scope'][u'value'] = normalizeEmailAddressOrUID(myarg, noUid=True)
|
||||||
|
return i
|
||||||
|
|
||||||
def doCalendarUpdateACL():
|
CALENDAR_ACL_ROLES_MAP = {
|
||||||
calendarId = sys.argv[2]
|
u'editor': u'writer',
|
||||||
role = sys.argv[4].lower()
|
u'freebusy': u'freeBusyReader',
|
||||||
scope = sys.argv[5].lower()
|
u'freebusyreader': u'freeBusyReader',
|
||||||
if len(sys.argv) > 6:
|
u'owner': u'owner',
|
||||||
entity = sys.argv[6].lower()
|
u'read': u'reader',
|
||||||
else:
|
u'reader': u'reader',
|
||||||
entity = None
|
u'writer': u'writer',
|
||||||
doCalendarAddACL(calendarId=calendarId, role=role, scope=scope, entity=entity)
|
u'none': u'none',
|
||||||
|
}
|
||||||
|
|
||||||
|
def doCalendarAddACL(function):
|
||||||
|
calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
|
||||||
|
if not cal:
|
||||||
|
return
|
||||||
|
myarg = sys.argv[4].lower().replace(u'_', u'')
|
||||||
|
if myarg not in CALENDAR_ACL_ROLES_MAP:
|
||||||
|
systemErrorExit(2, 'Role must be one of %s; got %s' % (u', '.join(sorted(CALENDAR_ACL_ROLES_MAP.keys())), myarg))
|
||||||
|
body = {u'role': CALENDAR_ACL_ROLES_MAP[myarg]}
|
||||||
|
i = _getCalendarACLScope(5, body)
|
||||||
|
sendNotifications = True
|
||||||
|
while i < len(sys.argv):
|
||||||
|
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||||
|
if myarg == u'sendnotifications':
|
||||||
|
sendNotifications = getBoolean(sys.argv[i+1], myarg)
|
||||||
|
i += 2
|
||||||
|
else:
|
||||||
|
systemErrorExit(2, '%s is not a valid argument for "gam calendar <email> %s"' % (sys.argv[i], function.lower()))
|
||||||
|
print u'Calendar: {0}, {1} ACL: {2}'.format(calendarId, function, formatACLRule(body))
|
||||||
|
callGAPI(cal.acl(), u'insert', calendarId=calendarId, body=body, sendNotifications=sendNotifications)
|
||||||
|
|
||||||
def doCalendarDelACL():
|
def doCalendarDelACL():
|
||||||
calendarId = sys.argv[2]
|
calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
|
||||||
entity = sys.argv[5].lower()
|
if not cal:
|
||||||
scope = u'user'
|
return
|
||||||
if entity == u'domain':
|
body = {u'role': u'none'}
|
||||||
scope = u'domain'
|
_getCalendarACLScope(5, body)
|
||||||
elif entity == u'default':
|
print u'Calendar: {0}, {1} ACL: {2}'.format(calendarId, u'Delete', formatACLScope(body))
|
||||||
scope = u'default'
|
callGAPI(cal.acl(), u'insert', calendarId=calendarId, body=body, sendNotifications=False)
|
||||||
entity = u''
|
|
||||||
doCalendarAddACL(calendarId=calendarId, role=u'none', scope=scope, entity=entity)
|
|
||||||
|
|
||||||
def doCalendarWipeData():
|
def doCalendarWipeData():
|
||||||
calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
|
calendarId, cal = buildCalendarDataGAPIObject(sys.argv[2])
|
||||||
@ -3475,16 +3503,12 @@ def doCalendarAddEvent():
|
|||||||
sendNotifications = True
|
sendNotifications = True
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg == u'attendee':
|
elif myarg == u'attendee':
|
||||||
try:
|
body.setdefault(u'attendees', [])
|
||||||
body[u'attendees'].append({u'email': sys.argv[i+1]})
|
body[u'attendees'].append({u'email': sys.argv[i+1]})
|
||||||
except KeyError:
|
|
||||||
body[u'attendees'] = [{u'email': sys.argv[i+1]},]
|
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'optionalattendee':
|
elif myarg == u'optionalattendee':
|
||||||
try:
|
body.setdefault(u'attendees', [])
|
||||||
body[u'attendees'].append({u'email': sys.argv[i+1], u'optional': True})
|
body[u'attendees'].append({u'email': sys.argv[i+1], u'optional': True})
|
||||||
except TypeError:
|
|
||||||
body[u'attendees'] = [{u'email': sys.argv[i+1], u'optional': True},]
|
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'anyonecanaddself':
|
elif myarg == u'anyonecanaddself':
|
||||||
body[u'anyoneCanAddSelf'] = True
|
body[u'anyoneCanAddSelf'] = True
|
||||||
@ -3540,17 +3564,13 @@ def doCalendarAddEvent():
|
|||||||
body[u'reminders'] = {u'useDefault': False}
|
body[u'reminders'] = {u'useDefault': False}
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg == u'reminder':
|
elif myarg == u'reminder':
|
||||||
try:
|
body.setdefault(u'reminders', {u'overrides': [], u'useDefault': False})
|
||||||
body[u'reminders'][u'overrides'].append({u'minutes': sys.argv[i+1], u'method': sys.argv[i+2]})
|
body[u'reminders'][u'overrides'].append({u'minutes': getInteger(sys.argv[i+1], myarg, minVal=0, maxVal=CALENDAR_REMINDER_MAX_MINUTES),
|
||||||
body[u'reminders'][u'useDefault'] = False
|
u'method': sys.argv[i+2]})
|
||||||
except KeyError:
|
|
||||||
body[u'reminders'] = {u'useDefault': False, u'overrides': [{u'minutes': sys.argv[i+1], u'method': sys.argv[i+2]},]}
|
|
||||||
i += 3
|
i += 3
|
||||||
elif myarg == u'recurrence':
|
elif myarg == u'recurrence':
|
||||||
try:
|
body.setdefault(u'recurrence', [])
|
||||||
body[u'recurrence'].append(sys.argv[i+1])
|
body[u'recurrence'].append(sys.argv[i+1])
|
||||||
except KeyError:
|
|
||||||
body[u'recurrence'] = [sys.argv[i+1],]
|
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'timezone':
|
elif myarg == u'timezone':
|
||||||
timeZone = sys.argv[i+1]
|
timeZone = sys.argv[i+1]
|
||||||
@ -3566,18 +3586,17 @@ def doCalendarAddEvent():
|
|||||||
body[u'extendedProperties'][u'shared'][sys.argv[i+1]] = sys.argv[i+2]
|
body[u'extendedProperties'][u'shared'][sys.argv[i+1]] = sys.argv[i+2]
|
||||||
i += 3
|
i += 3
|
||||||
elif myarg == u'colorindex':
|
elif myarg == u'colorindex':
|
||||||
body[u'colorId'] = str(sys.argv[i+1])
|
body[u'colorId'] = getInteger(sys.argv[i+1], myarg, CALENDAR_EVENT_MIN_COLOR_INDEX, CALENDAR_EVENT_MAX_COLOR_INDEX)
|
||||||
i += 2
|
i += 2
|
||||||
else:
|
else:
|
||||||
systemErrorExit(2, '%s is not a valid argument for "gam calendar <email> addevent"' % sys.argv[i])
|
systemErrorExit(2, '%s is not a valid argument for "gam calendar <email> addevent"' % sys.argv[i])
|
||||||
if not timeZone and u'recurrence' in body:
|
if (u'recurrence' in body) and ((u'start' in body) or (u'end' in body)):
|
||||||
timeZone = callGAPI(cal.calendars(), u'get', calendarId=calendarId, fields=u'timeZone')[u'timeZone']
|
if not timeZone:
|
||||||
if u'recurrence' in body:
|
timeZone = callGAPI(cal.calendars(), u'get', calendarId=calendarId, fields=u'timeZone')[u'timeZone']
|
||||||
for a_time in [u'start', u'end']:
|
if u'start' in body:
|
||||||
try:
|
body[u'start'][u'timeZone'] = timeZone
|
||||||
body[a_time][u'timeZone'] = timeZone
|
if u'end' in body:
|
||||||
except KeyError:
|
body[u'end'][u'timeZone'] = timeZone
|
||||||
pass
|
|
||||||
callGAPI(cal.events(), u'insert', calendarId=calendarId, sendNotifications=sendNotifications, body=body)
|
callGAPI(cal.events(), u'insert', calendarId=calendarId, sendNotifications=sendNotifications, body=body)
|
||||||
|
|
||||||
def doCalendarModifySettings():
|
def doCalendarModifySettings():
|
||||||
@ -3961,6 +3980,18 @@ def delDriveFileACL(users):
|
|||||||
permissionId=permissionId, supportsTeamDrives=True,
|
permissionId=permissionId, supportsTeamDrives=True,
|
||||||
useDomainAdminAccess=useDomainAdminAccess)
|
useDomainAdminAccess=useDomainAdminAccess)
|
||||||
|
|
||||||
|
DRIVEFILE_ACL_ROLES_MAP = {
|
||||||
|
u'commenter': u'commenter',
|
||||||
|
u'contentmanager': u'fileOrganizer',
|
||||||
|
u'editor': u'writer',
|
||||||
|
u'fileorganizer': u'fileOrganizer',
|
||||||
|
u'organizer': u'organizer',
|
||||||
|
u'owner': u'owner',
|
||||||
|
u'read': u'reader',
|
||||||
|
u'reader': u'reader',
|
||||||
|
u'writer': u'writer',
|
||||||
|
}
|
||||||
|
|
||||||
def addDriveFileACL(users):
|
def addDriveFileACL(users):
|
||||||
fileId = sys.argv[5]
|
fileId = sys.argv[5]
|
||||||
body = {u'type': sys.argv[6].lower()}
|
body = {u'type': sys.argv[6].lower()}
|
||||||
@ -3987,12 +4018,11 @@ def addDriveFileACL(users):
|
|||||||
body[u'allowFileDiscovery'] = True
|
body[u'allowFileDiscovery'] = True
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg == u'role':
|
elif myarg == u'role':
|
||||||
body[u'role'] = sys.argv[i+1]
|
role = sys.argv[i+1].lower()
|
||||||
if body[u'role'] not in [u'reader', u'commenter', u'writer', u'owner', u'organizer', u'editor']:
|
if role not in DRIVEFILE_ACL_ROLES_MAP:
|
||||||
systemErrorExit(2, 'role must be reader, commenter, writer, organizer, or owner; got %s' % body[u'role'])
|
systemErrorExit(2, 'role must be {0}; got {1}'.format(u', '.join(DRIVEFILE_ACL_ROLES_MAP), role))
|
||||||
if body[u'role'] == u'editor':
|
body[u'role'] = DRIVEFILE_ACL_ROLES_MAP[role]
|
||||||
body[u'role'] = u'writer'
|
if body[u'role'] == u'owner':
|
||||||
elif body[u'role'] == u'owner':
|
|
||||||
sendNotificationEmail = True
|
sendNotificationEmail = True
|
||||||
transferOwnership = True
|
transferOwnership = True
|
||||||
i += 2
|
i += 2
|
||||||
@ -4036,12 +4066,11 @@ def updateDriveFileACL(users):
|
|||||||
removeExpiration = True
|
removeExpiration = True
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg == u'role':
|
elif myarg == u'role':
|
||||||
body[u'role'] = sys.argv[i+1]
|
role = sys.argv[i+1].lower()
|
||||||
if body[u'role'] not in [u'reader', u'commenter', u'writer', u'owner', u'organizer', u'editor']:
|
if role not in DRIVEFILE_ACL_ROLES_MAP:
|
||||||
systemErrorExit(2, 'role must be reader, commenter, writer, organizer, or owner; got %s' % body[u'role'])
|
systemErrorExit(2, 'role must be {0}; got {1}'.format(u', '.join(DRIVEFILE_ACL_ROLES_MAP), role))
|
||||||
if body[u'role'] == u'editor':
|
body[u'role'] = DRIVEFILE_ACL_ROLES_MAP[role]
|
||||||
body[u'role'] = u'writer'
|
if body[u'role'] == u'owner':
|
||||||
elif body[u'role'] == u'owner':
|
|
||||||
transferOwnership = True
|
transferOwnership = True
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'asadmin':
|
elif myarg == u'asadmin':
|
||||||
@ -4560,7 +4589,7 @@ def downloadDriveFile(users):
|
|||||||
fileIdSelection[u'query'] = u"'me' in owners and title = '{0}'".format(sys.argv[i+1])
|
fileIdSelection[u'query'] = u"'me' in owners and title = '{0}'".format(sys.argv[i+1])
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'revision':
|
elif myarg == u'revision':
|
||||||
revisionId = sys.argv[i+1]
|
revisionId = getInteger(sys.argv[i+1], myarg, minVal=1)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'format':
|
elif myarg == u'format':
|
||||||
exportFormatChoices = sys.argv[i+1].replace(u',', u' ').lower().split()
|
exportFormatChoices = sys.argv[i+1].replace(u',', u' ').lower().split()
|
||||||
@ -4725,13 +4754,16 @@ def showDriveFileRevisions(users):
|
|||||||
|
|
||||||
def transferSecCals(users):
|
def transferSecCals(users):
|
||||||
target_user = sys.argv[5]
|
target_user = sys.argv[5]
|
||||||
remove_source_user = True
|
remove_source_user = sendNotifications = True
|
||||||
i = 6
|
i = 6
|
||||||
while i < len(sys.argv):
|
while i < len(sys.argv):
|
||||||
myarg = sys.argv[i].lower()
|
myarg = sys.argv[i].lower().replace(u'_', u'')
|
||||||
if myarg == u'keepuser':
|
if myarg == u'keepuser':
|
||||||
remove_source_user = False
|
remove_source_user = False
|
||||||
i += 1
|
i += 1
|
||||||
|
elif myarg == u'sendnotifications':
|
||||||
|
sendNotifications = getBoolean(sys.argv[i+1], myarg)
|
||||||
|
i += 2
|
||||||
else:
|
else:
|
||||||
systemErrorExit(2, '%s is not a valid argument for "gam <users> transfer seccals"' % sys.argv[i])
|
systemErrorExit(2, '%s is not a valid argument for "gam <users> transfer seccals"' % sys.argv[i])
|
||||||
if remove_source_user:
|
if remove_source_user:
|
||||||
@ -4742,13 +4774,16 @@ def transferSecCals(users):
|
|||||||
user, source_cal = buildCalendarGAPIObject(user)
|
user, source_cal = buildCalendarGAPIObject(user)
|
||||||
if not source_cal:
|
if not source_cal:
|
||||||
continue
|
continue
|
||||||
source_calendars = callGAPIpages(source_cal.calendarList(), u'list', u'items', soft_errors=True,
|
calendars = callGAPIpages(source_cal.calendarList(), u'list', u'items', soft_errors=True,
|
||||||
minAccessRole=u'owner', showHidden=True, fields=u'items(id),nextPageToken')
|
minAccessRole=u'owner', showHidden=True, fields=u'items(id),nextPageToken')
|
||||||
for source_cal in source_calendars:
|
for calendar in calendars:
|
||||||
if source_cal[u'id'].find(u'@group.calendar.google.com') != -1:
|
calendarId = calendar[u'id']
|
||||||
doCalendarAddACL(calendarId=source_cal[u'id'], act_as=user, role=u'owner', scope=u'user', entity=target_user)
|
if calendarId.find(u'@group.calendar.google.com') != -1:
|
||||||
|
callGAPI(source_cal.acl(), u'insert', calendarId=calendarId,
|
||||||
|
body={u'role': u'owner', u'scope': {u'type': u'user', u'value': target_user}}, sendNotifications=sendNotifications)
|
||||||
if remove_source_user:
|
if remove_source_user:
|
||||||
doCalendarAddACL(calendarId=source_cal[u'id'], act_as=target_user, role=u'none', scope=u'user', entity=user)
|
callGAPI(target_cal.acl(), u'insert', calendarId=calendarId,
|
||||||
|
body={u'role': u'none', u'scope': {u'type': u'user', u'value': user}}, sendNotifications=sendNotifications)
|
||||||
|
|
||||||
def transferDriveFiles(users):
|
def transferDriveFiles(users):
|
||||||
target_user = sys.argv[5]
|
target_user = sys.argv[5]
|
||||||
@ -5467,7 +5502,7 @@ def doProcessMessagesOrThreads(users, function, unit=u'messages'):
|
|||||||
doIt = True
|
doIt = True
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg in [u'maxtodelete', u'maxtotrash', u'maxtomodify', u'maxtountrash']:
|
elif myarg in [u'maxtodelete', u'maxtotrash', u'maxtomodify', u'maxtountrash']:
|
||||||
maxToProcess = int(sys.argv[i+1])
|
maxToProcess = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif (function == u'modify') and (myarg == u'addlabel'):
|
elif (function == u'modify') and (myarg == u'addlabel'):
|
||||||
body.setdefault(u'addLabelIds', [])
|
body.setdefault(u'addLabelIds', [])
|
||||||
@ -6423,7 +6458,8 @@ def doCreateOrUpdateUserSchema(updateCmd):
|
|||||||
a_field[u'readAccessType'] = u'ADMINS_AND_SELF'
|
a_field[u'readAccessType'] = u'ADMINS_AND_SELF'
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg == u'range':
|
elif myarg == u'range':
|
||||||
a_field[u'numericIndexingSpec'] = {u'minValue': sys.argv[i+1], u'maxValue': sys.argv[i+2]}
|
a_field[u'numericIndexingSpec'] = {u'minValue': getInteger(sys.argv[i+1], myarg),
|
||||||
|
u'maxValue': getInteger(sys.argv[i+2], myarg)}
|
||||||
i += 3
|
i += 3
|
||||||
elif myarg == u'endfield':
|
elif myarg == u'endfield':
|
||||||
body[u'fields'].append(a_field)
|
body[u'fields'].append(a_field)
|
||||||
@ -6887,7 +6923,7 @@ def getUserAttributes(i, cd, updateCmd):
|
|||||||
while True:
|
while True:
|
||||||
myopt = sys.argv[i].lower()
|
myopt = sys.argv[i].lower()
|
||||||
if myopt == u'expires':
|
if myopt == u'expires':
|
||||||
ssh[u'expirationTimeUsec'] = sys.argv[i+1]
|
ssh[u'expirationTimeUsec'] = getInteger(sys.argv[i+1], myopt, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myopt == u'key':
|
elif myopt == u'key':
|
||||||
ssh[u'key'] = sys.argv[i+1]
|
ssh[u'key'] = sys.argv[i+1]
|
||||||
@ -6910,10 +6946,10 @@ def getUserAttributes(i, cd, updateCmd):
|
|||||||
posix[u'gecos'] = sys.argv[i+1]
|
posix[u'gecos'] = sys.argv[i+1]
|
||||||
i += 2
|
i += 2
|
||||||
elif myopt == u'gid':
|
elif myopt == u'gid':
|
||||||
posix[u'gid'] = int(sys.argv[i+1])
|
posix[u'gid'] = getInteger(sys.argv[i+1], myopt, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myopt == u'uid':
|
elif myopt == u'uid':
|
||||||
posix[u'uid'] = int(sys.argv[i+1])
|
posix[u'uid'] = getInteger(sys.argv[i+1], myopt, minVal=1000)
|
||||||
i += 2
|
i += 2
|
||||||
elif myopt in [u'home', u'homedirectory']:
|
elif myopt in [u'home', u'homedirectory']:
|
||||||
posix[u'homeDirectory'] = sys.argv[i+1]
|
posix[u'homeDirectory'] = sys.argv[i+1]
|
||||||
@ -8037,7 +8073,7 @@ def doCreateGroup():
|
|||||||
|
|
||||||
def doCreateAlias():
|
def doCreateAlias():
|
||||||
cd = buildGAPIObject(u'directory')
|
cd = buildGAPIObject(u'directory')
|
||||||
body = {u'alias': normalizeEmailAddressOrUID(sys.argv[3], noUid=True)}
|
body = {u'alias': normalizeEmailAddressOrUID(sys.argv[3], noUid=True, noLower=True)}
|
||||||
target_type = sys.argv[4].lower()
|
target_type = sys.argv[4].lower()
|
||||||
if target_type not in [u'user', u'group', u'target']:
|
if target_type not in [u'user', u'group', u'target']:
|
||||||
systemErrorExit(2, 'type of target must be user or group; got %s' % target_type)
|
systemErrorExit(2, 'type of target must be user or group; got %s' % target_type)
|
||||||
@ -8268,7 +8304,7 @@ def _getResourceCalendarAttributes(cd, args, body={}):
|
|||||||
body[u'buildingId'] = _getBuildingByNameOrId(cd, args[i+1], minLen=0)
|
body[u'buildingId'] = _getBuildingByNameOrId(cd, args[i+1], minLen=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg in [u'capacity']:
|
elif myarg in [u'capacity']:
|
||||||
body[u'capacity'] = int(args[i+1])
|
body[u'capacity'] = getInteger(args[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg in [u'feature', u'features']:
|
elif myarg in [u'feature', u'features']:
|
||||||
features = args[i+1].split(u',')
|
features = args[i+1].split(u',')
|
||||||
@ -8631,7 +8667,7 @@ def doUpdateGroup():
|
|||||||
|
|
||||||
def doUpdateAlias():
|
def doUpdateAlias():
|
||||||
cd = buildGAPIObject(u'directory')
|
cd = buildGAPIObject(u'directory')
|
||||||
alias = normalizeEmailAddressOrUID(sys.argv[3], noUid=True)
|
alias = normalizeEmailAddressOrUID(sys.argv[3], noUid=True, noLower=True)
|
||||||
target_type = sys.argv[4].lower()
|
target_type = sys.argv[4].lower()
|
||||||
if target_type not in [u'user', u'group', u'target']:
|
if target_type not in [u'user', u'group', u'target']:
|
||||||
systemErrorExit(2, 'target type must be one of user, group, target; got %s' % target_type)
|
systemErrorExit(2, 'target type must be one of user, group, target; got %s' % target_type)
|
||||||
@ -8895,9 +8931,9 @@ def doUpdateResoldSubscription():
|
|||||||
i += 2
|
i += 2
|
||||||
elif myarg in [u'seats']:
|
elif myarg in [u'seats']:
|
||||||
function = u'changeSeats'
|
function = u'changeSeats'
|
||||||
kwargs[u'body'] = {u'numberOfSeats': sys.argv[i+1]}
|
kwargs[u'body'] = {u'numberOfSeats': getInteger(sys.argv[i+1], u'numberOfSeats', minVal=0)}
|
||||||
if len(sys.argv) > i + 2 and sys.argv[i+2].isdigit():
|
if len(sys.argv) > i + 2 and sys.argv[i+2].isdigit():
|
||||||
kwargs[u'body'][u'maximumNumberOfSeats'] = sys.argv[i+2]
|
kwargs[u'body'][u'maximumNumberOfSeats'] = getInteger(sys.argv[i+2], u'maximumNumberOfSeats', minVal=0)
|
||||||
i += 3
|
i += 3
|
||||||
else:
|
else:
|
||||||
i += 2
|
i += 2
|
||||||
@ -8908,9 +8944,9 @@ def doUpdateResoldSubscription():
|
|||||||
while i < len(sys.argv):
|
while i < len(sys.argv):
|
||||||
planarg = sys.argv[i].lower()
|
planarg = sys.argv[i].lower()
|
||||||
if planarg == u'seats':
|
if planarg == u'seats':
|
||||||
kwargs[u'body'][u'seats'] = {u'numberOfSeats': sys.argv[i+1]}
|
kwargs[u'body'][u'seats'] = {u'numberOfSeats': getInteger(sys.argv[i+1], u'numberOfSeats', minVal=0)}
|
||||||
if len(sys.argv) > i + 2 and sys.argv[i+2].isdigit():
|
if len(sys.argv) > i + 2 and sys.argv[i+2].isdigit():
|
||||||
kwargs[u'body'][u'seats'][u'maximumNumberOfSeats'] = sys.argv[i+2]
|
kwargs[u'body'][u'seats'][u'maximumNumberOfSeats'] = getInteger(sys.argv[i+2], u'maximumNumberOfSeats', minVal=0)
|
||||||
i += 3
|
i += 3
|
||||||
else:
|
else:
|
||||||
i += 2
|
i += 2
|
||||||
@ -8959,9 +8995,9 @@ def _getResoldSubscriptionAttr(arg, customerId):
|
|||||||
elif myarg in [u'purchaseorderid', u'po']:
|
elif myarg in [u'purchaseorderid', u'po']:
|
||||||
body[u'purchaseOrderId'] = arg[i+1]
|
body[u'purchaseOrderId'] = arg[i+1]
|
||||||
elif myarg in [u'seats']:
|
elif myarg in [u'seats']:
|
||||||
body[u'seats'][u'numberOfSeats'] = arg[i+1]
|
body[u'seats'][u'numberOfSeats'] = getInteger(sys.argv[i+1], u'numberOfSeats', minVal=0)
|
||||||
if len(arg) > i + 2 and arg[i+2].isdigit():
|
if len(arg) > i + 2 and arg[i+2].isdigit():
|
||||||
body[u'seats'][u'maximumNumberOfSeats'] = arg[i+2]
|
body[u'seats'][u'maximumNumberOfSeats'] = getInteger(sys.argv[i+2], u'maximumNumberOfSeats', minVal=0)
|
||||||
i += 1
|
i += 1
|
||||||
elif myarg in [u'sku', u'skuid']:
|
elif myarg in [u'sku', u'skuid']:
|
||||||
_, body[u'skuId'] = getProductAndSKU(arg[i+1])
|
_, body[u'skuId'] = getProductAndSKU(arg[i+1])
|
||||||
@ -9446,7 +9482,7 @@ def doGetCrosInfo():
|
|||||||
endDate = _getFilterDate(sys.argv[i+1])
|
endDate = _getFilterDate(sys.argv[i+1])
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'listlimit':
|
elif myarg == u'listlimit':
|
||||||
listLimit = int(sys.argv[i+1])
|
listLimit = getInteger(sys.argv[i+1], myarg, minVal=-1)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'allfields':
|
elif myarg == u'allfields':
|
||||||
projection = u'FULL'
|
projection = u'FULL'
|
||||||
@ -10178,7 +10214,7 @@ def doDeleteAlias(alias_email=None):
|
|||||||
elif alias_email.lower() == u'group':
|
elif alias_email.lower() == u'group':
|
||||||
is_group = True
|
is_group = True
|
||||||
alias_email = sys.argv[4]
|
alias_email = sys.argv[4]
|
||||||
alias_email = normalizeEmailAddressOrUID(alias_email, noUid=True)
|
alias_email = normalizeEmailAddressOrUID(alias_email, noUid=True, noLower=True)
|
||||||
print u"Deleting alias %s" % alias_email
|
print u"Deleting alias %s" % alias_email
|
||||||
if is_user or (not is_user and not is_group):
|
if is_user or (not is_user and not is_group):
|
||||||
try:
|
try:
|
||||||
@ -10639,7 +10675,7 @@ def doPrintGroups():
|
|||||||
usemember = None
|
usemember = None
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'maxresults':
|
elif myarg == u'maxresults':
|
||||||
maxResults = int(sys.argv[i+1])
|
maxResults = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'delimiter':
|
elif myarg == u'delimiter':
|
||||||
aliasDelimiter = memberDelimiter = sys.argv[i+1]
|
aliasDelimiter = memberDelimiter = sys.argv[i+1]
|
||||||
@ -11182,10 +11218,10 @@ def doPrintMobileDevices():
|
|||||||
delimiter = sys.argv[i+1]
|
delimiter = sys.argv[i+1]
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'listlimit':
|
elif myarg == u'listlimit':
|
||||||
listLimit = int(sys.argv[i+1])
|
listLimit = getInteger(sys.argv[i+1], myarg, minVal=-1)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'appslimit':
|
elif myarg == u'appslimit':
|
||||||
appsLimit = int(sys.argv[i+1])
|
appsLimit = getInteger(sys.argv[i+1], myarg, minVal=-1)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'fields':
|
elif myarg == u'fields':
|
||||||
fields = u'nextPageToken,mobiledevices(%s)' % sys.argv[i+1]
|
fields = u'nextPageToken,mobiledevices(%s)' % sys.argv[i+1]
|
||||||
@ -11301,7 +11337,7 @@ def doPrintCrosActivity():
|
|||||||
endDate = _getFilterDate(sys.argv[i+1])
|
endDate = _getFilterDate(sys.argv[i+1])
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'listlimit':
|
elif myarg == u'listlimit':
|
||||||
listLimit = int(sys.argv[i+1])
|
listLimit = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'delimiter':
|
elif myarg == u'delimiter':
|
||||||
delimiter = sys.argv[i+1]
|
delimiter = sys.argv[i+1]
|
||||||
@ -11424,7 +11460,7 @@ def doPrintCrosDevices():
|
|||||||
endDate = _getFilterDate(sys.argv[i+1])
|
endDate = _getFilterDate(sys.argv[i+1])
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'listlimit':
|
elif myarg == u'listlimit':
|
||||||
listLimit = int(sys.argv[i+1])
|
listLimit = getInteger(sys.argv[i+1], myarg, minVal=0)
|
||||||
i += 2
|
i += 2
|
||||||
elif myarg == u'orderby':
|
elif myarg == u'orderby':
|
||||||
orderBy = sys.argv[i+1].lower().replace(u'_', u'')
|
orderBy = sys.argv[i+1].lower().replace(u'_', u'')
|
||||||
@ -12810,11 +12846,11 @@ def ProcessGAMCommand(args):
|
|||||||
if argument == u'showacl':
|
if argument == u'showacl':
|
||||||
doCalendarShowACL()
|
doCalendarShowACL()
|
||||||
elif argument == u'add':
|
elif argument == u'add':
|
||||||
doCalendarAddACL()
|
doCalendarAddACL(u'Add')
|
||||||
elif argument in [u'del', u'delete']:
|
elif argument in [u'del', u'delete']:
|
||||||
doCalendarDelACL()
|
doCalendarDelACL()
|
||||||
elif argument == u'update':
|
elif argument == u'update':
|
||||||
doCalendarUpdateACL()
|
doCalendarAddACL(u'Update')
|
||||||
elif argument == u'wipe':
|
elif argument == u'wipe':
|
||||||
doCalendarWipeData()
|
doCalendarWipeData()
|
||||||
elif argument == u'addevent':
|
elif argument == u'addevent':
|
||||||
|
Reference in New Issue
Block a user