mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-20 22:21:37 +00:00
Compare commits
4 Commits
20241122.1
...
20241127.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84d04141b3 | ||
|
|
f29c697455 | ||
|
|
a1238c6397 | ||
|
|
4dfdc3a717 |
@@ -1059,6 +1059,7 @@ Specify a collection of items by directly specifying them; the item type is dete
|
||||
all_shortcuts |
|
||||
all_3p_shortcuts |
|
||||
all_items |
|
||||
my_commentable_items |
|
||||
my_docs |
|
||||
my_files |
|
||||
my_folders |
|
||||
@@ -6779,12 +6780,12 @@ gam print ownership <DriveFileID>|(drivefilename <DriveFileName>) [todrive <ToDr
|
||||
gam <UserTypeEntity> show filecomments <DriveFileEntity>
|
||||
[showdeleted] [start <Date>|<Time>]
|
||||
[fields <CommentsFieldNameList>] [showphotolinks]
|
||||
[countsonly]
|
||||
[countsonly|positivecountsonly]
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> print filecomments <DriveFileEntity> [todrive <ToDriveAttribute>*]
|
||||
[showdeleted] [start <Date>|<Time>]
|
||||
[fields <CommentsFieldNameList>] [showphotolinks]
|
||||
[countsonly]
|
||||
[countsonly|positivecountsonly]
|
||||
(addcsvdata <FieldName> <String>)*
|
||||
[formatjson [quotechar <Character>]]
|
||||
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
7.01.03
|
||||
|
||||
Fixed bug in `gam update cigroups <GroupEntity> delete|sync|update` where `cbcm-browser` and `chrome-os_device`
|
||||
addresses were not properly handled.
|
||||
|
||||
7.01.02
|
||||
|
||||
Added option `positivecountsonly` to `gam <UserTypeEntity> print|show filecomments` that causes
|
||||
GAM to display the number of comments and replies only for files that have comments.
|
||||
|
||||
Added `my_commentable_items` to `<DriveFileQueryShortcut>` that can be used with
|
||||
`gam <UserTypeEntity> print|show filecomments my_commentable_items` to speed up processing.
|
||||
|
||||
Updated code that uses the Domain Shared Contacts API with an HTTPS proxy to avoid a trap:
|
||||
```
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
File "atom/http.py", line 250, in _prepare_connection
|
||||
AttributeError: module 'ssl' has no attribute 'wrap_socket'
|
||||
```
|
||||
|
||||
7.01.01
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> print|show filetree` where no error message was generated
|
||||
if a user had Drive disabled.
|
||||
|
||||
7.01.00
|
||||
|
||||
Fixed bug in `gam update chromepolicy` that caused some policy updates to fail.
|
||||
@@ -5,7 +31,7 @@ Fixed bug in `gam update chromepolicy` that caused some policy updates to fail.
|
||||
Added option `showhtml` to `gam <UserTypeEntity> print|show messages` that, when used with `showbody`,
|
||||
will display message body content of type HTML.
|
||||
|
||||
Added support for manageing/displaying Chrome profiles.
|
||||
Added support for managing/displaying Chrome profiles.
|
||||
|
||||
* See: https://github.com/GAM-team/GAM/wiki/Chrome-Profile-Management
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.01.00'
|
||||
__version__ = '7.01.03'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@@ -5729,8 +5729,10 @@ def convertUIDtoEmailAddressWithType(emailAddressOrUID, cd=None, sal=None, email
|
||||
# Convert UID to email address
|
||||
def convertUIDtoEmailAddress(emailAddressOrUID, cd=None, emailTypes=None,
|
||||
checkForCustomerId=False, ciGroupsAPI=False, aliasAllowed=True):
|
||||
if emailAddressOrUID.startswith('cbcm-browser.'):
|
||||
return emailAddressOrUID
|
||||
if ciGroupsAPI:
|
||||
normalizedEmailAddressOrUID = normalizeEmailAddressOrUID(emailAddressOrUID, ciGroupsAPI=ciGroupsAPI)
|
||||
if normalizedEmailAddressOrUID.startswith('cbcm-browser.') or normalizedEmailAddressOrUID.startswith('chrome-os-device.'):
|
||||
return normalizedEmailAddressOrUID
|
||||
email, _ = convertUIDtoEmailAddressWithType(emailAddressOrUID, cd, emailTypes,
|
||||
checkForCustomerId, ciGroupsAPI, aliasAllowed)
|
||||
return email
|
||||
@@ -34639,7 +34641,7 @@ def doUpdateCIGroups():
|
||||
continue
|
||||
_batchAddGroupMembers(parent, i, count,
|
||||
[convertUIDtoEmailAddress(member, cd=cd, emailTypes='any',
|
||||
checkForCustomerId=True) for member in addMembers],
|
||||
checkForCustomerId=True, ciGroupsAPI=True) for member in addMembers],
|
||||
role, expireTime)
|
||||
elif CL_subCommand in {'delete', 'remove'}:
|
||||
baseRole, groupMemberType = _getRoleGroupMemberType()
|
||||
@@ -34681,11 +34683,12 @@ def doUpdateCIGroups():
|
||||
j = 0
|
||||
for member in removeMembers:
|
||||
j += 1
|
||||
memberEmail = convertUIDtoEmailAddress(member, cd=cd, emailTypes='any', checkForCustomerId=True)
|
||||
memberEmail = convertUIDtoEmailAddress(member, cd=cd, emailTypes='any',
|
||||
checkForCustomerId=True, ciGroupsAPI=True)
|
||||
try:
|
||||
memberName = callGAPI(ci.groups().memberships(), 'lookup',
|
||||
throwReasons=GAPI.CIGROUP_GET_THROW_REASONS,
|
||||
parent=parent, memberKey_id=member, fields='name').get('name')
|
||||
parent=parent, memberKey_id=memberEmail, fields='name').get('name')
|
||||
callGAPI(ci.groups().memberships(), 'delete',
|
||||
throwReasons=GAPI.MEMBERS_THROW_REASONS+[GAPI.FAILED_PRECONDITION],
|
||||
name=memberName)
|
||||
@@ -34714,7 +34717,7 @@ def doUpdateCIGroups():
|
||||
syncMembersMaps[baseRole] = {}
|
||||
for member in syncMembers:
|
||||
syncMembersSets[baseRole].add(_cleanConsumerAddress(convertUIDtoEmailAddress(member, cd=cd, emailTypes='any',
|
||||
checkForCustomerId=True), syncMembersMaps[baseRole]))
|
||||
checkForCustomerId=True, ciGroupsAPI=True), syncMembersMaps[baseRole]))
|
||||
checkForExtraneousArguments()
|
||||
i = 0
|
||||
count = len(entityList)
|
||||
@@ -34836,7 +34839,8 @@ def doUpdateCIGroups():
|
||||
j = 0
|
||||
for member in updateMembers:
|
||||
j += 1
|
||||
memberEmail = convertUIDtoEmailAddress(member, cd=cd, emailTypes='any', checkForCustomerId=True)
|
||||
memberEmail = convertUIDtoEmailAddress(member, cd=cd, emailTypes='any',
|
||||
checkForCustomerId=True, ciGroupsAPI=True)
|
||||
try:
|
||||
memberName = callGAPI(ci.groups().memberships(), 'lookup',
|
||||
throwReasons=GAPI.CIGROUP_GET_THROW_REASONS,
|
||||
@@ -51946,6 +51950,7 @@ QUERY_SHORTCUTS_MAP = {
|
||||
'allshortcuts': f"mimeType = '{MIMETYPE_GA_SHORTCUT}'",
|
||||
'all3pshortcuts': f"mimeType = '{MIMETYPE_GA_3P_SHORTCUT}'",
|
||||
'allitems': 'allitems',
|
||||
'mycommentableitems': ME_IN_OWNERS_AND+f"(mimeType = '{MIMETYPE_GA_DOCUMENT}' or mimeType = '{MIMETYPE_GA_SPREADSHEET}' or mimeType = '{MIMETYPE_GA_PRESENTATION}')",
|
||||
'mydocs': ME_IN_OWNERS_AND+f"mimeType = '{MIMETYPE_GA_DOCUMENT}'",
|
||||
'myfiles': ME_IN_OWNERS_AND+f"mimeType != '{MIMETYPE_GA_FOLDER}'",
|
||||
'myfolders': ME_IN_OWNERS_AND+f"mimeType = '{MIMETYPE_GA_FOLDER}'",
|
||||
@@ -54815,7 +54820,8 @@ def initFileTree(drive, shareddrive, DLP, shareddriveFields, showParent, user, i
|
||||
except (GAPI.notFound, GAPI.fileNotFound, GAPI.invalid, GAPI.noListTeamDrivesAdministratorPrivilege) as e:
|
||||
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE, fileId], str(e), i, count)
|
||||
return (None, False)
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy):
|
||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||
userSvcNotApplicableOrDriveDisabled(user, str(e), i, count)
|
||||
return (None, False)
|
||||
return (fileTree, True)
|
||||
|
||||
@@ -56232,14 +56238,14 @@ def _showComment(comment, stripPhotoLinks, timeObjects, i=0, count=0, FJQC=None)
|
||||
Ind.Decrement()
|
||||
|
||||
# gam <UserTypeEntity> show filecomments <DriveFileEntity>
|
||||
# [showdeleted] [start <Date>|<Time>] [countsonly]
|
||||
# [showdeleted] [start <Date>|<Time>] [countsonly|positivecountsonly]
|
||||
# [fields <CommentsFieldNameList>] [showphotolinks]
|
||||
# [countsonly]
|
||||
# [formatjson]
|
||||
# gam <UserTypeEntity> print filecomments <DriveFileEntity> [todrive <ToDriveAttribute>*]
|
||||
# [showdeleted] [start <Date>|<Time>]
|
||||
# [fields <CommentsFieldNameList>] [showphotolinks]
|
||||
# [countsonly]
|
||||
# [countsonly|positivecountsonly]
|
||||
# (addcsvdata <FieldName> <String>)*
|
||||
# [formatjson [quotechar <Character>]]
|
||||
def printShowFileComments(users):
|
||||
@@ -56264,7 +56270,7 @@ def printShowFileComments(users):
|
||||
FJQC = FormatJSONQuoteChar(csvPF)
|
||||
fieldsList = []
|
||||
fileIdEntity = getDriveFileEntity()
|
||||
countsOnly = False
|
||||
countsOnly = positiveCountsOnly = False
|
||||
stripPhotoLinks = True
|
||||
kwargs = {}
|
||||
addCSVData = {}
|
||||
@@ -56285,6 +56291,8 @@ def printShowFileComments(users):
|
||||
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
||||
elif myarg == 'countsonly':
|
||||
countsOnly = True
|
||||
elif myarg == 'positivecountsonly':
|
||||
countsOnly = positiveCountsOnly = True
|
||||
else:
|
||||
FJQC.GetFormatJSONQuoteChar(myarg)
|
||||
if csvPF:
|
||||
@@ -56338,7 +56346,8 @@ def printShowFileComments(users):
|
||||
numReplies += len(comment['replies'])
|
||||
if not csvPF:
|
||||
if countsOnly:
|
||||
printKeyValueList([Ent.Singular(Ent.DRIVE_FILE_ID), fileId, 'comments', kcount, 'replies', numReplies])
|
||||
if not positiveCountsOnly or kcount > 0:
|
||||
printKeyValueList([Ent.Singular(Ent.DRIVE_FILE_ID), fileId, 'comments', kcount, 'replies', numReplies])
|
||||
else:
|
||||
if not FJQC.formatJSON:
|
||||
entityPerformActionNumItems([Ent.DRIVE_FILE_ID, fileId], kcount, Ent.DRIVE_FILE_COMMENT, j, jcount)
|
||||
@@ -56350,12 +56359,13 @@ def printShowFileComments(users):
|
||||
_showComment(comment, stripPhotoLinks, timeObjects, k, kcount, FJQC)
|
||||
Ind.Decrement()
|
||||
elif countsOnly:
|
||||
row = {'User': user, 'fileId': fileId}
|
||||
if addCSVData:
|
||||
row.update(addCSVData)
|
||||
row['comments'] = kcount
|
||||
row['replies'] = numReplies
|
||||
csvPF.WriteRowTitles(row)
|
||||
if not positiveCountsOnly or kcount > 0:
|
||||
row = {'User': user, 'fileId': fileId}
|
||||
if addCSVData:
|
||||
row.update(addCSVData)
|
||||
row['comments'] = kcount
|
||||
row['replies'] = numReplies
|
||||
csvPF.WriteRowTitles(row)
|
||||
elif comments:
|
||||
baserow = {'User': user, 'fileId': fileId}
|
||||
if addCSVData:
|
||||
|
||||
@@ -247,7 +247,9 @@ class ProxiedHttpClient(HttpClient):
|
||||
# Trivial setup for ssl socket.
|
||||
sslobj = None
|
||||
if ssl_imported:
|
||||
sslobj = ssl.wrap_socket(p_sock, None, None)
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
|
||||
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
||||
sslobj = context.wrap_socket(p_sock, server_hostname=url.host)
|
||||
else:
|
||||
sock_ssl = socket.ssl(p_sock, None, None)
|
||||
sslobj = http.client.FakeSocket(p_sock, sock_ssl)
|
||||
|
||||
@@ -568,7 +568,7 @@ class ProxiedHttpClient(HttpClient):
|
||||
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
||||
sslobj = context.wrap_socket(p_sock, server_hostname=uri.host)
|
||||
else:
|
||||
sock_ssl = socket.ssl(p_sock, None, Nonesock_)
|
||||
sock_ssl = socket.ssl(p_sock, None, None)
|
||||
sslobj = http.client.FakeSocket(p_sock, sock_ssl)
|
||||
# Initalize httplib and replace with the proxy socket.
|
||||
connection = http.client.HTTPConnection(proxy_uri.host)
|
||||
|
||||
Reference in New Issue
Block a user