diff --git a/docs/GamUpdates.md b/docs/GamUpdates.md index 522d7f0a..dd8aa5fa 100644 --- a/docs/GamUpdates.md +++ b/docs/GamUpdates.md @@ -10,6 +10,10 @@ Add the `-s` option to the end of the above commands to suppress creating the `g See [Downloads-Installs](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation +### 6.80.17 + +Updated `gam modify messages` to improve error handling. + ### 6.80.16 Fixed bug in `gam print vaultcounts` that caused a trap. diff --git a/docs/How-to-Upgrade-from-Standard-GAM.md b/docs/How-to-Upgrade-from-Standard-GAM.md index cd8fbaa9..88091d3f 100644 --- a/docs/How-to-Upgrade-from-Standard-GAM.md +++ b/docs/How-to-Upgrade-from-Standard-GAM.md @@ -251,7 +251,7 @@ writes the credentials into the file oauth2.txt. admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt admin@server:/Users/admin$ gam version WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found -GAMADV-XTD3 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 @@ -923,7 +923,7 @@ writes the credentials into the file oauth2.txt. C:\>del C:\GAMConfig\oauth2.txt C:\>gam version WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found -GAMADV-XTD3 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final Windows-10-10.0.17134 AMD64 diff --git a/docs/Version-and-Help.md b/docs/Version-and-Help.md index 79c6a284..a7596298 100644 --- a/docs/Version-and-Help.md +++ b/docs/Version-and-Help.md @@ -1,9 +1,9 @@ -\\# Version and Help +# Version and Help Print the current version of Gam with details ``` gam version -GAMADV-XTD3 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 @@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00 Print the current version of Gam with details and time offset information ``` gam version timeoffset -GAMADV-XTD3 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 @@ -27,7 +27,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 ``` gam version extended -GAMADV-XTD3 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource +GAMADV-XTD3 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 @@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64 Path: /Users/Admin/bin/gamadv-xtd3 Version Check: Current: 5.35.08 - Latest: 6.80.16 + Latest: 6.80.17 echo $? 1 ``` @@ -72,7 +72,7 @@ echo $? Print the current version number without details ``` gam version simple -6.80.16 +6.80.17 ``` In Linux/MacOS you can do: ``` @@ -82,7 +82,7 @@ echo $VER Print the current version of Gam and address of this Wiki ``` gam help -GAM 6.80.16 - https://github.com/taers232c/GAMADV-XTD3 +GAM 6.80.17 - https://github.com/taers232c/GAMADV-XTD3 Ross Scroggs Python 3.12.5 64-bit final MacOS Sonoma 14.5 x86_64 diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index 997de7eb..2ec09239 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -2,6 +2,10 @@ Merged GAM-Team version +6.80.17 + +Updated `gam modify messages` to improve error handling. + 6.80.16 Fixed bug in `gam print vaultcounts` that caused a trap. diff --git a/src/gam/__init__.py b/src/gam/__init__.py index c3720fb9..271c2389 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -2409,6 +2409,12 @@ def entityDoesNotExistWarning(entityType, entityName, i=0, count=0): [Ent.Singular(entityType), entityName, Msg.DOES_NOT_EXIST], currentCountNL(i, count))) +def entityListDoesNotExistWarning(entityValueList, i=0, count=0): + setSysExitRC(ENTITY_DOES_NOT_EXIST_RC) + writeStderr(formatKeyValueList(Ind.Spaces(), + Ent.FormatEntityValueList(entityValueList)+[Msg.DOES_NOT_EXIST], + currentCountNL(i, count))) + def entityUnknownWarning(entityType, entityName, i=0, count=0): domain = getEmailAddressDomain(entityName) if (domain.endswith(GC.Values[GC.DOMAIN])) or (domain.endswith('google.com')): @@ -67502,12 +67508,12 @@ def createLabels(users, labelEntity): if not buildPath: try: callGAPI(gmail.users().labels(), 'create', - throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.DUPLICATE, GAPI.PERMISSION_DENIED], + throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.DUPLICATE, GAPI.INVALID, GAPI.PERMISSION_DENIED], userId='me', body=body, fields='') entityActionPerformed([Ent.USER, user, Ent.LABEL, label], l, lcount) except GAPI.duplicate: entityActionFailedWarning([Ent.USER, user, Ent.LABEL, label], Msg.DUPLICATE, l, lcount) - except GAPI.permissionDenied as e: + except (GAPI.invalid, GAPI.permissionDenied) as e: entityActionFailedWarning([Ent.USER, user, Ent.LABEL, label], str(e), l, lcount) except (GAPI.serviceNotAvailable, GAPI.badRequest): entityServiceNotApplicableWarning(Ent.USER, user, i, count) @@ -68036,7 +68042,7 @@ def _initLabelNameMap(userGmailLabels): labelNameMap[label['name']] = labelNameMap[label['name'].upper()] = label['id'] return labelNameMap -def _convertLabelNamesToIds(gmail, bodyLabels, labelNameMap, addLabelIfMissing): +def _convertLabelNamesToIds(gmail, user, i, count, bodyLabels, labelNameMap, addLabel): labelIds = [] for label in bodyLabels: if label in labelNameMap: @@ -68045,14 +68051,19 @@ def _convertLabelNamesToIds(gmail, bodyLabels, labelNameMap, addLabelIfMissing): if label.upper() in labelNameMap: labelIds.append(labelNameMap[label.upper()]) continue - if not addLabelIfMissing: + if not addLabel: + entityListDoesNotExistWarning([Ent.USER, user, Ent.LABEL, label], i, count) continue try: results = callGAPI(gmail.users().labels(), 'create', throwReasons=[GAPI.INVALID], userId='me', body={'labelListVisibility': 'labelShow', 'messageListVisibility': 'show', 'name': label}, fields='id') except GAPI.invalid as e: - entityActionFailedExit([Ent.LABEL, label], str(e)) + action = Act.Get() + Act.Set(Act.CREATE) + entityActionFailedWarning([Ent.USER, user, Ent.LABEL, label], str(e), i, count) + Act.Set(action) + continue labelNameMap[label] = labelNameMap[label.upper()] = results['id'] labelIds.append(results['id']) if label.find('/') != -1: @@ -68289,7 +68300,7 @@ def _processMessagesThreads(users, entityType): idsList += ',...' try: callGAPI(gmail.users().messages(), function, - throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.INVALID, + throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.INVALID_MESSAGE_ID, GAPI.INVALID, GAPI.INVALID_ARGUMENT, GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED], userId='me', body=body) for messageId in body['ids']: @@ -68300,7 +68311,7 @@ def _processMessagesThreads(users, entityType): csvPF.WriteRow({'User': user, entityHeader: messageId, 'action': Act.Performed()}) except (GAPI.serviceNotAvailable, GAPI.badRequest): mcount += bcount - except (GAPI.invalid, GAPI.permissionDenied) as e: + except (GAPI.invalid, GAPI.invalidArgument, GAPI.permissionDenied) as e: _processMessageFailed(user, idsList, f'{str(e)} ({mcount+1}-{mcount+bcount}/{jcount})') mcount += bcount except GAPI.invalidMessageId: @@ -68369,6 +68380,8 @@ def _processMessagesThreads(users, entityType): csvPF.GetTodriveParameters() else: unknownArgumentExit() + if function == 'modify' and not addLabelNames and not removeLabelNames: + missingArgumentExit('(addlabel )|(removelabel )') _finalizeMessageSelectParameters(parameters, True) includeSpamTrash = Act.Get() in [Act.DELETE, Act.MODIFY, Act.UNTRASH] if function == 'spam': @@ -68387,8 +68400,11 @@ def _processMessagesThreads(users, entityType): if not userGmailLabels: continue labelNameMap = _initLabelNameMap(userGmailLabels) - addLabelIds = _convertLabelNamesToIds(gmail, addLabelNames, labelNameMap, True) - removeLabelIds = _convertLabelNamesToIds(gmail, removeLabelNames, labelNameMap, False) + addLabelIds = _convertLabelNamesToIds(gmail, user, i, count, addLabelNames, labelNameMap, True) + removeLabelIds = _convertLabelNamesToIds(gmail, user, i, count, removeLabelNames, labelNameMap, False) + if not addLabelIds and not removeLabelIds: + entityActionNotPerformedWarning([Ent.USER, user], Msg.NO_LABELS_TO_PROCESS, i, count) + continue try: if parameters['messageEntity'] is None: printGettingAllEntityItemsForWhom(Ent.MESSAGE, user, i, count) @@ -69039,7 +69055,7 @@ def _draftImportInsertMessage(users, operation): if not userGmailLabels: continue labelNameMap = _initLabelNameMap(userGmailLabels) - body['labelIds'] = _convertLabelNamesToIds(gmail, addLabelNames, labelNameMap, True) + body['labelIds'] = _convertLabelNamesToIds(gmail, user, i, count, addLabelNames, labelNameMap, True) else: body['labelIds'] = ['INBOX'] result = callGAPI(gmail.users().messages(), function, diff --git a/src/gam/gamlib/glmsgs.py b/src/gam/gamlib/glmsgs.py index 6082b864..b916e45e 100644 --- a/src/gam/gamlib/glmsgs.py +++ b/src/gam/gamlib/glmsgs.py @@ -396,6 +396,7 @@ NO_ENTITIES_MATCHED = 'No {0} matched' NO_FILTER_ACTIONS = 'No {0} actions specified' NO_FILTER_CRITERIA = 'No {0} criteria specified' NO_LABELS_MATCH = 'No Labels match' +NO_LABELS_TO_PROCESS = 'No Labels to process' NO_MESSAGES_WITH_LABEL = 'No Messages with Label' NO_PARENTS_TO_CONVERT_TO_SHORTCUTS = 'No parents to convert to shortcuts' NO_REPORT_AVAILABLE = 'No {0} report available.'