Three updates (#956)

Add notregex to GAM_CSV_ROW_FILTER to allow selection rows that don't have a particular value

Standarize formatting timestamps

Display mobile.patchSecurityLevel as a date/time
This commit is contained in:
Ross Scroggs
2019-06-18 11:03:19 -07:00
committed by Jay Lee
parent df4de5ce4b
commit 34dc12994a
3 changed files with 46 additions and 35 deletions

View File

@@ -143,6 +143,7 @@ If an item contains spaces, it should be surrounded by ".
<ASPID> ::= <String>
<BuildingID> ::= <String>|id:<String>
<CalendarACLRole> ::= editor|freebusy|freebusyreader|owner|reader|writer
<CalendarACLRuleID> ::= user:<EmailAddress>|group:<EmailAddress>|domain:<DomainName>|default
<CalendarColorIndex> ::= <Number in range 1-24>
<CalendarItem> ::= <EmailAddress>|<String>
<ChatRoom> ::= <String>

View File

@@ -604,7 +604,7 @@ def SetGlobalVariables():
ROW_FILTER_COMP_PATTERN = re.compile(r'^(date|time|count)\s*([<>]=?|=|!=)\s*(.+)$', re.IGNORECASE)
ROW_FILTER_BOOL_PATTERN = re.compile(r'^(boolean):(.+)$', re.IGNORECASE)
ROW_FILTER_RE_PATTERN = re.compile(r'^(regex):(.+)$', re.IGNORECASE)
ROW_FILTER_RE_PATTERN = re.compile(r'^(regex|notregex):(.+)$', re.IGNORECASE)
def _getCfgRowFilter(itemName):
value = GC_Defaults[itemName]
@@ -647,7 +647,7 @@ def SetGlobalVariables():
continue
except re.error as e:
systemErrorExit(3, 'Item: {0}, Value: "{1}": "{2}", Invalid RE: {3}'.format(itemName, column, filterStr, e))
systemErrorExit(3, 'Item: {0}, Value: "{1}": {2}, Expected: (date|time|count<Operator><Value>) or (boolean:true|false) or (regex:<RegularExpression>)'.format(itemName, column, filterStr))
systemErrorExit(3, 'Item: {0}, Value: "{1}": {2}, Expected: (date|time|count<Operator><Value>) or (boolean:true|false) or (regex|notregex:<RegularExpression>)'.format(itemName, column, filterStr))
return rowFilters
except (TypeError, ValueError) as e:
systemErrorExit(3, 'Item: {0}, Value: "{1}", Failed to parse as JSON: {2}'.format(itemName, value, str(e)))
@@ -2027,11 +2027,11 @@ def doGetDomainInfo():
domainName = sys.argv[3]
result = callGAPI(cd.domains(), 'get', customer=GC_Values[GC_CUSTOMER_ID], domainName=domainName)
if 'creationTime' in result:
result['creationTime'] = str(datetime.datetime.fromtimestamp(int(result['creationTime'])/1000))
result['creationTime'] = utils.formatTimestampYMDHMSF(result['creationTime'])
if 'domainAliases' in result:
for i in range(0, len(result['domainAliases'])):
if 'creationTime' in result['domainAliases'][i]:
result['domainAliases'][i]['creationTime'] = str(datetime.datetime.fromtimestamp(int(result['domainAliases'][i]['creationTime'])/1000))
result['domainAliases'][i]['creationTime'] = utils.formatTimestampYMDHMSF(result['domainAliases'][i]['creationTime'])
print_json(None, result)
def doGetDomainAliasInfo():
@@ -2039,7 +2039,7 @@ def doGetDomainAliasInfo():
alias = sys.argv[3]
result = callGAPI(cd.domainAliases(), 'get', customer=GC_Values[GC_CUSTOMER_ID], domainAliasName=alias)
if 'creationTime' in result:
result['creationTime'] = str(datetime.datetime.fromtimestamp(int(result['creationTime'])/1000))
result['creationTime'] = utils.formatTimestampYMDHMSF(result['creationTime'])
print_json(None, result)
def doGetCustomerInfo():
@@ -2159,7 +2159,7 @@ def doPrintDomains(return_results=False):
if attr in ['kind', 'etag', 'domainAliases', 'isPrimary']:
continue
if attr in ['creationTime',]:
domain[attr] = str(datetime.datetime.fromtimestamp(int(domain[attr])/1000))
domain[attr] = utils.formatTimestampYMDHMSF(domain[attr])
if attr not in titles:
titles.append(attr)
domain_attributes[attr] = domain[attr]
@@ -2174,7 +2174,7 @@ def doPrintDomains(return_results=False):
if attr in ['kind', 'etag']:
continue
if attr in ['creationTime',]:
aliasdomain[attr] = str(datetime.datetime.fromtimestamp(int(aliasdomain[attr])/1000))
aliasdomain[attr] = utils.formatTimestampYMDHMSF(aliasdomain[attr])
if attr not in titles:
titles.append(attr)
aliasdomain_attributes[attr] = aliasdomain[attr]
@@ -2203,7 +2203,7 @@ def doPrintDomainAliases():
if attr in ['kind', 'etag']:
continue
if attr == 'creationTime':
domainAlias[attr] = str(datetime.datetime.fromtimestamp(int(domainAlias[attr])/1000))
domainAlias[attr] = utils.formatTimestampYMDHMSF(domainAlias[attr])
if attr not in titles:
titles.append(attr)
domainAlias_attributes[attr] = domainAlias[attr]
@@ -3048,9 +3048,8 @@ def doPrintPrintJobs():
jobCount = totalJobs
break
continue
updateTime = int(job['updateTime'])/1000
job['createTime'] = datetime.datetime.fromtimestamp(createTime).strftime('%Y-%m-%d %H:%M:%S')
job['updateTime'] = datetime.datetime.fromtimestamp(updateTime).strftime('%Y-%m-%d %H:%M:%S')
job['createTime'] = utils.formatTimestampYMDHMS(job['createTime'])
job['updateTime'] = utils.formatTimestampYMDHMS(job['updateTime'])
job['tags'] = ' '.join(job['tags'])
addRowTitlesToCSVfile(flatten_json(job), csvRows, titles)
if jobCount >= totalJobs:
@@ -3090,12 +3089,9 @@ def doPrintPrinters():
printers = callGAPI(cp.printers(), 'list', q=query, type=printer_type, connection_status=connection_status, extra_fields=extra_fields)
checkCloudPrintResult(printers)
for printer in printers['printers']:
createTime = int(printer['createTime'])/1000
accessTime = int(printer['accessTime'])/1000
updateTime = int(printer['updateTime'])/1000
printer['createTime'] = datetime.datetime.fromtimestamp(createTime).strftime('%Y-%m-%d %H:%M:%S')
printer['accessTime'] = datetime.datetime.fromtimestamp(accessTime).strftime('%Y-%m-%d %H:%M:%S')
printer['updateTime'] = datetime.datetime.fromtimestamp(updateTime).strftime('%Y-%m-%d %H:%M:%S')
printer['createTime'] = utils.formatTimestampYMDHMS(printer['createTime'])
printer['accessTime'] = utils.formatTimestampYMDHMS(printer['accessTime'])
printer['updateTime'] = utils.formatTimestampYMDHMS(printer['updateTime'])
printer['tags'] = ' '.join(printer['tags'])
addRowTitlesToCSVfile(flatten_json(printer), csvRows, titles)
writeCSVfile(csvRows, titles, 'Printers', todrive)
@@ -3518,12 +3514,9 @@ def doGetPrinterInfo():
result = callGAPI(cp.printers(), 'get', printerid=printerid)
checkCloudPrintResult(result)
printer_info = result['printers'][0]
createTime = int(printer_info['createTime'])/1000
accessTime = int(printer_info['accessTime'])/1000
updateTime = int(printer_info['updateTime'])/1000
printer_info['createTime'] = datetime.datetime.fromtimestamp(createTime).strftime('%Y-%m-%d %H:%M:%S')
printer_info['accessTime'] = datetime.datetime.fromtimestamp(accessTime).strftime('%Y-%m-%d %H:%M:%S')
printer_info['updateTime'] = datetime.datetime.fromtimestamp(updateTime).strftime('%Y-%m-%d %H:%M:%S')
printer_info['createTime'] = utils.formatTimestampYMDHMS(printer_info['createTime'])
printer_info['accessTime'] = utils.formatTimestampYMDHMS(printer_info['accessTime'])
printer_info['updateTime'] = utils.formatTimestampYMDHMS(printer_info['updateTime'])
printer_info['tags'] = ' '.join(printer_info['tags'])
if not everything:
del printer_info['capabilities']
@@ -5765,7 +5758,7 @@ def printShowSmime(users, csvFormat):
result = callGAPI(gmail.users().settings().sendAs().smimeInfo(), 'list', sendAsEmail=sendAsEmail, userId='me')
smimes = result.get('smimeInfo', [])
for j, _ in enumerate(smimes):
smimes[j]['expiration'] = datetime.datetime.fromtimestamp(int(smimes[j]['expiration'])/1000).strftime('%Y-%m-%d %H:%M:%S')
smimes[j]['expiration'] = utils.formatTimestampYMDHMS(smimes[j]['expiration'])
if csvFormat:
for smime in smimes:
addRowTitlesToCSVfile(flatten_json(smime, flattened={'User': user}), csvRows, titles)
@@ -6869,11 +6862,11 @@ def getVacation(users):
print(' Contacts Only: {0}'.format(result['restrictToContacts']))
print(' Domain Only: {0}'.format(result['restrictToDomain']))
if 'startTime' in result:
print(' Start Date: {0}'.format(datetime.datetime.fromtimestamp(int(result['startTime'])/1000).strftime('%Y-%m-%d')))
print(' Start Date: {0}'.format(utils.formatTimestampYMD(result['startTime'])))
else:
print(' Start Date: Started')
if 'endTime' in result:
print(' End Date: {0}'.format(datetime.datetime.fromtimestamp(int(result['endTime'])/1000).strftime('%Y-%m-%d')))
print(' End Date: {0}'.format(utils.formatTimestampYMD(result['endTime'])))
else:
print(' End Date: Not specified')
print(utils.convertUTF8(' Subject: {0}'.format(result.get('responseSubject', 'None'))))
@@ -7528,8 +7521,8 @@ def _run_oauth_flow(client_id, client_secret, scopes, access_type, login_hint=No
'token_uri': 'https://oauth2.googleapis.com/token',
}
}
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_config(
client_config, scopes)
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_config(client_config, scopes)
kwargs = {'access_type': access_type}
if login_hint:
kwargs['login_hint'] = login_hint
@@ -10325,6 +10318,9 @@ def doGetMobileInfo():
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)
attrib = 'securityPatchLevel'
if attrib in info and int(info[attrib]):
info[attrib] = utils.formatTimestampYMDHMS(info[attrib])
print_json(None, info)
def print_json(object_name, object_value, spacing=''):
@@ -10585,11 +10581,11 @@ def doGetASPs(users):
if asp['creationTime'] == '0':
created_date = 'Unknown'
else:
created_date = datetime.datetime.fromtimestamp(int(asp['creationTime'])/1000).strftime('%Y-%m-%d %H:%M:%S')
created_date = utils.formatTimestampYMDHMS(asp['creationTime'])
if asp['lastTimeUsed'] == '0':
used_date = 'Never'
else:
used_date = datetime.datetime.fromtimestamp(int(asp['lastTimeUsed'])/1000).strftime('%Y-%m-%d %H:%M:%S')
used_date = utils.formatTimestampYMDHMS(asp['lastTimeUsed'])
print(' ID: %s\n Name: %s\n Created: %s\n Last Used: %s\n' % (asp['codeId'], asp['name'], created_date, used_date))
else:
print(' no ASPs for %s\n' % user)
@@ -11003,6 +10999,8 @@ def writeCSVfile(csvRows, titles, list_type, todrive):
continue
if filterVal[0] == 'regex':
csvRows = [row for row in csvRows if filterVal[1].search(str(row.get(column, '')))]
elif filterVal[0] == 'notregex':
csvRows = [row for row in csvRows if not filterVal[1].search(str(row.get(column, '')))]
elif filterVal[0] in ['date', 'time']:
csvRows = [row for row in csvRows if rowDateTimeFilterMatch(filterVal[0] == 'date', row.get(column, ''), filterVal[1], filterVal[2])]
elif filterVal[0] == 'count':
@@ -12024,10 +12022,12 @@ def doPrintMobileDevices():
else:
if attrib not in titles:
titles.append(attrib)
if attrib != 'deviceId':
row[attrib] = mobile[attrib]
else:
if attrib == 'deviceId':
row[attrib] = mobile[attrib].encode('unicode-escape').decode(UTF8)
elif attrib == 'securityPatchLevel' and int(mobile[attrib]):
row[attrib] = utils.formatTimestampYMDHMS(mobile[attrib])
else:
row[attrib] = mobile[attrib]
csvRows.append(row)
sortCSVTitles(['resourceId', 'deviceId', 'serialNumber', 'name', 'email', 'status'], titles)
writeCSVfile(csvRows, titles, 'Mobile', todrive)

View File

@@ -1,3 +1,4 @@
import datetime
import re
import sys
from html.entities import name2codepoint
@@ -22,8 +23,7 @@ class _DeHTMLParser(HTMLParser):
self.__text.append(data)
def handle_charref(self, name):
self.__text.append(
chr(int(name[1:], 16)) if name.startswith('x') else chr(int(name)))
self.__text.append(chr(int(name[1:], 16)) if name.startswith('x') else chr(int(name)))
def handle_entityref(self, name):
cp = name2codepoint.get(name)
@@ -73,6 +73,16 @@ def indentMultiLineText(message, n=0):
return message.replace('\n', '\n{0}'.format(' ' * n)).rstrip()
def formatTimestampYMD(timestamp):
return datetime.datetime.fromtimestamp(int(timestamp)/1000).strftime('%Y-%m-%d')
def formatTimestampYMDHMS(timestamp):
return datetime.datetime.fromtimestamp(int(timestamp)/1000).strftime('%Y-%m-%d %H:%M:%S')
def formatTimestampYMDHMSF(timestamp):
return str(datetime.datetime.fromtimestamp(int(timestamp)/1000))
def formatFileSize(fileSize):
if fileSize == 0:
return '0kb'