diff --git a/src/GamUpdate.txt b/src/GamUpdate.txt index bdf4e84d..9ff58afe 100644 --- a/src/GamUpdate.txt +++ b/src/GamUpdate.txt @@ -1,3 +1,14 @@ +7.05.20 + +Updated code to validate both `` and `` +in the following command line options; this will expose errors when the command +is being parsed rather than at run-time. +``` +replaceregex +replacedescription +replacefilename +``` + 7.05.19 Added `replaceregex ` to the following commands: diff --git a/src/gam/__init__.py b/src/gam/__init__.py index 84a6a9d3..7d02c1d2 100755 --- a/src/gam/__init__.py +++ b/src/gam/__init__.py @@ -25,7 +25,7 @@ https://github.com/taers232c/GAMADV-XTD3/wiki """ __author__ = 'Ross Scroggs ' -__version__ = '7.05.19' +__version__ = '7.05.20' __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)' #pylint: disable=wrong-import-position @@ -1723,6 +1723,16 @@ def getREPattern(flags=0): return validateREPattern(patstr, flags) missingArgumentExit(Cmd.OB_RE_PATTERN) +def getREPatternReplacement(flags=0): + pattern = getREPattern(flags) + replacement = getString(Cmd.OB_STRING, minLen=0) + try: + re.sub(pattern, replacement, '') + return (pattern, replacement) + except re.error as e: + Cmd.Backup() + usageErrorExit(f'{Cmd.OB_RE_REPLACEMENT} {Msg.ERROR}: {e}') + def getSheetEntity(allowBlankSheet): if Cmd.ArgumentsRemaining(): sheet = Cmd.Current() @@ -14521,7 +14531,7 @@ def _getTagReplacement(myarg, tagReplacements, allowSubs): if myarg == 'replace': trregex = None elif myarg == 'replaceregex': - trregex = (getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0)) + trregex = getREPatternReplacement(re.IGNORECASE) else: return False matchTag = getString(Cmd.OB_TAG) @@ -14600,10 +14610,7 @@ def _getTagReplacement(myarg, tagReplacements, allowSubs): if trregex is None: tagReplacements['tags'][matchTag] = {'value': matchReplacement} else: - try: - tagReplacements['tags'][matchTag] = {'value': re.sub(trregex[0], trregex[1], matchReplacement)} - except re.error as e: - systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e))) + tagReplacements['tags'][matchTag] = {'value': re.sub(trregex[0], trregex[1], matchReplacement)} return True def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None): @@ -14688,10 +14695,7 @@ def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None) tag['value'] = _substituteForUser(tag['template'], user, userName) trregex = tag.get('trregex', None) if trregex is not None: - try: - tag['value'] = re.sub(trregex[0], trregex[1], tag['value']) - except re.error as e: - systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e))) + tag['value'] = re.sub(trregex[0], trregex[1], tag['value']) RTL_PATTERN = re.compile(r'(?s){RTL}.*?{/RTL}') RT_PATTERN = re.compile(r'(?s){RT}.*?{/RT}') @@ -38560,7 +38564,7 @@ def _getCalendarEventAttribute(myarg, body, parameters, function): elif myarg == 'description': body['description'] = getStringWithCRsNLs() elif function == 'update' and myarg == 'replacedescription': - parameters['replaceDescription'].append((getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0))) + parameters['replaceDescription'].append(getREPatternReplacement(re.IGNORECASE)) elif myarg == 'location': body['location'] = getString(Cmd.OB_STRING, minLen=0) elif myarg == 'source': @@ -39109,10 +39113,7 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE if 'description' in updateFieldList and 'description' in event: body['description'] = event['description'] for replacement in parameters['replaceDescription']: - try: - body['description'] = re.sub(replacement[0], replacement[1], body['description']) - except re.error as e: - systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e))) + body['description'] = re.sub(replacement[0], replacement[1], body['description']) if 'attendees' in updateFieldList: if not parameters['clearAttendees']: if 'attendees' in event: @@ -52835,7 +52836,7 @@ def getDriveFileAttribute(myarg, body, parameters, updateCmd): elif myarg =='stripnameprefix': parameters[DFA_STRIPNAMEPREFIX] = getString(Cmd.OB_STRING, minLen=0) elif myarg == 'replacefilename': - parameters[DFA_REPLACEFILENAME].append((getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0))) + parameters[DFA_REPLACEFILENAME].append(getREPatternReplacement(re.IGNORECASE)) elif myarg in {'convert', 'ocr'}: deprecatedArgument(myarg) stderrWarningMsg(Msg.USE_MIMETYPE_TO_SPECIFY_GOOGLE_FORMAT) @@ -57380,10 +57381,7 @@ def writeReturnIdLink(returnIdLink, mimeType, result): def processFilenameReplacements(name, replacements): for replacement in replacements: - try: - name = re.sub(replacement[0], replacement[1], name) - except re.error as e: - systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e))) + name = re.sub(replacement[0], replacement[1], name) return name def addTimestampToFilename(parameters, body): @@ -58395,7 +58393,7 @@ def getCopyMoveOptions(myarg, copyMoveOptions): elif myarg =='stripnameprefix': copyMoveOptions['stripNamePrefix'] = getString(Cmd.OB_STRING, minLen=0) elif myarg == 'replacefilename': - copyMoveOptions['replaceFilename'].append((getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0))) + copyMoveOptions['replaceFilename'].append(getREPatternReplacement(re.IGNORECASE)) elif myarg == 'showpermissionmessages': copyMoveOptions['showPermissionMessages'] = getBoolean() elif myarg == 'sendemailifrequired': diff --git a/src/gam/gamlib/glclargs.py b/src/gam/gamlib/glclargs.py index 89ccd9f5..b9a78da3 100644 --- a/src/gam/gamlib/glclargs.py +++ b/src/gam/gamlib/glclargs.py @@ -991,6 +991,7 @@ class GamCLArgs(): OB_RESOURCE_ENTITY = 'ResourceEntity' OB_RESOURCE_ID = 'ResourceID' OB_RE_PATTERN = 'REPattern' + OB_RE_REPLACEMENT = 'REReplacement' OB_ROLE_ASSIGNMENT_ID = 'RoleAssignmentID' OB_ROLE_ITEM = 'RoleItem' OB_ROLE_LIST = 'RoleList' diff --git a/src/gam/gamlib/glmsgs.py b/src/gam/gamlib/glmsgs.py index 292aeb13..7d98994d 100644 --- a/src/gam/gamlib/glmsgs.py +++ b/src/gam/gamlib/glmsgs.py @@ -465,7 +465,6 @@ REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid wi REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create' RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n' REFUSING_TO_DEPROVISION_DEVICES = 'Refusing to deprovision {0} devices because acknowledge_device_touch_requirement not specified.\nDeprovisioning a device means the device will have to be physically wiped and re-enrolled to be managed by your domain again.\nThis requires physical access to the device and is very time consuming to perform for each device.\nPlease add "acknowledge_device_touch_requirement" to the GAM command if you understand this and wish to proceed with the deprovision.\nPlease also be aware that deprovisioning can have an effect on your device license count.\nSee https://support.google.com/chrome/a/answer/3523633 for full details.' -REGEX_REPLACEMENT_ERROR = 'Regular expression replacement string "{0}" error: {1}' REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo ' REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again' REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}'