diff --git a/src/gam.py b/src/gam.py index 163c181a..c37b22a1 100755 --- a/src/gam.py +++ b/src/gam.py @@ -3622,6 +3622,8 @@ def doCancelPrintJob(): print('Print Job %s cancelled' % job) def checkCloudPrintResult(result): + if isinstance(result, bytes): + result = result.decode(UTF8) if isinstance(result, str): try: result = json.loads(result) @@ -4198,7 +4200,7 @@ def showDriveFileACL(users): if not drive: continue feed = callGAPIpages(drive.permissions(), 'list', 'permissions', - fileId=fileId, fields='*', supportsTeamDrives=True, + fileId=fileId, fields='*', supportsAllDrives=True, useDomainAdminAccess=useDomainAdminAccess) for permission in feed: printPermission(permission) @@ -4239,7 +4241,7 @@ def delDriveFileACL(users): continue print('Removing permission for %s from %s' % (permissionId, fileId)) callGAPI(drive.permissions(), 'delete', fileId=fileId, - permissionId=permissionId, supportsTeamDrives=True, + permissionId=permissionId, supportsAllDrives=True, useDomainAdminAccess=useDomainAdminAccess) DRIVEFILE_ACL_ROLES_MAP = { @@ -4309,7 +4311,7 @@ def addDriveFileACL(users): continue result = callGAPI(drive.permissions(), 'create', fields='*', fileId=fileId, sendNotificationEmail=sendNotificationEmail, - emailMessage=emailMessage, body=body, supportsTeamDrives=True, + emailMessage=emailMessage, body=body, supportsAllDrives=True, transferOwnership=transferOwnership, useDomainAdminAccess=useDomainAdminAccess) printPermission(result) @@ -4348,7 +4350,7 @@ def updateDriveFileACL(users): result = callGAPI(drive.permissions(), 'update', fields='*', fileId=fileId, permissionId=permissionId, removeExpiration=removeExpiration, transferOwnership=transferOwnership, body=body, - supportsTeamDrives=True, useDomainAdminAccess=useDomainAdminAccess) + supportsAllDrives=True, useDomainAdminAccess=useDomainAdminAccess) printPermission(result) def _stripMeInOwners(query): @@ -4549,7 +4551,7 @@ def deleteDriveFile(users): for fileId in file_ids: i += 1 print('%s %s for %s (%s/%s)' % (action, fileId, user, i, len(file_ids))) - callGAPI(drive.files(), function, fileId=fileId, supportsTeamDrives=True) + callGAPI(drive.files(), function, fileId=fileId, supportsAllDrives=True) def printDriveFolderContents(feed, folderId, indent): for f_file in feed: @@ -4766,14 +4768,14 @@ def doUpdateDriveFile(users): ocr=parameters[DFA_OCR], ocrLanguage=parameters[DFA_OCRLANGUAGE], media_body=media_body, body=body, fields='id', - supportsTeamDrives=True) + supportsAllDrives=True) print('Successfully updated %s drive file with content from %s' % (result['id'], parameters[DFA_LOCALFILENAME])) else: result = callGAPI(drive.files(), 'patch', fileId=fileId, convert=parameters[DFA_CONVERT], ocr=parameters[DFA_OCR], ocrLanguage=parameters[DFA_OCRLANGUAGE], body=body, - fields='id', supportsTeamDrives=True) + fields='id', supportsAllDrives=True) print('Successfully updated drive file/folder ID %s' % (result['id'])) else: for fileId in fileIdSelection['fileIds']: @@ -4781,7 +4783,7 @@ def doUpdateDriveFile(users): fileId=fileId, convert=parameters[DFA_CONVERT], ocr=parameters[DFA_OCR], ocrLanguage=parameters[DFA_OCRLANGUAGE], - body=body, fields='id', supportsTeamDrives=True) + body=body, fields='id', supportsAllDrives=True) print('Successfully copied %s to %s' % (fileId, result['id'])) def createDriveFile(users): @@ -4819,7 +4821,7 @@ def createDriveFile(users): convert=parameters[DFA_CONVERT], ocr=parameters[DFA_OCR], ocrLanguage=parameters[DFA_OCRLANGUAGE], media_body=media_body, body=body, fields='id,title,mimeType', - supportsTeamDrives=True) + supportsAllDrives=True) titleInfo = '{0}({1})'.format(result['title'], result['id']) if csv_output: csv_rows.append({'User': user, 'title': result['title'], 'id': result['id']}) @@ -4916,7 +4918,7 @@ def downloadDriveFile(users): for fileId in fileIdSelection['fileIds']: fileExtension = None result = callGAPI(drive.files(), 'get', - fileId=fileId, fields='fileExtension,fileSize,mimeType,title', supportsTeamDrives=True) + fileId=fileId, fields='fileExtension,fileSize,mimeType,title', supportsAllDrives=True) fileExtension = result.get('fileExtension') mimeType = result['mimeType'] if mimeType == MIMETYPE_GA_FOLDER: @@ -5050,7 +5052,7 @@ def showDriveFileInfo(users): user, drive = buildDriveGAPIObject(user) if not drive: continue - feed = callGAPI(drive.files(), 'get', fileId=fileId, fields=fields, supportsTeamDrives=True) + feed = callGAPI(drive.files(), 'get', fileId=fileId, fields=fields, supportsAllDrives=True) if feed: print_json(None, feed) @@ -5241,7 +5243,7 @@ def doLanguage(users): user, gmail = buildGmailGAPIObject(user) if not gmail: continue - print('Setting language to %s for %s' % (displayLanguage, user)) + print('Setting language to %s for %s (%s/%s)' % (displayLanguage, user, i, count)) result = callGAPI(gmail.users().settings(), 'updateLanguage', userId='me', body={'displayLanguage': displayLanguage}) print('Language is set to %s for %s' % (result['displayLanguage'], user)) @@ -5257,7 +5259,7 @@ def getLanguage(users): soft_errors=True, userId='me') if result: - print('User: {0}, Language: {1}'.format(user, result['displayLanguage'])) + print('User: {0}, Language: {1} ({2}/{3})'.format(user, result['displayLanguage']), i, count) def getImap(users): i = 0 @@ -5741,7 +5743,8 @@ def addSmime(users): myarg = sys.argv[i].lower() if myarg == 'file': smimefile = sys.argv[i+1] - body['pkcs12'] = base64.urlsafe_b64encode(readFile(smimefile, mode='rb')) + smimeData = readFile(smimefile, mode='rb') + body['pkcs12'] = base64.urlsafe_b64encode(smimeData).decode(UTF8) i += 2 elif myarg == 'password': body['encryptedKeyPassword'] = sys.argv[i+1] @@ -7829,7 +7832,7 @@ def doGetTeamDriveInfo(users): if not drive: print('Failed to access Drive as %s' % user) continue - result = callGAPI(drive.teamdrives(), 'get', teamDriveId=teamDriveId, + result = callGAPI(drive.drives(), 'get', driveId=teamDriveId, useDomainAdminAccess=useDomainAdminAccess, fields='*') print_json(None, result) @@ -7849,7 +7852,7 @@ def doCreateTeamDrive(users): print('Failed to access Drive as %s' % user) continue requestId = str(uuid.uuid4()) - result = callGAPI(drive.teamdrives(), 'create', requestId=requestId, body=body, fields='id') + result = callGAPI(drive.drives(), 'create', requestId=requestId, body=body, fields='id') print('Created Team Drive %s with id %s' % (body['name'], result['id'])) TEAMDRIVE_RESTRICTIONS_MAP = { @@ -7898,8 +7901,8 @@ def doUpdateTeamDrive(users): user, drive = buildDrive3GAPIObject(user) if not drive: continue - result = callGAPI(drive.teamdrives(), 'update', - useDomainAdminAccess=useDomainAdminAccess, body=body, teamDriveId=teamDriveId, fields='id', soft_errors=True) + result = callGAPI(drive.drives(), 'update', + useDomainAdminAccess=useDomainAdminAccess, body=body, driveId=teamDriveId, fields='id', soft_errors=True) if not result: continue print('Updated Team Drive %s' % (teamDriveId)) @@ -7928,7 +7931,7 @@ def printShowTeamDrives(users, csvFormat): user, drive = buildDrive3GAPIObject(user) if not drive: continue - results = callGAPIpages(drive.teamdrives(), 'list', 'teamDrives', + results = callGAPIpages(drive.drives(), 'list', 'drives', useDomainAdminAccess=useDomainAdminAccess, fields='*', q=q, soft_errors=True) if not results: @@ -7956,7 +7959,7 @@ def doDeleteTeamDrive(users): if not drive: continue print('Deleting Team Drive %s' % (teamDriveId)) - callGAPI(drive.teamdrives(), 'delete', teamDriveId=teamDriveId, soft_errors=True) + callGAPI(drive.drives(), 'delete', driveId=teamDriveId, soft_errors=True) def validateCollaborators(collaboratorList, cd): collaborators = [] @@ -10105,7 +10108,7 @@ def doGetCrosInfo(): print(' date: {0}'.format(activeTimeRange['date'])) print(' activeTime: {0}'.format(str(activeTimeRange['activeTime']))) print(' duration: {0}'.format(utils.formatMilliSeconds(activeTimeRange['activeTime']))) - print(' minutes: {0}'.format(activeTimeRange['activeTime']/60000)) + print(' minutes: {0}'.format(activeTimeRange['activeTime']//60000)) recentUsers = cros.get('recentUsers', []) lenRU = len(recentUsers) if lenRU: @@ -10172,6 +10175,8 @@ def doGetMobileInfo(): cd = buildGAPIObject('directory') resourceId = sys.argv[3] info = callGAPI(cd.mobiledevices(), 'get', customerId=GC_Values[GC_CUSTOMER_ID], resourceId=resourceId) + if 'deviceId' in info: + info['deviceId'] = info['deviceId'].encode('unicode-escape').decode(UTF8) print_json(None, info) def print_json(object_name, object_value, spacing=''): @@ -11866,6 +11871,8 @@ def doPrintMobileDevices(): appDetails.append('') applications.append('-'.join(appDetails)) row[attrib] = delimiter.join(applications) + elif attrib == 'deviceId': + row[attrib] = mobile[attrib].encode('unicode-escape').decode(UTF8) else: if attrib not in titles: titles.append(attrib) @@ -11957,7 +11964,7 @@ def doPrintCrosActivity(): new_row = row.copy() new_row['activeTimeRanges.date'] = activeTimeRange['date'] new_row['activeTimeRanges.duration'] = utils.formatMilliSeconds(activeTimeRange['activeTime']) - new_row['activeTimeRanges.minutes'] = activeTimeRange['activeTime']/60000 + new_row['activeTimeRanges.minutes'] = activeTimeRange['activeTime']//60000 csvRows.append(new_row) if selectRecentUsers: recentUsers = cros.get('recentUsers', []) @@ -12147,7 +12154,7 @@ def doPrintCrosDevices(): new_row['activeTimeRanges.date'] = activeTimeRanges[i]['date'] new_row['activeTimeRanges.activeTime'] = str(activeTimeRanges[i]['activeTime']) new_row['activeTimeRanges.duration'] = utils.formatMilliSeconds(activeTimeRanges[i]['activeTime']) - new_row['activeTimeRanges.minutes'] = activeTimeRanges[i]['activeTime']/60000 + new_row['activeTimeRanges.minutes'] = activeTimeRanges[i]['activeTime']//60000 if i < lenRU: new_row['recentUsers.email'] = recentUsers[i].get('email', ['Unknown', 'UnmanagedUser'][recentUsers[i]['type'] == 'USER_TYPE_UNMANAGED']) new_row['recentUsers.type'] = recentUsers[i]['type'] @@ -14230,6 +14237,6 @@ def ProcessGAMCommand(args): if __name__ == "__main__": if sys.platform.startswith('win'): freeze_support() - if sys.version_info[0] < 3 or sys.version_info[1] < 7: - systemErrorExit(5, 'GAM requires Python 3.7 or newer. You are running %s.%s.%s. Please upgrade your Python version or use one of the binary GAM downloads.' % sys.version_info[:3]) + if sys.version_info[0] < 3 or sys.version_info[1] < 5: + systemErrorExit(5, 'GAM requires Python 3.5 or newer. You are running %s.%s.%s. Please upgrade your Python version or use one of the binary GAM downloads.' % sys.version_info[:3]) sys.exit(ProcessGAMCommand(sys.argv)) diff --git a/src/travis/windows-x86-before-install.sh b/src/travis/windows-x86-before-install.sh index 49d8b5c4..37f68a7c 100755 --- a/src/travis/windows-x86-before-install.sh +++ b/src/travis/windows-x86-before-install.sh @@ -1,9 +1,9 @@ -powershell Install-WindowsFeature Net-Framework-Core +until powershell Install-WindowsFeature Net-Framework-Core; do echo "trying again..."; done cinst -y --forcex86 python3 cinst -y --forcex86 openssl.light cp -v /c/Program\ Files/OpenSSL/*.dll /c/Python37/DLLs export PATH=$PATH:/c/Python37/scripts -cinst -y wixtoolset +until cinst -y wixtoolset; do echo "trying again..."; done pip install --upgrade pip pip freeze > upgrades.txt pip install --upgrade -r upgrades.txt diff --git a/src/travis/windows-x86_64-before-install.sh b/src/travis/windows-x86_64-before-install.sh index 74fa8824..075ef589 100755 --- a/src/travis/windows-x86_64-before-install.sh +++ b/src/travis/windows-x86_64-before-install.sh @@ -1,9 +1,9 @@ -powershell Install-WindowsFeature Net-Framework-Core +until powershell Install-WindowsFeature Net-Framework-Core; do echo "trying again..."; done cinst -y python3 cinst -y openssl.light cp -v /c/Program\ Files/OpenSSL/bin/*.dll /c/Python37/DLLs export PATH=$PATH:/c/Python37/scripts -cinst -y wixtoolset +until cinst -y wixtoolset; do echo "trying again..."; done pip install --upgrade pip pip freeze > upgrades.txt pip install --upgrade -r upgrades.txt