mirror of
https://github.com/GAM-team/GAM.git
synced 2025-07-05 20:23:34 +00:00
Fixed/improved handling of shortcuts in gam <UserTypeEntity> transfer drive
.
This commit is contained in:
@ -10,6 +10,10 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
|||||||
|
|
||||||
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
See [Downloads](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 6.66.11
|
||||||
|
|
||||||
|
Fixed/improved handling of shortcuts in `gam <UserTypeEntity> transfer drive`.
|
||||||
|
|
||||||
### 6.66.10
|
### 6.66.10
|
||||||
|
|
||||||
Updated `gam create datatransfer` to handle the following error:
|
Updated `gam create datatransfer` to handle the following error:
|
||||||
|
@ -334,7 +334,7 @@ writes the credentials into the file oauth2.txt.
|
|||||||
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
admin@server:/Users/admin/bin/gamadv-xtd3$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
admin@server:/Users/admin/bin/gamadv-xtd3$ ./gam version
|
||||||
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.66.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.10.8 64-bit final
|
Python 3.10.8 64-bit final
|
||||||
MacOS High Sierra 10.13.6 x86_64
|
MacOS High Sierra 10.13.6 x86_64
|
||||||
@ -1002,7 +1002,7 @@ writes the credentials into the file oauth2.txt.
|
|||||||
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
C:\GAMADV-XTD3>del C:\GAMConfig\oauth2.txt
|
||||||
C:\GAMADV-XTD3>gam version
|
C:\GAMADV-XTD3>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAMADV-XTD3 6.66.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
|
@ -585,13 +585,6 @@ gam <UserTypeEntity> delete events <UserCalendarEntity> [doit] [<EventNotificati
|
|||||||
```
|
```
|
||||||
No events are deleted unless you specify the `doit` option; omit `doit` to verify that you properly selected the events to delete.
|
No events are deleted unless you specify the `doit` option; omit `doit` to verify that you properly selected the events to delete.
|
||||||
|
|
||||||
## Move calendar events to another calendar
|
|
||||||
Generally you won't move all events from one calendar to another; typically, you'll move events created by the event creator
|
|
||||||
using `matchfield creatoremail <RegularExpression>` in conjunction with other `<EventSelectProperty>` and `<EventMatchProperty>` options.
|
|
||||||
```
|
|
||||||
gam <UserTypeEntity> move events <UserCalendarEntity> [<EventEntity>] destination|to <CalendarItem> [<EventNotificationAttribute>]
|
|
||||||
```
|
|
||||||
|
|
||||||
## Empty calendar trash
|
## Empty calendar trash
|
||||||
A user signed in to Google Calendar can empty the calendar trash but there is no direct API support for this operation.
|
A user signed in to Google Calendar can empty the calendar trash but there is no direct API support for this operation.
|
||||||
To empty the calendar trash a temporary calendar is created, the deleted events are moved to the temporary calendar and then the temporary calendar is deleted.
|
To empty the calendar trash a temporary calendar is created, the deleted events are moved to the temporary calendar and then the temporary calendar is deleted.
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAMADV-XTD3 6.66.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@ -16,7 +16,7 @@ Time: 2023-06-02T21:10:00-07:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAMADV-XTD3 6.66.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@ -28,7 +28,7 @@ Your system time differs from www.googleapis.com by less than 1 second
|
|||||||
Print the current version of Gam with extended details and SSL information
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAMADV-XTD3 6.66.10 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
GAMADV-XTD3 6.66.11 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/Admin/bin/gamadv-xtd3
|
Path: /Users/Admin/bin/gamadv-xtd3
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 6.66.10
|
Latest: 6.66.11
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@ -73,7 +73,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
6.66.10
|
6.66.11
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@ -83,7 +83,7 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 6.66.10 - https://github.com/taers232c/GAMADV-XTD3
|
GAM 6.66.11 - https://github.com/taers232c/GAMADV-XTD3
|
||||||
Ross Scroggs <ross.scroggs@gmail.com>
|
Ross Scroggs <ross.scroggs@gmail.com>
|
||||||
Python 3.12.0 64-bit final
|
Python 3.12.0 64-bit final
|
||||||
MacOS Monterey 12.7 x86_64
|
MacOS Monterey 12.7 x86_64
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
Merged GAM-Team version
|
Merged GAM-Team version
|
||||||
|
|
||||||
|
6.66.11
|
||||||
|
|
||||||
|
Fixed/improved handling of shortcuts in `gam <UserTypeEntity> transfer drive`.
|
||||||
|
|
||||||
6.66.10
|
6.66.10
|
||||||
|
|
||||||
Updated `gam create datatransfer` to handle the following error:
|
Updated `gam create datatransfer` to handle the following error:
|
||||||
|
@ -5107,30 +5107,30 @@ def checkGAPIError(e, softErrors=False, retryOnHttpError=False, mapNotFound=True
|
|||||||
error = makeErrorDict(http_status, GAPI.OPERATION_NOT_SUPPORTED, message)
|
error = makeErrorDict(http_status, GAPI.OPERATION_NOT_SUPPORTED, message)
|
||||||
elif 'failed status in update settings response' in lmessage:
|
elif 'failed status in update settings response' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.INVALID_INPUT, message)
|
error = makeErrorDict(http_status, GAPI.INVALID_INPUT, message)
|
||||||
elif status == 'INTERNAL':
|
|
||||||
error = makeErrorDict(http_status, GAPI.INTERNAL_ERROR, message)
|
|
||||||
elif 'cannot delete a field in use.resource.fields' in lmessage:
|
elif 'cannot delete a field in use.resource.fields' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.FIELD_IN_USE, message)
|
error = makeErrorDict(http_status, GAPI.FIELD_IN_USE, message)
|
||||||
|
elif status == 'INTERNAL':
|
||||||
|
error = makeErrorDict(http_status, GAPI.INTERNAL_ERROR, message)
|
||||||
elif http_status == 502:
|
elif http_status == 502:
|
||||||
if 'bad gateway' in lmessage:
|
if 'bad gateway' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.BAD_GATEWAY, message)
|
error = makeErrorDict(http_status, GAPI.BAD_GATEWAY, message)
|
||||||
elif http_status == 503:
|
elif http_status == 503:
|
||||||
if status == 'UNAVAILABLE' or 'the service is currently unavailable' in lmessage:
|
if message.startswith('quota exceeded for the current request'):
|
||||||
error = makeErrorDict(http_status, GAPI.SERVICE_NOT_AVAILABLE, message)
|
|
||||||
elif message.startswith('quota exceeded for the current request'):
|
|
||||||
error = makeErrorDict(http_status, GAPI.QUOTA_EXCEEDED, message)
|
error = makeErrorDict(http_status, GAPI.QUOTA_EXCEEDED, message)
|
||||||
|
elif status == 'UNAVAILABLE' or 'the service is currently unavailable' in lmessage:
|
||||||
|
error = makeErrorDict(http_status, GAPI.SERVICE_NOT_AVAILABLE, message)
|
||||||
elif http_status == 504:
|
elif http_status == 504:
|
||||||
if 'gateway timeout' in lmessage:
|
if 'gateway timeout' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.GATEWAY_TIMEOUT, message)
|
error = makeErrorDict(http_status, GAPI.GATEWAY_TIMEOUT, message)
|
||||||
elif http_status == 400:
|
elif http_status == 400:
|
||||||
if '@attachmentnotvisible' in lmessage:
|
if '@attachmentnotvisible' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.BAD_REQUEST, message)
|
error = makeErrorDict(http_status, GAPI.BAD_REQUEST, message)
|
||||||
|
elif 'does not match' in lmessage or 'invalid' in lmessage:
|
||||||
|
error = makeErrorDict(http_status, GAPI.INVALID, message)
|
||||||
elif status == 'FAILED_PRECONDITION' or 'precondition check failed' in lmessage:
|
elif status == 'FAILED_PRECONDITION' or 'precondition check failed' in lmessage:
|
||||||
error = makeErrorDict(http_status, GAPI.FAILED_PRECONDITION, message)
|
error = makeErrorDict(http_status, GAPI.FAILED_PRECONDITION, message)
|
||||||
elif status == 'INVALID_ARGUMENT':
|
elif status == 'INVALID_ARGUMENT':
|
||||||
error = makeErrorDict(http_status, GAPI.INVALID_ARGUMENT, message)
|
error = makeErrorDict(http_status, GAPI.INVALID_ARGUMENT, message)
|
||||||
elif 'does not match' in lmessage or 'invalid' in lmessage:
|
|
||||||
error = makeErrorDict(http_status, GAPI.INVALID, message)
|
|
||||||
elif http_status == 401:
|
elif http_status == 401:
|
||||||
if status == 'PERMISSION_DENIED':
|
if status == 'PERMISSION_DENIED':
|
||||||
error = makeErrorDict(http_status, GAPI.PERMISSION_DENIED, message)
|
error = makeErrorDict(http_status, GAPI.PERMISSION_DENIED, message)
|
||||||
@ -57919,17 +57919,55 @@ def transferDrive(users):
|
|||||||
entityModifierItemValueListActionPerformed(kvList, Act.MODIFIER_IN,
|
entityModifierItemValueListActionPerformed(kvList, Act.MODIFIER_IN,
|
||||||
[Ent.DRIVE_FOLDER, newParentId, targetEntityType, f"{childName}({result['id']})"],
|
[Ent.DRIVE_FOLDER, newParentId, targetEntityType, f"{childName}({result['id']})"],
|
||||||
j, jcount)
|
j, jcount)
|
||||||
Act.Set(action)
|
|
||||||
except (GAPI.forbidden, GAPI.insufficientFilePermissions, GAPI.insufficientParentPermissions, GAPI.invalid, GAPI.badRequest,
|
except (GAPI.forbidden, GAPI.insufficientFilePermissions, GAPI.insufficientParentPermissions, GAPI.invalid, GAPI.badRequest,
|
||||||
GAPI.fileNotFound, GAPI.unknownError, GAPI.storageQuotaExceeded, GAPI.teamDrivesSharingRestrictionNotAllowed,
|
GAPI.fileNotFound, GAPI.unknownError, GAPI.storageQuotaExceeded, GAPI.teamDrivesSharingRestrictionNotAllowed,
|
||||||
GAPI.teamDriveHierarchyTooDeep, GAPI.shortcutTargetInvalid) as e:
|
GAPI.teamDriveHierarchyTooDeep, GAPI.shortcutTargetInvalid) as e:
|
||||||
entityActionFailedWarning(kvList+[Ent.DRIVE_FILE_SHORTCUT, childName], str(e), j, jcount)
|
entityActionFailedWarning(kvList+[Ent.DRIVE_FILE_SHORTCUT, childName], str(e), j, jcount)
|
||||||
|
Act.Set(action)
|
||||||
|
|
||||||
|
# Recreate source user shortcut in target user
|
||||||
|
def _transferShortcut(j, jcount, childEntryInfo, childId, childName, newParentId):
|
||||||
|
entityType = Ent.DRIVE_FOLDER_SHORTCUT if childEntryInfo['shortcutDetails']['targetMimeType'] == MIMETYPE_GA_FOLDER else Ent.DRIVE_FILE_SHORTCUT
|
||||||
|
kvList = [Ent.USER, sourceUser, entityType, f'{childName}({childId})']
|
||||||
|
action = Act.Get()
|
||||||
|
body = {'name': childName, 'mimeType': MIMETYPE_GA_SHORTCUT,
|
||||||
|
'parents': [newParentId], 'shortcutDetails': {'targetId': childEntryInfo['shortcutDetails']['targetId']}}
|
||||||
|
Act.Set(Act.RECREATE)
|
||||||
|
try:
|
||||||
|
result = callGAPI(targetDrive.files(), 'create',
|
||||||
|
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.FORBIDDEN, GAPI.INSUFFICIENT_PERMISSIONS, GAPI.INSUFFICIENT_PARENT_PERMISSIONS,
|
||||||
|
GAPI.INVALID, GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND, GAPI.UNKNOWN_ERROR,
|
||||||
|
GAPI.STORAGE_QUOTA_EXCEEDED, GAPI.TEAMDRIVES_SHARING_RESTRICTION_NOT_ALLOWED,
|
||||||
|
GAPI.TEAMDRIVE_HIERARCHY_TOO_DEEP, GAPI.SHORTCUT_TARGET_INVALID],
|
||||||
|
body=body, fields='id', supportsAllDrives=True)
|
||||||
|
shortcutId = result['id']
|
||||||
|
entityModifierNewValueItemValueListActionPerformed(kvList, Act.MODIFIER_IN, None, [Ent.USER, targetUser,
|
||||||
|
Ent.DRIVE_FOLDER, newParentId, entityType, f"{shortcutId})"],
|
||||||
|
j, jcount)
|
||||||
|
except (GAPI.forbidden, GAPI.insufficientFilePermissions, GAPI.insufficientParentPermissions, GAPI.invalid, GAPI.badRequest,
|
||||||
|
GAPI.fileNotFound, GAPI.unknownError, GAPI.storageQuotaExceeded, GAPI.teamDrivesSharingRestrictionNotAllowed,
|
||||||
|
GAPI.teamDriveHierarchyTooDeep, GAPI.shortcutTargetInvalid) as e:
|
||||||
|
entityActionFailedWarning(kvList+[Ent.DRIVE_FILE_SHORTCUT, childName], str(e), j, jcount)
|
||||||
|
Act.Set(action)
|
||||||
|
return
|
||||||
|
if ownerRetainRoleBody['role'] == 'none':
|
||||||
|
Act.Set(Act.DELETE_SHORTCUT)
|
||||||
|
kvList = [Ent.USER, sourceUser, entityType, f'{childName}({childId})']
|
||||||
|
try:
|
||||||
|
callGAPI(sourceDrive.files(), 'delete',
|
||||||
|
throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.FILE_NEVER_WRITABLE],
|
||||||
|
fileId=childId, supportsAllDrives=True)
|
||||||
|
entityActionPerformed(kvList, j, jcount)
|
||||||
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.unknownError, GAPI.fileNeverWritable) as e:
|
||||||
|
entityActionFailedWarning(kvList, str(e), j, jcount)
|
||||||
|
Act.Set(action)
|
||||||
|
|
||||||
def _transferFile(childEntry, i, count, j, jcount, atSelectTop):
|
def _transferFile(childEntry, i, count, j, jcount, atSelectTop):
|
||||||
childEntryInfo = childEntry['info']
|
childEntryInfo = childEntry['info']
|
||||||
childFileId = childEntryInfo['id']
|
childFileId = childEntryInfo['id']
|
||||||
childFileName = childEntryInfo['name']
|
childFileName = childEntryInfo['name']
|
||||||
childFileType = _getEntityMimeType(childEntryInfo)
|
childFileType = _getEntityMimeType(childEntryInfo)
|
||||||
|
# Owned files
|
||||||
if childEntryInfo['ownedByMe']:
|
if childEntryInfo['ownedByMe']:
|
||||||
childEntryInfo['sourcePermission'] = {'role': 'owner'}
|
childEntryInfo['sourcePermission'] = {'role': 'owner'}
|
||||||
for permission in childEntryInfo.get('permissions', []):
|
for permission in childEntryInfo.get('permissions', []):
|
||||||
@ -57975,20 +58013,25 @@ def transferDrive(users):
|
|||||||
GAPI.PERMISSION_NOT_FOUND, GAPI.SHARING_RATE_LIMIT_EXCEEDED],
|
GAPI.PERMISSION_NOT_FOUND, GAPI.SHARING_RATE_LIMIT_EXCEEDED],
|
||||||
fileId=childFileId, permissionId=targetPermissionId,
|
fileId=childFileId, permissionId=targetPermissionId,
|
||||||
transferOwnership=True, body={'role': 'owner'}, fields='')
|
transferOwnership=True, body={'role': 'owner'}, fields='')
|
||||||
if removeSourceParents:
|
if removeSourceParents:
|
||||||
op = 'Remove Source Parents'
|
op = 'Remove Source Parents'
|
||||||
callGAPI(sourceDrive.files(), 'update',
|
callGAPI(sourceDrive.files(), 'update',
|
||||||
throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS, retryReasons=[GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND], triesLimit=3,
|
throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS, retryReasons=[GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND], triesLimit=3,
|
||||||
fileId=childFileId, removeParents=','.join(removeSourceParents), fields='')
|
fileId=childFileId, removeParents=','.join(removeSourceParents), fields='')
|
||||||
actionUser = targetUser
|
actionUser = targetUser
|
||||||
if addTargetParent or removeTargetParents:
|
if addTargetParent or removeTargetParents:
|
||||||
op = 'Add/Remove Target Parents'
|
op = 'Add/Remove Target Parents'
|
||||||
callGAPI(targetDrive.files(), 'update',
|
callGAPI(targetDrive.files(), 'update',
|
||||||
throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.INSUFFICIENT_PARENT_PERMISSIONS],
|
throwReasons=GAPI.DRIVE_ACCESS_THROW_REASONS+[GAPI.INSUFFICIENT_PARENT_PERMISSIONS],
|
||||||
retryReasons=[GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND], triesLimit=3,
|
retryReasons=[GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND], triesLimit=3,
|
||||||
fileId=childFileId,
|
fileId=childFileId,
|
||||||
addParents=addTargetParent, removeParents=','.join(removeTargetParents), fields='')
|
addParents=addTargetParent, removeParents=','.join(removeTargetParents), fields='')
|
||||||
entityModifierNewValueItemValueListActionPerformed([Ent.USER, sourceUser, childFileType, childFileName], Act.MODIFIER_TO, None, [Ent.USER, targetUser], j, jcount)
|
entityModifierNewValueItemValueListActionPerformed([Ent.USER, sourceUser, childFileType, childFileName], Act.MODIFIER_TO, None, [Ent.USER, targetUser], j, jcount)
|
||||||
|
else:
|
||||||
|
if topSourceId in childParents:
|
||||||
|
_transferShortcut(j, jcount, childEntryInfo, childFileId, childFileName, addTargetParent)
|
||||||
|
else:
|
||||||
|
entityModifierNewValueItemValueListActionPerformed([Ent.USER, sourceUser, childFileType, childFileName], Act.MODIFIER_TO, None, [Ent.USER, targetUser], j, jcount)
|
||||||
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.unknownError,
|
except (GAPI.fileNotFound, GAPI.forbidden, GAPI.internalError, GAPI.unknownError,
|
||||||
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.insufficientParentPermissions) as e:
|
GAPI.badRequest, GAPI.sharingRateLimitExceeded, GAPI.insufficientParentPermissions) as e:
|
||||||
entityActionFailedWarning([Ent.USER, actionUser, childFileType, childFileName], f'{op}: {str(e)}', j, jcount)
|
entityActionFailedWarning([Ent.USER, actionUser, childFileType, childFileName], f'{op}: {str(e)}', j, jcount)
|
||||||
@ -58003,6 +58046,7 @@ def transferDrive(users):
|
|||||||
entityActionFailedWarning([Ent.USER, actionUser, childFileType, childFileName], Ent.TypeNameMessage(Ent.PERMISSION_ID, targetPermissionId, str(e)), j, jcount)
|
entityActionFailedWarning([Ent.USER, actionUser, childFileType, childFileName], Ent.TypeNameMessage(Ent.PERMISSION_ID, targetPermissionId, str(e)), j, jcount)
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
userSvcNotApplicableOrDriveDisabled(actionUser, str(e), i, count)
|
userSvcNotApplicableOrDriveDisabled(actionUser, str(e), i, count)
|
||||||
|
# Non-owned files
|
||||||
else:
|
else:
|
||||||
Act.Set(Act.PROCESS)
|
Act.Set(Act.PROCESS)
|
||||||
for permission in childEntryInfo.get('permissions', []):
|
for permission in childEntryInfo.get('permissions', []):
|
||||||
@ -58145,6 +58189,10 @@ def transferDrive(users):
|
|||||||
childFileId = childEntryInfo['id']
|
childFileId = childEntryInfo['id']
|
||||||
childFileName = childEntryInfo['name']
|
childFileName = childEntryInfo['name']
|
||||||
childFileType = _getEntityMimeType(childEntryInfo)
|
childFileType = _getEntityMimeType(childEntryInfo)
|
||||||
|
if childEntryInfo['mimeType'] == MIMETYPE_GA_SHORTCUT:
|
||||||
|
if showRetentionMessages:
|
||||||
|
entityActionNotPerformedWarning([Ent.USER, sourceUser, childFileType, childFileName, Ent.ROLE, ownerRetainRoleBody['role']], Msg.NOT_APPROPRIATE, j, jcount)
|
||||||
|
return
|
||||||
if childEntryInfo['ownedByMe']:
|
if childEntryInfo['ownedByMe']:
|
||||||
try:
|
try:
|
||||||
if ownerRetainRoleBody['role'] != 'none':
|
if ownerRetainRoleBody['role'] != 'none':
|
||||||
@ -58293,7 +58341,7 @@ def transferDrive(users):
|
|||||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
|
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
|
||||||
retryReasons=[GAPI.UNKNOWN_ERROR],
|
retryReasons=[GAPI.UNKNOWN_ERROR],
|
||||||
orderBy=OBY.orderBy, q=WITH_PARENTS.format(fileId),
|
orderBy=OBY.orderBy, q=WITH_PARENTS.format(fileId),
|
||||||
fields='nextPageToken,files(id,name,parents,mimeType,ownedByMe,trashed,owners(emailAddress,permissionId),permissions(id,role))',
|
fields='nextPageToken,files(id,name,parents,mimeType,ownedByMe,trashed,owners(emailAddress,permissionId),permissions(id,role),shortcutDetails)',
|
||||||
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS])
|
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS])
|
||||||
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
userSvcNotApplicableOrDriveDisabled(sourceUser, str(e), i, count)
|
userSvcNotApplicableOrDriveDisabled(sourceUser, str(e), i, count)
|
||||||
@ -58512,6 +58560,7 @@ def transferDrive(users):
|
|||||||
return
|
return
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
if buildTree:
|
if buildTree:
|
||||||
|
topSourceId = sourceRootId
|
||||||
parentIdMap = {sourceRootId: targetIds[TARGET_PARENT_ID]}
|
parentIdMap = {sourceRootId: targetIds[TARGET_PARENT_ID]}
|
||||||
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, Ent.TypeName(Ent.SOURCE_USER, user), i, count)
|
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, Ent.TypeName(Ent.SOURCE_USER, user), i, count)
|
||||||
feed = callGAPIpages(sourceDrive.files(), 'list', 'files',
|
feed = callGAPIpages(sourceDrive.files(), 'list', 'files',
|
||||||
@ -58519,7 +58568,7 @@ def transferDrive(users):
|
|||||||
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
|
throwReasons=GAPI.DRIVE_USER_THROW_REASONS,
|
||||||
retryReasons=[GAPI.UNKNOWN_ERROR],
|
retryReasons=[GAPI.UNKNOWN_ERROR],
|
||||||
orderBy=OBY.orderBy, q=NON_TRASHED,
|
orderBy=OBY.orderBy, q=NON_TRASHED,
|
||||||
fields='nextPageToken,files(id,name,parents,mimeType,ownedByMe,owners(emailAddress,permissionId),permissions(id,role))',
|
fields='nextPageToken,files(id,name,parents,mimeType,ownedByMe,owners(emailAddress,permissionId),permissions(id,role),shortcutDetails)',
|
||||||
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS])
|
pageSize=GC.Values[GC.DRIVE_MAX_RESULTS])
|
||||||
fileTree = buildFileTree(feed, sourceDrive)
|
fileTree = buildFileTree(feed, sourceDrive)
|
||||||
del feed
|
del feed
|
||||||
@ -58546,7 +58595,7 @@ def transferDrive(users):
|
|||||||
fileEntry = callGAPI(sourceDrive.files(), 'get',
|
fileEntry = callGAPI(sourceDrive.files(), 'get',
|
||||||
throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
|
throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
|
||||||
fileId=fileId,
|
fileId=fileId,
|
||||||
fields='id,name,parents,mimeType,ownedByMe,trashed,owners(emailAddress,permissionId),permissions(id,role)')
|
fields='id,name,parents,mimeType,ownedByMe,trashed,owners(emailAddress,permissionId),permissions(id,role),shortcutDetails')
|
||||||
entityType = _getEntityMimeType(fileEntry)
|
entityType = _getEntityMimeType(fileEntry)
|
||||||
if fileId in skipFileIdEntity['list']:
|
if fileId in skipFileIdEntity['list']:
|
||||||
entityActionNotPerformedWarning([Ent.USER, sourceUser, entityType, f'{fileEntry["name"]} ({fileId})'],
|
entityActionNotPerformedWarning([Ent.USER, sourceUser, entityType, f'{fileEntry["name"]} ({fileId})'],
|
||||||
@ -58554,9 +58603,11 @@ def transferDrive(users):
|
|||||||
continue
|
continue
|
||||||
entityPerformActionItemValue([Ent.USER, sourceUser], entityType, f'{fileEntry["name"]} ({fileId})', j, jcount)
|
entityPerformActionItemValue([Ent.USER, sourceUser], entityType, f'{fileEntry["name"]} ({fileId})', j, jcount)
|
||||||
if not mergeWithTarget:
|
if not mergeWithTarget:
|
||||||
|
topSourceId = None
|
||||||
for parentId in fileEntry.get('parents', []):
|
for parentId in fileEntry.get('parents', []):
|
||||||
parentIdMap[parentId] = targetIds[TARGET_PARENT_ID]
|
parentIdMap[parentId] = targetIds[TARGET_PARENT_ID]
|
||||||
else:
|
else:
|
||||||
|
topSourceId = fileId
|
||||||
parentIdMap[fileId] = targetIds[TARGET_PARENT_ID]
|
parentIdMap[fileId] = targetIds[TARGET_PARENT_ID]
|
||||||
_identifyDriveFileAndChildren(fileEntry, i, count)
|
_identifyDriveFileAndChildren(fileEntry, i, count)
|
||||||
filesTransferred = set()
|
filesTransferred = set()
|
||||||
|
@ -49,6 +49,7 @@ class GamAction():
|
|||||||
DELETE = 'dele'
|
DELETE = 'dele'
|
||||||
DELETE_EMPTY = 'delm'
|
DELETE_EMPTY = 'delm'
|
||||||
DELETE_PREVIEW = 'delp'
|
DELETE_PREVIEW = 'delp'
|
||||||
|
DELETE_SHORTCUT = 'desc'
|
||||||
DEPROVISION = 'depr'
|
DEPROVISION = 'depr'
|
||||||
DISABLE = 'disa'
|
DISABLE = 'disa'
|
||||||
DOWNLOAD = 'down'
|
DOWNLOAD = 'down'
|
||||||
@ -160,12 +161,15 @@ class GamAction():
|
|||||||
COPY_MERGE: ['Copied(Merge)', 'Copy(Merge)'],
|
COPY_MERGE: ['Copied(Merge)', 'Copy(Merge)'],
|
||||||
CREATE: ['Created', 'Create'],
|
CREATE: ['Created', 'Create'],
|
||||||
CREATE_PREVIEW: ['Created (Preview)', 'Create (Preview)'],
|
CREATE_PREVIEW: ['Created (Preview)', 'Create (Preview)'],
|
||||||
CREATE_SHORTCUT: ['Created Shortcut', 'Create SHORTCUT'],
|
CREATE_SHORTCUT: ['Created Shortcut', 'Create Shortcut'],
|
||||||
DEDUP: ['Duplicates Deleted', 'Delete Duplicates'],
|
DEDUP: ['Duplicates Deleted', 'Delete Duplicates'],
|
||||||
DELETE: ['Deleted', 'Delete'],
|
DELETE: ['Deleted', 'Delete'],
|
||||||
DELETE_EMPTY: ['Deleted', 'Delete Empty'],
|
DELETE_EMPTY: ['Deleted', 'Delete Empty'],
|
||||||
DELETE_PREVIEW: ['Deleted (Preview)', 'Delete (Preview)'],
|
DELETE_PREVIEW: ['Deleted (Preview)', 'Delete (Preview)'],
|
||||||
DEPROVISION: ['Deprovisioned', 'Deprovision'],
|
DEPROVISION: ['Deprovisioned', 'Deprovision'],
|
||||||
|
DELETE_SHORTCUT: ['Deleted Shortcut', 'Delete Shortcut'],
|
||||||
|
DISABLE: ['Disabled', 'Disable'],
|
||||||
|
DEPROVISION: ['Deprovisioned', 'Deprovision'],
|
||||||
DISABLE: ['Disabled', 'Disable'],
|
DISABLE: ['Disabled', 'Disable'],
|
||||||
DOWNLOAD: ['Downloaded', 'Download'],
|
DOWNLOAD: ['Downloaded', 'Download'],
|
||||||
DRAFT: ['Drafted', 'Draft'],
|
DRAFT: ['Drafted', 'Draft'],
|
||||||
|
@ -338,6 +338,7 @@ NOT_A_MEMBER = 'Not a member'
|
|||||||
NOT_ACTIVE = 'Not Active'
|
NOT_ACTIVE = 'Not Active'
|
||||||
NOT_ALLOWED = 'Not Allowed'
|
NOT_ALLOWED = 'Not Allowed'
|
||||||
NOT_AN_ENTITY = 'Not a {0}'
|
NOT_AN_ENTITY = 'Not a {0}'
|
||||||
|
NOT_APPROPRIATE = 'Not Appropriate'
|
||||||
NOT_COMPATIBLE = 'Not Compatible'
|
NOT_COMPATIBLE = 'Not Compatible'
|
||||||
NOT_COPYABLE = 'Not Copyable'
|
NOT_COPYABLE = 'Not Copyable'
|
||||||
NOT_COPYABLE_INTO_ITSELF = 'Not copyable into itself'
|
NOT_COPYABLE_INTO_ITSELF = 'Not copyable into itself'
|
||||||
|
Reference in New Issue
Block a user