Clean up, small fixes (#299)

* Clean up, small fixes

* Update as per Jay's suggestions

* Add Jays'changes

# Conflicts:
#	src/gam.py
This commit is contained in:
Ross Scroggs
2016-10-23 17:33:10 -07:00
committed by Jay Lee
parent facd10d882
commit 1c92ad3d6d

View File

@ -20,21 +20,37 @@ u"""GAM is a command line tool which allows Administrators to control their Goog
With GAM you can programatically create users, turn on/off services for users like POP and Forwarding and much more. With GAM you can programatically create users, turn on/off services for users like POP and Forwarding and much more.
For more information, see http://git.io/gam For more information, see http://git.io/gam
""" """
__author__ = u'Jay Lee <jay0lee@gmail.com>' __author__ = u'Jay Lee <jay0lee@gmail.com>'
__version__ = u'3.72' __version__ = u'3.72'
__license__ = u'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' __license__ = u'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
import sys, os, time, datetime, random, socket, csv, platform, re, base64, string, codecs, StringIO, subprocess, collections, mimetypes import sys
import os
import string
import time
import base64
import codecs
import collections
import csv
import datetime
from htmlentitydefs import name2codepoint
from HTMLParser import HTMLParser
import json import json
import httplib2 import mimetypes
import platform
import random
import re
import socket
import StringIO
import subprocess
import googleapiclient import googleapiclient
import googleapiclient.discovery import googleapiclient.discovery
import googleapiclient.errors import googleapiclient.errors
import googleapiclient.http import googleapiclient.http
import httplib2
import oauth2client.client import oauth2client.client
import oauth2client.service_account import oauth2client.service_account
import oauth2client.file import oauth2client.file
@ -71,6 +87,7 @@ GAM_INFO = u'GAM {0} - {1} / {2} / Python {3}.{4}.{5} {6} / {7} {8} /'.format(__
sys.version_info[0], sys.version_info[1], sys.version_info[2], sys.version_info[0], sys.version_info[1], sys.version_info[2],
sys.version_info[3], sys.version_info[3],
platform.platform(), platform.machine()) platform.platform(), platform.machine())
GAM_RELEASES = u'https://github.com/jay0lee/GAM/releases'
GAM_WIKI = u'https://github.com/jay0lee/GAM/wiki' GAM_WIKI = u'https://github.com/jay0lee/GAM/wiki'
GAM_WIKI_CREATE_CLIENT_SECRETS = GAM_WIKI+u'/CreatingClientSecretsFile' GAM_WIKI_CREATE_CLIENT_SECRETS = GAM_WIKI+u'/CreatingClientSecretsFile'
GAM_ALL_RELEASES = u'https://api.github.com/repos/jay0lee/GAM/releases' GAM_ALL_RELEASES = u'https://api.github.com/repos/jay0lee/GAM/releases'
@ -355,9 +372,6 @@ def convertUTF8(data):
return type(data)(map(convertUTF8, data)) return type(data)(map(convertUTF8, data))
return data return data
from HTMLParser import HTMLParser
from htmlentitydefs import name2codepoint
class _DeHTMLParser(HTMLParser): class _DeHTMLParser(HTMLParser):
def __init__(self): def __init__(self):
HTMLParser.__init__(self) HTMLParser.__init__(self)
@ -749,13 +763,15 @@ def SetGlobalVariables():
return True return True
def doGAMCheckForUpdates(forceCheck=False): def doGAMCheckForUpdates(forceCheck=False):
import urllib2, calendar import urllib2
import calendar
current_version = __version__ current_version = __version__
now_time = calendar.timegm(time.gmtime()) now_time = calendar.timegm(time.gmtime())
if forceCheck: if forceCheck:
check_url = GAM_ALL_RELEASES # includes pre-releases check_url = GAM_ALL_RELEASES # includes pre-releases
else: else:
last_check_time_str = readFile(GM_Globals[GM_LAST_UPDATE_CHECK_TXT], continueOnError=True, displayError=forceCheck) last_check_time_str = readFile(GM_Globals[GM_LAST_UPDATE_CHECK_TXT], continueOnError=True, displayError=False)
last_check_time = int(last_check_time_str) if last_check_time_str and last_check_time_str.isdigit() else 0 last_check_time = int(last_check_time_str) if last_check_time_str and last_check_time_str.isdigit() else 0
if last_check_time > now_time-604800: if last_check_time > now_time-604800:
return return
@ -768,8 +784,8 @@ def doGAMCheckForUpdates(forceCheck=False):
release_data = json.loads(c.read()) release_data = json.loads(c.read())
except ValueError: except ValueError:
return return
if type(release_data) is list: if isinstance(release_data, list):
release_data = release_data[0] # only care about latest release release_data = release_data[0] # only care about latest release
latest_version = release_data[u'tag_name'] latest_version = release_data[u'tag_name']
if latest_version[0].lower() == u'v': if latest_version[0].lower() == u'v':
latest_version = latest_version[1:] latest_version = latest_version[1:]
@ -898,7 +914,7 @@ def checkGAPIError(e, soft_errors=False, silent_errors=False, retryOnHttpError=F
elif u'Mail service not enabled' in message: elif u'Mail service not enabled' in message:
reason = GAPI_SERVICE_NOT_AVAILABLE reason = GAPI_SERVICE_NOT_AVAILABLE
except KeyError: except KeyError:
reason = http_status reason = u'{0}'.format(http_status)
return (http_status, reason, message) return (http_status, reason, message)
class GAPI_serviceNotAvailable(Exception): class GAPI_serviceNotAvailable(Exception):
@ -907,9 +923,9 @@ class GAPI_serviceNotAvailable(Exception):
def callGAPI(service, function, def callGAPI(service, function,
silent_errors=False, soft_errors=False, throw_reasons=None, retry_reasons=None, silent_errors=False, soft_errors=False, throw_reasons=None, retry_reasons=None,
**kwargs): **kwargs):
if throw_reasons == None: if throw_reasons is None:
throw_reasons = [] throw_reasons = []
if retry_reasons == None: if retry_reasons is None:
retry_reasons = [] retry_reasons = []
method = getattr(service, function) method = getattr(service, function)
retries = 10 retries = 10
@ -947,7 +963,7 @@ def callGAPIpages(service, function, items,
page_message=None, message_attribute=None, page_message=None, message_attribute=None,
throw_reasons=None, throw_reasons=None,
**kwargs): **kwargs):
if throw_reasons == None: if throw_reasons is None:
throw_reasons = [] throw_reasons = []
pageToken = None pageToken = None
all_pages = list() all_pages = list()
@ -989,9 +1005,9 @@ def callGAPIpages(service, function, items,
def callGAPIitems(service, function, items, def callGAPIitems(service, function, items,
throw_reasons=None, retry_reasons=None, throw_reasons=None, retry_reasons=None,
**kwargs): **kwargs):
if throw_reasons == None: if throw_reasons is None:
throw_reasons = [] throw_reasons = []
if retry_reasons == None: if retry_reasons is None:
retry_reasons = [] retry_reasons = []
results = callGAPI(service, function, results = callGAPI(service, function,
throw_reasons=throw_reasons, retry_reasons=retry_reasons, throw_reasons=throw_reasons, retry_reasons=retry_reasons,
@ -1221,7 +1237,7 @@ def showReport():
else: else:
print u'ERROR: %s is not a valid argument to "gam report"' % sys.argv[i] print u'ERROR: %s is not a valid argument to "gam report"' % sys.argv[i]
sys.exit(2) sys.exit(2)
if try_date == None: if try_date is None:
try_date = str(datetime.date.today()) try_date = str(datetime.date.today())
if report in [u'users', u'user']: if report in [u'users', u'user']:
while True: while True:
@ -1372,6 +1388,7 @@ def gen_sha512_hash(password):
return sha512_crypt.encrypt(password, rounds=5000) return sha512_crypt.encrypt(password, rounds=5000)
def printShowDelegates(users, csvFormat): def printShowDelegates(users, csvFormat):
emailsettings = buildGAPIObject(u'email-settings')
if csvFormat: if csvFormat:
todrive = False todrive = False
csvRows = [] csvRows = []
@ -1390,7 +1407,6 @@ def printShowDelegates(users, csvFormat):
else: else:
print u'ERROR: %s is not a valid argument for "gam <users> show delegates"' % sys.argv[i] print u'ERROR: %s is not a valid argument for "gam <users> show delegates"' % sys.argv[i]
sys.exit(2) sys.exit(2)
emailsettings = buildGAPIObject(u'email-settings')
for user in users: for user in users:
if user.find(u'@') == -1: if user.find(u'@') == -1:
userName = user userName = user
@ -2103,7 +2119,7 @@ def doPrintShowGuardians(csvFormat):
items = u'guardianInvitations' items = u'guardianInvitations'
itemName = 'Guardian Invitations' itemName = 'Guardian Invitations'
titles = [u'studentEmail', u'studentId', u'invitedEmailAddress', u'invitationId'] titles = [u'studentEmail', u'studentId', u'invitedEmailAddress', u'invitationId']
if states == None: if states is None:
states = [u'COMPLETE', u'PENDING', u'GUARDIAN_INVITATION_STATE_UNSPECIFIED'] states = [u'COMPLETE', u'PENDING', u'GUARDIAN_INVITATION_STATE_UNSPECIFIED']
i += 1 i += 1
elif myarg == u'states': elif myarg == u'states':
@ -2172,7 +2188,7 @@ def doDeleteGuardian():
def doCreateCourse(): def doCreateCourse():
croom = buildGAPIObject(u'classroom') croom = buildGAPIObject(u'classroom')
body = {} body = {u'ownerId': u'me', u'name': u'Unknown Course'}
i = 3 i = 3
while i < len(sys.argv): while i < len(sys.argv):
if sys.argv[i].lower() == u'name': if sys.argv[i].lower() == u'name':
@ -2205,10 +2221,6 @@ def doCreateCourse():
else: else:
print u'ERROR: %s is not a valid argument for "gam create course".' % sys.argv[i] print u'ERROR: %s is not a valid argument for "gam create course".' % sys.argv[i]
sys.exit(2) sys.exit(2)
if not u'ownerId' in body:
body[u'ownerId'] = u'me'
if not u'name' in body:
body[u'name'] = u'Unknown Course'
result = callGAPI(croom.courses(), u'create', body=body) result = callGAPI(croom.courses(), u'create', body=body)
print u'Created course %s' % result[u'id'] print u'Created course %s' % result[u'id']
@ -2761,7 +2773,7 @@ def doPrinterAddACL():
result = callGAPI(cp.printers(), u'share', printerid=printer, role=role, scope=scope, public=public, skip_notification=skip_notification) result = callGAPI(cp.printers(), u'share', printerid=printer, role=role, scope=scope, public=public, skip_notification=skip_notification)
checkCloudPrintResult(result) checkCloudPrintResult(result)
who = scope who = scope
if who == None: if who is None:
who = u'public' who = u'public'
role = u'user' role = u'user'
print u'Added %s %s' % (role, who) print u'Added %s %s' % (role, who)
@ -2779,7 +2791,7 @@ def doPrinterDelACL():
result = callGAPI(cp.printers(), u'unshare', printerid=printer, scope=scope, public=public) result = callGAPI(cp.printers(), u'unshare', printerid=printer, scope=scope, public=public)
checkCloudPrintResult(result) checkCloudPrintResult(result)
who = scope who = scope
if who == None: if who is None:
who = u'public' who = u'public'
print u'Removed %s' % who print u'Removed %s' % who
@ -3071,7 +3083,7 @@ def doPrintJobSubmit():
filepath = content filepath = content
content = os.path.basename(content) content = os.path.basename(content)
mimetype = mimetypes.guess_type(filepath)[0] mimetype = mimetypes.guess_type(filepath)[0]
if mimetype == None: if mimetype is None:
mimetype = u'application/octet-stream' mimetype = u'application/octet-stream'
filecontent = readFile(filepath) filecontent = readFile(filepath)
form_files[u'content'] = {u'filename': content, u'content': filecontent, u'mimetype': mimetype} form_files[u'content'] = {u'filename': content, u'content': filecontent, u'mimetype': mimetype}
@ -3129,16 +3141,16 @@ def doCalendarShowACL():
print u'Calendar: {0}, ACL: {1}{2}'.format(show_cal, formatACLRule(rule), currentCount(i, count)) print u'Calendar: {0}, ACL: {1}{2}'.format(show_cal, formatACLRule(rule), currentCount(i, count))
def doCalendarAddACL(calendarId=None, act_as=None, role=None, scope=None, entity=None): def doCalendarAddACL(calendarId=None, act_as=None, role=None, scope=None, entity=None):
if act_as != None: if act_as is not None:
act_as, cal = buildCalendarGAPIObject(act_as) act_as, cal = buildCalendarGAPIObject(act_as)
else: else:
cal = buildGAPIObject(u'calendar') cal = buildGAPIObject(u'calendar')
body = {u'scope': {}} body = {u'scope': {}}
if calendarId == None: if calendarId is None:
calendarId = sys.argv[2] calendarId = sys.argv[2]
if calendarId.find(u'@') == -1: if calendarId.find(u'@') == -1:
calendarId = u'%s@%s' % (calendarId, GC_Values[GC_DOMAIN]) calendarId = u'%s@%s' % (calendarId, GC_Values[GC_DOMAIN])
if role != None: if role is not None:
body[u'role'] = role body[u'role'] = role
else: else:
body[u'role'] = sys.argv[4].lower() body[u'role'] = sys.argv[4].lower()
@ -3151,7 +3163,7 @@ def doCalendarAddACL(calendarId=None, act_as=None, role=None, scope=None, entity
body[u'role'] = u'reader' body[u'role'] = u'reader'
elif body[u'role'] == u'editor': elif body[u'role'] == u'editor':
body[u'role'] = u'writer' body[u'role'] = u'writer'
if scope != None: if scope is not None:
body[u'scope'][u'type'] = scope body[u'scope'][u'type'] = scope
else: else:
body[u'scope'][u'type'] = sys.argv[5].lower() body[u'scope'][u'type'] = sys.argv[5].lower()
@ -3160,7 +3172,7 @@ def doCalendarAddACL(calendarId=None, act_as=None, role=None, scope=None, entity
body[u'scope'][u'type'] = u'user' body[u'scope'][u'type'] = u'user'
i = 5 i = 5
try: try:
if entity != None and body[u'scope'][u'type'] != u'default': if entity is not None and body[u'scope'][u'type'] != u'default':
body[u'scope'][u'value'] = entity body[u'scope'][u'value'] = entity
else: else:
body[u'scope'][u'value'] = sys.argv[i].lower() body[u'scope'][u'value'] = sys.argv[i].lower()
@ -3381,7 +3393,7 @@ def doPhoto(users):
continue continue
else: else:
image_data = readFile(filename, continueOnError=True, displayError=True) image_data = readFile(filename, continueOnError=True, displayError=True)
if image_data == None: if image_data is None:
continue continue
image_data = base64.urlsafe_b64encode(image_data) image_data = base64.urlsafe_b64encode(image_data)
body = {u'photoData': image_data} body = {u'photoData': image_data}
@ -3555,7 +3567,7 @@ def printDriveSettings(users):
continue continue
sys.stderr.write(u'Getting Drive settings for %s (%s/%s)\n' % (user, i, count)) sys.stderr.write(u'Getting Drive settings for %s (%s/%s)\n' % (user, i, count))
feed = callGAPI(drive.about(), u'get', soft_errors=True) feed = callGAPI(drive.about(), u'get', soft_errors=True)
if feed == None: if feed is None:
continue continue
row = {u'email': user} row = {u'email': user}
for setting in feed: for setting in feed:
@ -4065,7 +4077,7 @@ def getDriveFileAttribute(i, body, parameters, myarg, update=False):
parameters[DFA_LOCALFILENAME] = os.path.basename(parameters[DFA_LOCALFILEPATH]) parameters[DFA_LOCALFILENAME] = os.path.basename(parameters[DFA_LOCALFILEPATH])
body.setdefault(u'title', parameters[DFA_LOCALFILENAME]) body.setdefault(u'title', parameters[DFA_LOCALFILENAME])
body[u'mimeType'] = mimetypes.guess_type(parameters[DFA_LOCALFILEPATH])[0] body[u'mimeType'] = mimetypes.guess_type(parameters[DFA_LOCALFILEPATH])[0]
if body[u'mimeType'] == None: if body[u'mimeType'] is None:
body[u'mimeType'] = u'application/octet-stream' body[u'mimeType'] = u'application/octet-stream'
parameters[DFA_LOCALMIMETYPE] = body[u'mimeType'] parameters[DFA_LOCALMIMETYPE] = body[u'mimeType']
i += 2 i += 2
@ -4123,7 +4135,7 @@ def getDriveFileAttribute(i, body, parameters, myarg, update=False):
return i return i
def doUpdateDriveFile(users): def doUpdateDriveFile(users):
fileIdSelection = {u'fileIds': None, u'query': None} fileIdSelection = {u'fileIds': [], u'query': None}
media_body = None media_body = None
operation = u'update' operation = u'update'
body, parameters = initializeDriveFileAttributes() body, parameters = initializeDriveFileAttributes()
@ -4246,7 +4258,7 @@ DOCUMENT_FORMATS_MAP = {
def downloadDriveFile(users): def downloadDriveFile(users):
i = 5 i = 5
fileIdSelection = {u'fileIds': None, u'query': None} fileIdSelection = {u'fileIds': [], u'query': None}
revisionId = None revisionId = None
exportFormatName = u'openoffice' exportFormatName = u'openoffice'
exportFormats = DOCUMENT_FORMATS_MAP[exportFormatName] exportFormats = DOCUMENT_FORMATS_MAP[exportFormatName]
@ -4827,13 +4839,16 @@ def addUpdateSendAs(users, i, addCmd):
signature = readFile(filename, encoding=encoding) signature = readFile(filename, encoding=encoding)
else: else:
i = getSendAsAttributes(i, myarg, body, tagReplacements, command) i = getSendAsAttributes(i, myarg, body, tagReplacements, command)
if signature != None: if signature is not None:
if not signature: if not signature:
body[u'signature'] = None body[u'signature'] = None
elif tagReplacements: elif tagReplacements:
body[u'signature'] = _processTags(tagReplacements, signature) body[u'signature'] = _processTags(tagReplacements, signature)
else: else:
body[u'signature'] = signature body[u'signature'] = signature
kwargs = {u'body': body}
if not addCmd:
kwargs[u'sendAsEmail'] = emailAddress
i = 0 i = 0
count = len(users) count = len(users)
for user in users: for user in users:
@ -4842,9 +4857,6 @@ def addUpdateSendAs(users, i, addCmd):
if not gmail: if not gmail:
continue continue
print u"Allowing %s to send as %s (%s/%s)" % (user, emailAddress, i, count) print u"Allowing %s to send as %s (%s/%s)" % (user, emailAddress, i, count)
kwargs = {u'body': body}
if not addCmd:
kwargs[u'sendAsEmail'] = emailAddress
callGAPI(gmail.users().settings().sendAs(), [u'patch', u'create'][addCmd], callGAPI(gmail.users().settings().sendAs(), [u'patch', u'create'][addCmd],
soft_errors=True, soft_errors=True,
userId=u'me', **kwargs) userId=u'me', **kwargs)
@ -5096,7 +5108,7 @@ def doProcessMessages(users, function):
kwargs = {} kwargs = {}
else: else:
kwargs = {u'body': {}} kwargs = {u'body': {}}
for my_key in body.keys(): for my_key in body:
kwargs[u'body'][my_key] = labelsToLabelIds(gmail, body[my_key]) kwargs[u'body'][my_key] = labelsToLabelIds(gmail, body[my_key])
for a_message in listResult: for a_message in listResult:
i += 1 i += 1
@ -5327,7 +5339,7 @@ def renameLabels(users):
if label[u'type'] == u'system': if label[u'type'] == u'system':
continue continue
match_result = re.search(pattern, label[u'name']) match_result = re.search(pattern, label[u'name'])
if match_result != None: if match_result is not None:
new_label_name = replace % match_result.groups() new_label_name = replace % match_result.groups()
print u' Renaming "%s" to "%s"' % (label[u'name'], new_label_name) print u' Renaming "%s" to "%s"' % (label[u'name'], new_label_name)
try: try:
@ -5394,50 +5406,62 @@ FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP = {
def _printFilter(user, userFilter, labels): def _printFilter(user, userFilter, labels):
row = {u'User': user, u'id': userFilter[u'id']} row = {u'User': user, u'id': userFilter[u'id']}
for item in userFilter[u'criteria']: if u'criteria' in userFilter:
if item in [u'hasAttachment', u'excludeChats']: for item in userFilter[u'criteria']:
row[item] = item if item in [u'hasAttachment', u'excludeChats']:
elif item == u'size': row[item] = item
row[item] = u'size {0} {1}'.format(userFilter[u'criteria'][u'sizeComparison'], userFilter[u'criteria'][item]) elif item == u'size':
elif item == u'sizeComparison': row[item] = u'size {0} {1}'.format(userFilter[u'criteria'][u'sizeComparison'], userFilter[u'criteria'][item])
pass elif item == u'sizeComparison':
else: pass
row[item] = u'{0} {1}'.format(item, userFilter[u'criteria'][item]) else:
for labelId in userFilter[u'action'].get(u'addLabelIds', []): row[item] = u'{0} {1}'.format(item, userFilter[u'criteria'][item])
if labelId in FILTER_ADD_LABEL_TO_ARGUMENT_MAP: else:
row[FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId]] = FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId] row[u'error'] = u'NoCriteria'
else: if u'action' in userFilter:
row[u'label'] = u'label {0}'.format(_getLabelName(labels, labelId)) for labelId in userFilter[u'action'].get(u'addLabelIds', []):
for labelId in userFilter[u'action'].get(u'removeLabelIds', []): if labelId in FILTER_ADD_LABEL_TO_ARGUMENT_MAP:
if labelId in FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP: row[FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId]] = FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId]
row[FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId]] = FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId] else:
if userFilter[u'action'].get(u'forward'): row[u'label'] = u'label {0}'.format(_getLabelName(labels, labelId))
row[u'forward'] = u'forward {0}'.format(userFilter[u'action'][u'forward']) for labelId in userFilter[u'action'].get(u'removeLabelIds', []):
if labelId in FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP:
row[FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId]] = FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId]
if userFilter[u'action'].get(u'forward'):
row[u'forward'] = u'forward {0}'.format(userFilter[u'action'][u'forward'])
else:
row[u'error'] = u'NoActions'
return row return row
def _showFilter(userFilter, j, jcount, labels): def _showFilter(userFilter, j, jcount, labels):
print u' Filter: {0}{1}'.format(userFilter[u'id'], currentCount(j, jcount)) print u' Filter: {0}{1}'.format(userFilter[u'id'], currentCount(j, jcount))
print u' Criteria:' print u' Criteria:'
for item in userFilter[u'criteria']: if u'criteria' in userFilter:
if item in [u'hasAttachment', u'excludeChats']: for item in userFilter[u'criteria']:
print u' {0}'.format(item) if item in [u'hasAttachment', u'excludeChats']:
elif item == u'size': print u' {0}'.format(item)
print u' {0} {1} {2}'.format(item, userFilter[u'criteria'][u'sizeComparison'], userFilter[u'criteria'][item]) elif item == u'size':
elif item == u'sizeComparison': print u' {0} {1} {2}'.format(item, userFilter[u'criteria'][u'sizeComparison'], userFilter[u'criteria'][item])
pass elif item == u'sizeComparison':
else: pass
print convertUTF8(u' {0} "{1}"'.format(item, userFilter[u'criteria'][item])) else:
print convertUTF8(u' {0} "{1}"'.format(item, userFilter[u'criteria'][item]))
else:
print u' ERROR: No Filter criteria'
print u' Actions:' print u' Actions:'
for labelId in userFilter[u'action'].get(u'addLabelIds', []): if u'action' in userFilter:
if labelId in FILTER_ADD_LABEL_TO_ARGUMENT_MAP: for labelId in userFilter[u'action'].get(u'addLabelIds', []):
print u' {0}'.format(FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId]) if labelId in FILTER_ADD_LABEL_TO_ARGUMENT_MAP:
else: print u' {0}'.format(FILTER_ADD_LABEL_TO_ARGUMENT_MAP[labelId])
print convertUTF8(u' label "{0}"'.format(_getLabelName(labels, labelId))) else:
for labelId in userFilter[u'action'].get(u'removeLabelIds', []): print convertUTF8(u' label "{0}"'.format(_getLabelName(labels, labelId)))
if labelId in FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP: for labelId in userFilter[u'action'].get(u'removeLabelIds', []):
print u' {0}'.format(FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId]) if labelId in FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP:
if userFilter[u'action'].get(u'forward'): print u' {0}'.format(FILTER_REMOVE_LABEL_TO_ARGUMENT_MAP[labelId])
print u' Forwarding Address: {0}'.format(userFilter[u'action'][u'forward']) if userFilter[u'action'].get(u'forward'):
print u' Forwarding Address: {0}'.format(userFilter[u'action'][u'forward'])
else:
print u' ERROR: No Filter actions'
# #
FILTER_CRITERIA_CHOICES_MAP = { FILTER_CRITERIA_CHOICES_MAP = {
u'excludechats': u'excludeChats', u'excludechats': u'excludeChats',
@ -6109,7 +6133,7 @@ def doPrintShowUserSchemas(csvFormat):
todrive = True todrive = True
i += 1 i += 1
else: else:
print u'ERROR: %s is not a valid argument for "gam <users> %s schemas"' % (myarg, [u'show', u'print'][csvFormat]) print u'ERROR: %s is not a valid argument for "gam %s schemas"' % (myarg, [u'show', u'print'][csvFormat])
sys.exit(2) sys.exit(2)
schemas = callGAPI(cd.schemas(), u'list', customerId=GC_Values[GC_CUSTOMER_ID]) schemas = callGAPI(cd.schemas(), u'list', customerId=GC_Values[GC_CUSTOMER_ID])
if not schemas or u'schemas' not in schemas: if not schemas or u'schemas' not in schemas:
@ -6139,7 +6163,7 @@ def checkClearBodyList(i, body, itemName):
return False return False
def appendItemToBodyList(body, itemName, itemValue): def appendItemToBodyList(body, itemName, itemValue):
if (itemName in body) and (body[itemName] == None): if (itemName in body) and (body[itemName] is None):
del body[itemName] del body[itemName]
body.setdefault(itemName, []) body.setdefault(itemName, [])
body[itemName].append(itemValue) body[itemName].append(itemValue)
@ -7170,7 +7194,7 @@ def doWhatIs():
def doGetUserInfo(user_email=None): def doGetUserInfo(user_email=None):
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
i = 3 i = 3
if user_email == None: if user_email is None:
if len(sys.argv) > 3: if len(sys.argv) > 3:
user_email = sys.argv[3] user_email = sys.argv[3]
i = 4 i = 4
@ -7208,7 +7232,7 @@ def doGetUserInfo(user_email=None):
getSchemas = False getSchemas = False
projection = u'basic' projection = u'basic'
i += 1 i += 1
elif myarg == u'schemas': elif myarg in [u'custom', u'schemas']:
getSchemas = True getSchemas = True
projection = u'custom' projection = u'custom'
customFieldMask = sys.argv[i+1] customFieldMask = sys.argv[i+1]
@ -7391,7 +7415,7 @@ def doGetGroupInfo(group_name=None):
gs = buildGAPIObject(u'groupssettings') gs = buildGAPIObject(u'groupssettings')
getAliases = getUsers = True getAliases = getUsers = True
getGroups = False getGroups = False
if group_name == None: if group_name is None:
group_name = sys.argv[3] group_name = sys.argv[3]
i = 4 i = 4
else: else:
@ -7469,7 +7493,7 @@ def doGetGroupInfo(group_name=None):
def doGetAliasInfo(alias_email=None): def doGetAliasInfo(alias_email=None):
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
if alias_email == None: if alias_email is None:
alias_email = sys.argv[3] alias_email = sys.argv[3]
if alias_email.find(u'@') == -1: if alias_email.find(u'@') == -1:
alias_email = u'%s@%s' % (alias_email, GC_Values[GC_DOMAIN]) alias_email = u'%s@%s' % (alias_email, GC_Values[GC_DOMAIN])
@ -7641,13 +7665,13 @@ def doGetMobileInfo():
def print_json(object_name, object_value, spacing=u''): def print_json(object_name, object_value, spacing=u''):
if object_name in [u'kind', u'etag', u'etags']: if object_name in [u'kind', u'etag', u'etags']:
return return
if object_name != None: if object_name is not None:
sys.stdout.write(u'%s%s: ' % (spacing, object_name)) sys.stdout.write(u'%s%s: ' % (spacing, object_name))
if isinstance(object_value, list): if isinstance(object_value, list):
if len(object_value) == 1 and isinstance(object_value[0], (str, unicode, int, bool)): if len(object_value) == 1 and isinstance(object_value[0], (str, unicode, int, bool)):
sys.stdout.write(convertUTF8(u'%s\n' % object_value[0])) sys.stdout.write(convertUTF8(u'%s\n' % object_value[0]))
return return
if object_name != None: if object_name is not None:
sys.stdout.write(u'\n') sys.stdout.write(u'\n')
for a_value in object_value: for a_value in object_value:
if isinstance(a_value, (str, unicode, int, bool)): if isinstance(a_value, (str, unicode, int, bool)):
@ -7656,7 +7680,7 @@ def print_json(object_name, object_value, spacing=u''):
print_json(None, a_value, u' %s' % spacing) print_json(None, a_value, u' %s' % spacing)
elif isinstance(object_value, dict): elif isinstance(object_value, dict):
print print
if object_name != None: if object_name is not None:
sys.stdout.write(u'\n') sys.stdout.write(u'\n')
for another_object in object_value: for another_object in object_value:
print_json(another_object, object_value[another_object], u' %s' % spacing) print_json(another_object, object_value[another_object], u' %s' % spacing)
@ -7687,7 +7711,7 @@ def doUpdateNotification():
else: else:
print u'ERROR: %s is not a valid argument for "gam update notification"' % sys.argv[i] print u'ERROR: %s is not a valid argument for "gam update notification"' % sys.argv[i]
sys.exit(2) sys.exit(2)
if isUnread == None: if isUnread is None:
print u'ERROR: notifications need to be marked as read or unread.' print u'ERROR: notifications need to be marked as read or unread.'
sys.exit(2) sys.exit(2)
if get_all: if get_all:
@ -8148,7 +8172,7 @@ def doDeleteGroup():
def doDeleteAlias(alias_email=None): def doDeleteAlias(alias_email=None):
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
is_user = is_group = False is_user = is_group = False
if alias_email == None: if alias_email is None:
alias_email = sys.argv[3] alias_email = sys.argv[3]
if alias_email.lower() == u'user': if alias_email.lower() == u'user':
is_user = True is_user = True
@ -8292,7 +8316,7 @@ def writeCSVfile(csvRows, titles, list_type, todrive):
webbrowser.open(file_url) webbrowser.open(file_url)
def flatten_json(structure, key=u'', path=u'', flattened=None, listLimit=None): def flatten_json(structure, key=u'', path=u'', flattened=None, listLimit=None):
if flattened == None: if flattened is None:
flattened = {} flattened = {}
if not isinstance(structure, (dict, list)): if not isinstance(structure, (dict, list)):
flattened[((path + u'.') if path else u'') + key] = structure flattened[((path + u'.') if path else u'') + key] = structure
@ -8394,7 +8418,7 @@ def doPrintUsers():
sortHeaders = True sortHeaders = True
fieldsList = [] fieldsList = []
i += 1 i += 1
elif myarg == u'custom': elif myarg in [u'custom', u'schemas']:
fieldsList.append(u'customSchemas') fieldsList.append(u'customSchemas')
if sys.argv[i+1].lower() == u'all': if sys.argv[i+1].lower() == u'all':
projection = u'full' projection = u'full'
@ -8698,7 +8722,7 @@ def doPrintGroups():
if key in [u'email', u'name', u'description', u'kind', u'etag']: if key in [u'email', u'name', u'description', u'kind', u'etag']:
continue continue
setting_value = settings[key] setting_value = settings[key]
if setting_value == None: if setting_value is None:
setting_value = u'' setting_value = u''
if key not in titles: if key not in titles:
addTitleToCSVfile(key, titles) addTitleToCSVfile(key, titles)
@ -8869,7 +8893,7 @@ def doPrintGroupMembers():
if member[u'type'] == u'USER': if member[u'type'] == u'USER':
try: try:
mbinfo = callGAPI(cd.users(), u'get', mbinfo = callGAPI(cd.users(), u'get',
throw_reasons=[u'notFound', u'forbidden'], throw_reasons=[u'userNotFound', u'notFound', u'forbidden'],
userKey=member[u'id'], fields=u'name') userKey=member[u'id'], fields=u'name')
memberName = mbinfo[u'name'][u'fullName'] memberName = mbinfo[u'name'][u'fullName']
except googleapiclient.errors.HttpError: except googleapiclient.errors.HttpError:
@ -9200,9 +9224,9 @@ def doPrintResourceCalendars():
def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=None, checkNotSuspended=False): def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=None, checkNotSuspended=False):
got_uids = False got_uids = False
if entity_type == None: if entity_type is None:
entity_type = sys.argv[1].lower() entity_type = sys.argv[1].lower()
if entity == None: if entity is None:
entity = sys.argv[2] entity = sys.argv[2]
cd = buildGAPIObject(u'directory') cd = buildGAPIObject(u'directory')
if entity_type == u'user': if entity_type == u'user':
@ -9212,7 +9236,7 @@ def getUsersToModify(entity_type=None, entity=None, silent=False, member_type=No
elif entity_type == u'group': elif entity_type == u'group':
got_uids = True got_uids = True
group = entity group = entity
if member_type == None: if member_type is None:
member_type_message = u'all members' member_type_message = u'all members'
else: else:
member_type_message = u'%ss' % member_type.lower() member_type_message = u'%ss' % member_type.lower()
@ -9650,7 +9674,8 @@ def batch_worker():
GM_Globals[GM_BATCH_QUEUE].task_done() GM_Globals[GM_BATCH_QUEUE].task_done()
def run_batch(items): def run_batch(items):
import Queue, threading import Queue
import threading
total_items = len(items) total_items = len(items)
current_item = 0 current_item = 0
python_cmd = [sys.executable.lower(),] python_cmd = [sys.executable.lower(),]
@ -9940,14 +9965,14 @@ def ProcessGAMCommand(args):
sys.exit(2) sys.exit(2)
sys.exit(0) sys.exit(0)
elif command == u'print': elif command == u'print':
argument = sys.argv[2].lower() argument = sys.argv[2].lower().replace(u'-', u'')
if argument == u'users': if argument == u'users':
doPrintUsers() doPrintUsers()
elif argument in [u'nicknames', u'aliases']: elif argument in [u'nicknames', u'aliases']:
doPrintAliases() doPrintAliases()
elif argument == u'groups': elif argument == u'groups':
doPrintGroups() doPrintGroups()
elif argument in [u'group-members', u'groups-members']: elif argument in [u'groupmembers', u'groupsmembers']:
doPrintGroupMembers() doPrintGroupMembers()
elif argument in [u'orgs', u'ous']: elif argument in [u'orgs', u'ous']:
doPrintOrgs() doPrintOrgs()
@ -9965,7 +9990,7 @@ def ProcessGAMCommand(args):
doPrintShowUserSchemas(True) doPrintShowUserSchemas(True)
elif argument in [u'courses', u'classes']: elif argument in [u'courses', u'classes']:
doPrintCourses() doPrintCourses()
elif argument in [u'course-participants', u'class-participants']: elif argument in [u'courseparticipants', u'classparticipants']:
doPrintCourseParticipants() doPrintCourseParticipants()
elif argument == u'printers': elif argument == u'printers':
doPrintPrinters() doPrintPrinters()