gam7 7.5.17__tar.gz → 7.5.19__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of gam7 might be problematic. Click here for more details.

Files changed (107) hide show
  1. {gam7-7.5.17 → gam7-7.5.19}/PKG-INFO +1 -1
  2. {gam7-7.5.17 → gam7-7.5.19}/src/GamCommands.txt +73 -39
  3. {gam7-7.5.17 → gam7-7.5.19}/src/GamUpdate.txt +54 -0
  4. {gam7-7.5.17 → gam7-7.5.19}/src/gam/__init__.py +86 -40
  5. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glmsgs.py +1 -0
  6. {gam7-7.5.17 → gam7-7.5.19}/.github/ISSUE_TEMPLATE/aa-question.md +0 -0
  7. {gam7-7.5.17 → gam7-7.5.19}/.github/ISSUE_TEMPLATE/za-bug-report.md +0 -0
  8. {gam7-7.5.17 → gam7-7.5.19}/.github/ISSUE_TEMPLATE/zz-feature-request.md +0 -0
  9. {gam7-7.5.17 → gam7-7.5.19}/.github/ISSUE_TEMPLATE.txt +0 -0
  10. {gam7-7.5.17 → gam7-7.5.19}/.github/actions/creds.tar.xz.gpg +0 -0
  11. {gam7-7.5.17 → gam7-7.5.19}/.github/actions/decrypt.sh +0 -0
  12. {gam7-7.5.17 → gam7-7.5.19}/.github/actions/entitlements.plist +0 -0
  13. {gam7-7.5.17 → gam7-7.5.19}/.github/actions/package_exclusions.txt +0 -0
  14. {gam7-7.5.17 → gam7-7.5.19}/.github/stale.yml +0 -0
  15. {gam7-7.5.17 → gam7-7.5.19}/.github/workflows/build.yml +0 -0
  16. {gam7-7.5.17 → gam7-7.5.19}/.github/workflows/codeql-analysis.yml +0 -0
  17. {gam7-7.5.17 → gam7-7.5.19}/.github/workflows/get-cacerts.yml +0 -0
  18. {gam7-7.5.17 → gam7-7.5.19}/.github/workflows/pypi.yml +0 -0
  19. {gam7-7.5.17 → gam7-7.5.19}/.pre-commit-config.yaml +0 -0
  20. {gam7-7.5.17 → gam7-7.5.19}/LICENSE +0 -0
  21. {gam7-7.5.17 → gam7-7.5.19}/README.md +0 -0
  22. {gam7-7.5.17 → gam7-7.5.19}/pyproject.toml +0 -0
  23. {gam7-7.5.17 → gam7-7.5.19}/src/.gitignore +0 -0
  24. {gam7-7.5.17 → gam7-7.5.19}/src/LICENSE +0 -0
  25. {gam7-7.5.17 → gam7-7.5.19}/src/cacerts.pem +0 -0
  26. {gam7-7.5.17 → gam7-7.5.19}/src/callgam.py +0 -0
  27. {gam7-7.5.17 → gam7-7.5.19}/src/gam/__main__.py +0 -0
  28. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/__init__.py +0 -0
  29. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/auth.py +0 -0
  30. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/client.py +0 -0
  31. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/core.py +0 -0
  32. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/data.py +0 -0
  33. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/http.py +0 -0
  34. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/http_core.py +0 -0
  35. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/http_interface.py +0 -0
  36. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/mock_http.py +0 -0
  37. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/mock_http_core.py +0 -0
  38. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/mock_service.py +0 -0
  39. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/service.py +0 -0
  40. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/token_store.py +0 -0
  41. {gam7-7.5.17 → gam7-7.5.19}/src/gam/atom/url.py +0 -0
  42. {gam7-7.5.17 → gam7-7.5.19}/src/gam/cacerts.pem +0 -0
  43. {gam7-7.5.17 → gam7-7.5.19}/src/gam/cbcm-v1.1beta1.json +0 -0
  44. {gam7-7.5.17 → gam7-7.5.19}/src/gam/contactdelegation-v1.json +0 -0
  45. {gam7-7.5.17 → gam7-7.5.19}/src/gam/datastudio-v1.json +0 -0
  46. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/__init__.py +0 -0
  47. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glaction.py +0 -0
  48. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glapi.py +0 -0
  49. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glcfg.py +0 -0
  50. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glclargs.py +0 -0
  51. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glentity.py +0 -0
  52. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glgapi.py +0 -0
  53. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glgdata.py +0 -0
  54. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glglobals.py +0 -0
  55. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glindent.py +0 -0
  56. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glskus.py +0 -0
  57. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/gluprop.py +0 -0
  58. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/glverlibs.py +0 -0
  59. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gamlib/yubikey.py +0 -0
  60. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/__init__.py +0 -0
  61. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/alt/__init__.py +0 -0
  62. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/alt/app_engine.py +0 -0
  63. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/alt/appengine.py +0 -0
  64. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/__init__.py +0 -0
  65. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/audit/__init__.py +0 -0
  66. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/audit/service.py +0 -0
  67. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/contacts/__init__.py +0 -0
  68. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/contacts/service.py +0 -0
  69. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/apps/service.py +0 -0
  70. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/service.py +0 -0
  71. {gam7-7.5.17 → gam7-7.5.19}/src/gam/gdata/urlfetch.py +0 -0
  72. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/__init__.py +0 -0
  73. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/_auth.py +0 -0
  74. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/_helpers.py +0 -0
  75. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/channel.py +0 -0
  76. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/discovery.py +0 -0
  77. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/discovery_cache/__init__.py +0 -0
  78. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/discovery_cache/appengine_memcache.py +0 -0
  79. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/discovery_cache/base.py +0 -0
  80. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/discovery_cache/file_cache.py +0 -0
  81. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/errors.py +0 -0
  82. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/http.py +0 -0
  83. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/mimeparse.py +0 -0
  84. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/model.py +0 -0
  85. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/schema.py +0 -0
  86. {gam7-7.5.17 → gam7-7.5.19}/src/gam/googleapiclient/version.py +0 -0
  87. {gam7-7.5.17 → gam7-7.5.19}/src/gam/iso8601/__init__.py +0 -0
  88. {gam7-7.5.17 → gam7-7.5.19}/src/gam/iso8601/iso8601.py +0 -0
  89. {gam7-7.5.17 → gam7-7.5.19}/src/gam/meet-v2beta.json +0 -0
  90. {gam7-7.5.17 → gam7-7.5.19}/src/gam/serviceaccountlookup-v1.json +0 -0
  91. {gam7-7.5.17 → gam7-7.5.19}/src/gam/six.py +0 -0
  92. {gam7-7.5.17 → gam7-7.5.19}/src/gam-install.sh +0 -0
  93. {gam7-7.5.17 → gam7-7.5.19}/src/gam-setup.bat +0 -0
  94. {gam7-7.5.17 → gam7-7.5.19}/src/gam.exe.manifest +0 -0
  95. {gam7-7.5.17 → gam7-7.5.19}/src/gam.py +0 -0
  96. {gam7-7.5.17 → gam7-7.5.19}/src/gam.spec +0 -0
  97. {gam7-7.5.17 → gam7-7.5.19}/src/gam.wxs +0 -0
  98. {gam7-7.5.17 → gam7-7.5.19}/src/license.rtf +0 -0
  99. {gam7-7.5.17 → gam7-7.5.19}/src/requirements-dev.txt +0 -0
  100. {gam7-7.5.17 → gam7-7.5.19}/src/requirements.txt +0 -0
  101. {gam7-7.5.17 → gam7-7.5.19}/src/setup.cfg +0 -0
  102. {gam7-7.5.17 → gam7-7.5.19}/src/setup.py +0 -0
  103. {gam7-7.5.17 → gam7-7.5.19}/src/tools/a_atleast_b.py +0 -0
  104. {gam7-7.5.17 → gam7-7.5.19}/src/tools/gen-wix-xml-filelist.py +0 -0
  105. {gam7-7.5.17 → gam7-7.5.19}/src/tools/mkGamRef.py +0 -0
  106. {gam7-7.5.17 → gam7-7.5.19}/src/tools/openssl.props +0 -0
  107. {gam7-7.5.17 → gam7-7.5.19}/src/version_info.txt.in +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gam7
3
- Version: 7.5.17
3
+ Version: 7.5.19
4
4
  Summary: CLI tool to manage Google Workspace
5
5
  Project-URL: Homepage, https://github.com/GAM-team/GAM
6
6
  Project-URL: Issues, https://github.com/GAM-team/GAM/issues
@@ -1276,7 +1276,7 @@ If the pattern {{Section}} appears in <FileName>, it will be replaced with the n
1276
1276
  For redirect csv, the optional arguments must appear in the order shown.
1277
1277
  <Redirect> ::=
1278
1278
  redirect csv <FileName> [multiprocess] [append] [noheader] [charset <Charset>]
1279
- [columndelimiter <Character>] [noescapechar [<Boolean>]] [quotechar <Character>]
1279
+ [columndelimiter <Character>] [quotechar <Character>] [noescapechar [<Boolean>]]
1280
1280
  [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Bopolean>]]
1281
1281
  [todrive <ToDriveAttribute>*] |
1282
1282
  redirect stdout <FileName> [multiprocess] [append] |
@@ -1908,7 +1908,7 @@ gam calendar|calendars <CalendarEntity> modify <CalendarSettings>+
1908
1908
 
1909
1909
  <ChatContent> ::=
1910
1910
  ((text <String>)|
1911
- (textfile <FileName> [charset <CharSet>])|
1911
+ (textfile <FileName> [charset <Charset>])|
1912
1912
  (gdoc <UserGoogleDoc>)|
1913
1913
  (gcsdoc <StorageBucketObjectName>))
1914
1914
 
@@ -3926,6 +3926,10 @@ gam print group-members [todrive <ToDriveAttribute>*]
3926
3926
 
3927
3927
  # Cloud Identity Groups
3928
3928
 
3929
+ <CBCMBrowser> ::= id:cbcm-browser.<DeviceId>
3930
+ <ChromeOSDevice> ::= id:chrome-os-device.<DeviceId>
3931
+ <BrowserDeviceList> ::= "(<CBCMBrowser>|<ChromeOSDevice>)(,(<CBCMBrowser>|<ChromeOSDevice>))*"
3932
+
3929
3933
  <CIGroupFieldsName> ::=
3930
3934
  additionalgroupkeys|
3931
3935
  createtime|
@@ -3955,12 +3959,12 @@ gam update cigroups <GroupEntity> create|add [<GroupRole>]
3955
3959
  [usersonly|groupsonly]
3956
3960
  [notsuspended|suspended] [notarchived|archived]
3957
3961
  [expire|expires <Time>] [preview] [actioncsv]
3958
- <UserTypeEntity>
3962
+ <UserTypeEntity>|<BrowserDeviceList>
3959
3963
  gam update cigroups <GroupEntity> delete|remove [<GroupRole>]
3960
3964
  [usersonly|groupsonly]
3961
3965
  [notsuspended|suspended] [notarchived|archived]
3962
3966
  [preview] [actioncsv]
3963
- <UserTypeEntity>
3967
+ <UserTypeEntity>|<BrowserDeviceList>
3964
3968
  gam update cigroups <GroupEntity> sync [<GroupRole>|ignorerole]
3965
3969
  [usersonly|groupsonly] [addonly|removeonly]
3966
3970
  [notsuspended|suspended] [notarchived|archived]
@@ -4731,8 +4735,10 @@ gam sendemail [recipient|to] <RecipientEntity>
4731
4735
  [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
4732
4736
  [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
4733
4737
  [subject <String>]
4734
- [<MessageContent>] (replace <Tag> <String>)*
4735
- [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
4738
+ [<MessageContent>]
4739
+ (replace <Tag> <String>)*
4740
+ (replaceregex <RegularExpression> <String> <Tag> <String>)*
4741
+ [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
4736
4742
  (embedimage <FileName> <String>)*
4737
4743
  [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
4738
4744
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
@@ -4740,8 +4746,10 @@ gam <UserTypeEntity> sendemail recipient|to <RecipientEntity>
4740
4746
  [replyto <EmailAddress>]
4741
4747
  [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
4742
4748
  [subject <String>]
4743
- [<MessageContent>] (replace <Tag> <String>)*
4744
- [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
4749
+ [<MessageContent>]
4750
+ (replace <Tag> <String>)*
4751
+ (replaceregex <RegularExpression> <String> <Tag> <String>)*
4752
+ [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
4745
4753
  (embedimage <FileName> <String>)*
4746
4754
  [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
4747
4755
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
@@ -4749,8 +4757,10 @@ gam <UserTypeEntity> sendemail from <EmailAddress>
4749
4757
  [replyto <EmailAddress>]
4750
4758
  [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
4751
4759
  [subject <String>]
4752
- [<MessageContent>] (replace <Tag> <String>)*
4753
- [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
4760
+ [<MessageContent>]
4761
+ (replace <Tag> <String>)*
4762
+ (replaceregex <RegularExpression> <String> <Tag> <String>)*
4763
+ [html [<Boolean>]] (attach <FileName> [charset <Charset>])*
4754
4764
  (embedimage <FileName> <String>)*
4755
4765
  [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
4756
4766
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
@@ -5556,7 +5566,9 @@ gam create|add user <EmailAddress> [ignorenullpassword] <UserAttribute>*
5556
5566
  [mailbox <EmailAaddress>]
5557
5567
  [replyto <EmailAaddress>]
5558
5568
  [<NotifyMessageContent>]
5559
- (replace <Tag> <UserReplacement>)*]
5569
+ (replace <Tag> <UserReplacement>)*
5570
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
5571
+ ]
5560
5572
  [logpassword <FileName>]
5561
5573
  [addnumericsuffixonduplicate <Number>]
5562
5574
 
@@ -5565,7 +5577,7 @@ gam <UserTypeEntity> waitformailbox [retries <Number>]
5565
5577
  gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
5566
5578
  [verifynotinvitable|alwaysevict] [noactionifalias]
5567
5579
  [updateprimaryemail <RegularExpression> <EmailReplacement>]
5568
- [updateoufromgroup <FileName> [charset <CharSet>]
5580
+ [updateoufromgroup <FileName> [charset <Charset>]
5569
5581
  [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
5570
5582
  [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
5571
5583
  [immutableous <OrgUnitEntity>]|
@@ -5577,10 +5589,12 @@ gam update user <UserItem> [ignorenullpassword] <UserAttribute>*
5577
5589
  [subject <String>]
5578
5590
  [notifypassword <String>]
5579
5591
  [from <EmailAaddress>]
5580
- [mailbox <EmailAaddress>]
5581
- [replyto <EmailAaddress>]
5592
+ [mailbox <EmailAddress>]
5593
+ [replyto <EmailAddress>]
5582
5594
  [<NotifyMessageContent>]
5583
- (replace <Tag> <UserReplacement>)*]
5595
+ (replace <Tag> <UserReplacement>)*
5596
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
5597
+ ]
5584
5598
  [notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
5585
5599
  [logpassword <FileName>]
5586
5600
  gam delete user <UserItem> [noactionifalias]
@@ -5599,9 +5613,9 @@ gam info user [<UserItem>]
5599
5613
  [formatjson]
5600
5614
 
5601
5615
  gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
5602
- [verifynotinvitable] [noactionifalias]
5616
+ [verifynotinvitable|alwaysevict] [noactionifalias]
5603
5617
  [updateprimaryemail <RegularExpression> <EmailReplacement>]
5604
- [updateoufromgroup <FileName> [charset <CharSet>]
5618
+ [updateoufromgroup <FileName> [charset <Charset>]
5605
5619
  [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
5606
5620
  [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
5607
5621
  [clearschema <SchemaName>|<SchemaNameField>]
@@ -5611,13 +5625,15 @@ gam update users <UserTypeEntity> [ignorenullpassword] <UserAttribute>*
5611
5625
  [notify <EmailAddressList>
5612
5626
  [subject <String>]
5613
5627
  [notifypassword <String>]
5614
- [from <EmailAaddress>]
5615
- [mailbox <EmailAaddress>]
5628
+ [from <EmailAddress>]
5629
+ [mailbox <EmailAddress>]
5630
+ [replyto <EmailAaddress>]
5616
5631
  [<NotifyMessageContent>]
5617
- (replace <Tag> <UserReplacement>)*]
5632
+ (replace <Tag> <UserReplacement>)*
5633
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
5634
+ ]
5618
5635
  [notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
5619
5636
  [logpassword <FileName>]
5620
- [verifynotinvitable]
5621
5637
  gam delete users <UserTypeEntity> [noactionifalias]
5622
5638
  gam undelete users <UserEntity> [ou|org|orgunit <OrgUnitPath>]
5623
5639
  gam suspend users <UserTypeEntity> [noactionifalias]
@@ -5634,9 +5650,11 @@ gam info users <UserTypeEntity>
5634
5650
  [formatjson]
5635
5651
 
5636
5652
  gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
5637
- [verifynotinvitable] [noactionifalias]
5653
+ [verifynotinvitable|alwaysevict] [noactionifalias]
5638
5654
  [updateprimaryemail <RegularExpression> <EmailReplacement>]
5639
- [updateoufromgroup <CSVFileInput> [keyfield <FieldName>] [datafield <FieldName>]]
5655
+ [updateoufromgroup <FileName> [charset <Charset>]
5656
+ [columndelimiter <Character>] [noescapechar <Boolean>] [quotechar <Character>]
5657
+ [fields <FieldNameList>] [keyfield <FieldName>] [datafield <FieldName>]]
5640
5658
  [clearschema <SchemaName>|<SchemaNameField>]
5641
5659
  [createifnotfound] [notfoundpassword (random [<Integer>])|blocklogin|<Password>]
5642
5660
  (groups [<GroupRole>] [[delivery] <DeliverySetting>] <GroupEntity>)*
@@ -5645,12 +5663,14 @@ gam <UserTypeEntity> update users [ignorenullpassword] <UserAttribute>*
5645
5663
  [subject <String>]
5646
5664
  [notifypassword <String>]
5647
5665
  [from <EmailAaddress>]
5648
- [mailbox <EmailAaddress>]
5666
+ [mailbox <EmailAddress>]
5667
+ [replyto <EmailAddress>]
5649
5668
  [<NotifyMessageContent>]
5650
- (replace <Tag> <UserReplacement>)*]
5669
+ (replace <Tag> <UserReplacement>)*
5670
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
5671
+ ]
5651
5672
  [notifyonupdate [<Boolean>]] [setchangepasswordoncreate [<Boolean>]]
5652
5673
  [logpassword <FileName>]
5653
- [verifynotinvitable]
5654
5674
  gam <UserTypeEntity> delete users [noactionifalias]
5655
5675
  gam <UserEntity> undelete users [ou|org|orgunit <OrgUnitPath>]
5656
5676
  gam <UserTypeEntity> suspend users [noactionifalias]
@@ -6161,7 +6181,7 @@ gam <UserTypeEntity> print focustime|outofoffice|workinglocation
6161
6181
 
6162
6182
  <ChatContent> ::=
6163
6183
  ((text <String>)|
6164
- (textfile <FileName> [charset <CharSet>])|
6184
+ (textfile <FileName> [charset <Charset>])|
6165
6185
  (gdoc <UserGoogleDoc>)|
6166
6186
  (gcsdoc <StorageBucketObjectName>))
6167
6187
 
@@ -6523,7 +6543,7 @@ gam <UserTypeEntity> update drivefile <DriveFileEntity> [copy] [returnidonly|ret
6523
6543
  [timestamp [<Boolean>]] [timeformat <String>]
6524
6544
  <DriveFileUpdateAttribute>*
6525
6545
  [(gsheet|csvsheet <SheetEntity> [clearfilter])|(addsheet <String>)]
6526
- [charset <CharSet>] [columndelimiter <Character>]
6546
+ [charset <Charset>] [columndelimiter <Character>]
6527
6547
 
6528
6548
  <DriveFileCopyAttribute> ::=
6529
6549
  (contentrestrictions (readonly false)|(readonly true [reason <String>]) [ownerrestricted [<Boolean>]])|
@@ -7528,22 +7548,28 @@ gam <UserTypeEntity> print labels|label [todrive <ToDriveAttribute>*]
7528
7548
  (emlfile <FileName> [charset <Charset>])
7529
7549
 
7530
7550
  gam <UserTypeEntity> draft message
7531
- <MessageContent> (replace <Tag> <UserReplacement>)*
7551
+ <MessageContent>
7552
+ (replace <Tag> <UserReplacement>)*
7553
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
7532
7554
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
7533
- (attach <FileName> [charset <CharSet>])*
7555
+ (attach <FileName> [charset <Charset>])*
7534
7556
  (embedimage <FileName> <String>)*
7535
7557
  gam <UserTypeEntity> import message
7536
- <MessageContent> (replace <Tag> <UserReplacement>)*
7558
+ <MessageContent>
7559
+ (replace <Tag> <UserReplacement>)*
7560
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
7537
7561
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
7538
7562
  (addlabel <LabelName>)* [labels <LabelNameList>]
7539
- (attach <FileName> [charset <CharSet>])*
7563
+ (attach <FileName> [charset <Charset>])*
7540
7564
  (embedimage <FileName> <String>)*
7541
7565
  [deleted [<Boolean>]] [checkspam|nevermarkspam [<Boolean>]] [processforcalendar [<Boolean>]]
7542
7566
  gam <UserTypeEntity> insert message
7543
- <MessageContent> (replace <Tag> <UserReplacement>)*
7567
+ <MessageContent>
7568
+ (replace <Tag> <UserReplacement>)*
7569
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
7544
7570
  (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
7545
7571
  (addlabel <LabelName>)* [labels <LabelNameList>]
7546
- (attach <FileName> [charset <CharSet>])*
7572
+ (attach <FileName> [charset <Charset>])*
7547
7573
  (embedimage <FileName> <String>)*
7548
7574
  [deleted [<Boolean>]]
7549
7575
 
@@ -7622,13 +7648,17 @@ gam <UserTypeEntity> print gmailprofile [todrive <ToDriveAttribute>*]
7622
7648
  # Users - Gmail - Send As/Signature/Vacation
7623
7649
 
7624
7650
  gam <UserTypeEntity> [create|add] sendas <EmailAddress> [name] <String>
7625
- [<SendAsContent> (replace <Tag> <UserReplacement>)*]
7651
+ [<SendAsContent>
7652
+ (replace <Tag> <UserReplacement>)*
7653
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
7626
7654
  [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
7627
7655
  [smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
7628
7656
  smtpmsa.username <UserName> smtpmsa.password <Password>
7629
7657
  [smtpmsa.securitymode none|ssl|starttls]]
7630
7658
  gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
7631
- [<SendAsContent> (replace <Tag> <UserReplacement>)*]
7659
+ [<SendAsContent>
7660
+ (replace <Tag> <UserReplacement>)*
7661
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
7632
7662
  [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
7633
7663
  gam <UserTypeEntity> delete sendas <EmailAddressEntity>
7634
7664
  gam <UserTypeEntity> info sendas <EmailAddressEntity> [compact|format|html]
@@ -7638,7 +7668,9 @@ gam <UserTypeEntity> print sendas [compact]
7638
7668
  [primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
7639
7669
 
7640
7670
  gam <UserTypeEntity> signature|sig
7641
- <SignatureContent> (replace <Tag> <UserReplacement>)*
7671
+ <SignatureContent>
7672
+ (replace <Tag> <UserReplacement>)*
7673
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
7642
7674
  [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
7643
7675
  [name <String>]
7644
7676
  [primary]
@@ -7648,7 +7680,9 @@ gam <UserTypeEntity> print signature [compact]
7648
7680
  [primary|default] [verifyonly] [todrive <ToDriveAttribute>*]
7649
7681
 
7650
7682
  gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
7651
- [<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
7683
+ [<VacationMessageContent>
7684
+ (replace <Tag> <UserReplacement>)*
7685
+ (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
7652
7686
  [html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
7653
7687
  [start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
7654
7688
  gam <UserTypeEntity> show vacation [compact|format|html] [enabledonly]
@@ -7775,7 +7809,7 @@ gam <UserTypeEntity> check isinvitable [todrive <ToDriveAttribute>*]
7775
7809
 
7776
7810
  <NoteContent> ::=
7777
7811
  ((text <String>)|
7778
- (textfile <FileName> [charset <CharSet>])|
7812
+ (textfile <FileName> [charset <Charset>])|
7779
7813
  (gdoc <UserGoogleDoc>)|
7780
7814
  (gcsdoc <StorageBucketObjectName>)|
7781
7815
  <JSONData>)
@@ -1,3 +1,57 @@
1
+ 7.05.19
2
+
3
+ Added `replaceregex <RegularExpression> <ReplacementString> <Tag> <String>` to the following commands:
4
+ ```
5
+ gam sendemail subject <String> <MessageContent>
6
+ gam <UserTypeEntity> sendemail subject <String> <MessageContent>
7
+ ```
8
+
9
+ The `<RegularExpression>` is used as a match pattern against `<String>` to produce `<ReplacementString>`.
10
+ Instances of `{Tag}` will be replaced by `<ReplacementString>` in the message subject and body.
11
+
12
+ Added `replaceregex <RegularExpression> <ReplacementString> <Tag> <UserReplacement>` to the following commands:
13
+ ```
14
+ gam create user <NotifyMessageContent>
15
+ gam update user <NotifyMessageContent>
16
+ gam update users <NotifyMessageContent>
17
+ gam <UserTypeEntity> update users <NotifyMessageContent>
18
+ gam <UserTypeEntity> draft message <MessageContent>
19
+ gam <UserTypeEntity> import message <MessageContent>
20
+ gam <UserTypeEntity> insert messageo <MessageContent>
21
+ gam <UserTypeEntity> create sendas <SendAsContent>
22
+ gam <UserTypeEntity> update sendas <SendAsContent>
23
+ gam <UserTypeEntity> signature <SignatureContent>
24
+ gam <UserTypeEntity> vacation subject <String> <VacationMessageContent>
25
+ ```
26
+
27
+ The `<RegularExpression>` is used as a match pattern against `<UserReplacement>` to produce `<ReplacementString>`.
28
+ Instances of `{Tag}` will be replaced by `<ReplacementString>` in the indicated items.
29
+
30
+ For example, when adding a phone number to a signature, an unformatted number can be formatted:
31
+ ```
32
+ replaceregex "(\d{3})(\d{3})(\d{4})" "(\1) \2-\3" Phone "9876543210"
33
+ replaces 9876543210 with (987) 654-3210
34
+
35
+ replaceregex "(\+\d{2})(\d{3})(\d{3})(\d{3})" "\1 \2 \3 \4" Phone "+61987654321"
36
+ replaces +61421221506 with +61 987 654 321
37
+ ```
38
+
39
+ 7.05.18
40
+
41
+ Updated `gam calendars <CalendarEntity> show events` and `gam <UserTypeEntity> show events`
42
+ to display the event description according to `show_convert_cr_nl` in `gam.cfg`;
43
+ previously, GAM assumed `show_convert_cr_nl = true`.
44
+ ```
45
+ show_convert_cr_nl = false
46
+ description:
47
+ Line 1
48
+ Line 2
49
+ Line 3
50
+
51
+ show_convert_cr_nl = true
52
+ description: Line 1\nLine 2\nLine 3\n
53
+ ```
54
+
1
55
  7.05.17
2
56
 
3
57
  Updated commands that delete drive ACLs to handle the following error:
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
25
25
  """
26
26
 
27
27
  __author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
28
- __version__ = '7.05.17'
28
+ __version__ = '7.05.19'
29
29
  __license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
30
30
 
31
31
  #pylint: disable=wrong-import-position
@@ -4088,13 +4088,8 @@ def SetGlobalVariables():
4088
4088
  GC.Values[GC.OUTPUT_DATEFORMAT] = GM.Globals[GM.OUTPUT_DATEFORMAT]
4089
4089
  if not GC.Values[GC.OUTPUT_TIMEFORMAT]:
4090
4090
  GC.Values[GC.OUTPUT_TIMEFORMAT] = GM.Globals[GM.OUTPUT_TIMEFORMAT]
4091
- # Create/set mode for oauth2.txt.lock
4092
- if not GM.Globals[GM.OAUTH2_TXT_LOCK]:
4093
- fileName = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
4094
- if not os.path.isfile(fileName):
4095
- closeFile(openFile(fileName, mode=DEFAULT_FILE_APPEND_MODE))
4096
- os.chmod(fileName, 0o666)
4097
- GM.Globals[GM.OAUTH2_TXT_LOCK] = fileName
4091
+ # Define lockfile: oauth2.txt.lock
4092
+ GM.Globals[GM.OAUTH2_TXT_LOCK] = f'{GC.Values[GC.OAUTH2_TXT]}.lock'
4098
4093
  # Override httplib2 settings
4099
4094
  httplib2.debuglevel = GC.Values[GC.DEBUG_LEVEL]
4100
4095
  # Reset global variables if required
@@ -4113,7 +4108,7 @@ def SetGlobalVariables():
4113
4108
  if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
4114
4109
  _setMultiprocessExit()
4115
4110
  # redirect csv <FileName> [multiprocess] [append] [noheader] [charset <CharSet>]
4116
- # [columndelimiter <Character>] [noescapechar [<Boolean>]] [quotechar <Character>]]
4111
+ # [columndelimiter <Character>] [quotechar <Character>]] [noescapechar [<Boolean>]]
4117
4112
  # [sortheaders <StringList>] [timestampcolumn <String>] [transpose [<Boolean>]]
4118
4113
  # [todrive <ToDriveAttribute>*]
4119
4114
  # redirect stdout <FileName> [multiprocess] [append]
@@ -14522,7 +14517,13 @@ def _initTagReplacements():
14522
14517
  'fieldsSet': set(), 'fields': '',
14523
14518
  'schemasSet': set(), 'customFieldMask': None}
14524
14519
 
14525
- def _getTagReplacement(tagReplacements, allowSubs):
14520
+ def _getTagReplacement(myarg, tagReplacements, allowSubs):
14521
+ if myarg == 'replace':
14522
+ trregex = None
14523
+ elif myarg == 'replaceregex':
14524
+ trregex = (getREPattern(re.IGNORECASE), getString(Cmd.OB_STRING, minLen=0))
14525
+ else:
14526
+ return False
14526
14527
  matchTag = getString(Cmd.OB_TAG)
14527
14528
  matchReplacement = getString(Cmd.OB_STRING, minLen=0)
14528
14529
  if matchReplacement.startswith('field:'):
@@ -14567,7 +14568,8 @@ def _getTagReplacement(tagReplacements, allowSubs):
14567
14568
  tagReplacements['fieldsSet'].add(field)
14568
14569
  tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
14569
14570
  tagReplacements['tags'][matchTag] = {'field': field, 'subfield': subfield,
14570
- 'matchfield': matchfield, 'matchvalue': matchvalue, 'value': ''}
14571
+ 'matchfield': matchfield, 'matchvalue': matchvalue, 'value': '',
14572
+ 'trregex': trregex}
14571
14573
  if field == 'locations' and subfield == 'buildingName':
14572
14574
  _makeBuildingIdNameMap()
14573
14575
  elif matchReplacement.startswith('schema:'):
@@ -14585,15 +14587,24 @@ def _getTagReplacement(tagReplacements, allowSubs):
14585
14587
  tagReplacements['fields'] = ','.join(tagReplacements['fieldsSet'])
14586
14588
  tagReplacements['schemasSet'].add(schemaName)
14587
14589
  tagReplacements['customFieldMask'] = ','.join(tagReplacements['schemasSet'])
14588
- tagReplacements['tags'][matchTag] = {'schema': schemaName, 'schemafield': schemaField, 'value': ''}
14590
+ tagReplacements['tags'][matchTag] = {'schema': schemaName, 'schemafield': schemaField, 'value': '',
14591
+ 'trregex': trregex}
14589
14592
  elif ((matchReplacement.find('#') >= 0) and
14590
14593
  (matchReplacement.find('#user#') >= 0) or (matchReplacement.find('#email#') >= 0) or (matchReplacement.find('#username#') >= 0)):
14591
14594
  if not allowSubs:
14592
14595
  usageErrorExit(Msg.USER_SUBS_NOT_ALLOWED_TAG_REPLACEMENT)
14593
14596
  tagReplacements['subs'] = True
14594
- tagReplacements['tags'][matchTag] = {'template': matchReplacement, 'value': ''}
14597
+ tagReplacements['tags'][matchTag] = {'template': matchReplacement, 'value': '',
14598
+ 'trregex': trregex}
14595
14599
  else:
14596
- tagReplacements['tags'][matchTag] = {'value': matchReplacement}
14600
+ if trregex is None:
14601
+ tagReplacements['tags'][matchTag] = {'value': matchReplacement}
14602
+ else:
14603
+ try:
14604
+ tagReplacements['tags'][matchTag] = {'value': re.sub(trregex[0], trregex[1], matchReplacement)}
14605
+ except re.error as e:
14606
+ systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e)))
14607
+ return True
14597
14608
 
14598
14609
  def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None):
14599
14610
  if results is None:
@@ -14675,6 +14686,12 @@ def _getTagReplacementFieldValues(user, i, count, tagReplacements, results=None)
14675
14686
  tag['value'] = str(results.get('customSchemas', {}).get(tag['schema'], {}).get(tag['schemafield'], ''))
14676
14687
  elif tag.get('template'):
14677
14688
  tag['value'] = _substituteForUser(tag['template'], user, userName)
14689
+ trregex = tag.get('trregex', None)
14690
+ if trregex is not None:
14691
+ try:
14692
+ tag['value'] = re.sub(trregex[0], trregex[1], tag['value'])
14693
+ except re.error as e:
14694
+ systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(trregex[1], str(e)))
14678
14695
 
14679
14696
  RTL_PATTERN = re.compile(r'(?s){RTL}.*?{/RTL}')
14680
14697
  RT_PATTERN = re.compile(r'(?s){RT}.*?{/RT}')
@@ -14927,7 +14944,9 @@ def getRecipients():
14927
14944
  # gam sendemail [recipient|to] <RecipientEntity> [from <EmailAddress>] [mailbox <EmailAddress>] [replyto <EmailAddress>]
14928
14945
  # [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
14929
14946
  # [subject <String>]
14930
- # [<MessageContent>] (replace <Tag> <String>)*
14947
+ # [<MessageContent>]
14948
+ # (replace <Tag> <String>)*
14949
+ # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14931
14950
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14932
14951
  # (embedimage <FileName> <String>)*
14933
14952
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -14935,7 +14954,9 @@ def getRecipients():
14935
14954
  # gam <UserTypeEntity> sendemail recipient <RecipientEntity> [replyto <EmailAddress>]
14936
14955
  # [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
14937
14956
  # [subject <String>]
14938
- # [<MessageContent>] (replace <Tag> <String>)*
14957
+ # [<MessageContent>]
14958
+ # (replace <Tag> <String>)*
14959
+ # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14939
14960
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14940
14961
  # (embedimage <FileName> <String>)*
14941
14962
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -14943,7 +14964,9 @@ def getRecipients():
14943
14964
  # gam <UserTypeEntity> sendemail from <EmailAddress> [replyto <EmailAddress>]
14944
14965
  # [cc <RecipientEntity>] [bcc <RecipientEntity>] [singlemessage]
14945
14966
  # [subject <String>]
14946
- # [<MessageContent>] (replace <Tag> <String>)*
14967
+ # [<MessageContent>]
14968
+ # (replace <Tag> <String>)*
14969
+ # (replaceregex <RegularExpression> <String> <Tag> <String>)*
14947
14970
  # [html [<Boolean>]] (attach <FileName> [charset <CharSet>])*
14948
14971
  # (embedimage <FileName> <String>)*
14949
14972
  # [newuser <EmailAddress> firstname|givenname <String> lastname|familyname <string> password <Password>]
@@ -15006,8 +15029,8 @@ def doSendEmail(users=None):
15006
15029
  body['name']['familyName'] = getString(Cmd.OB_STRING, minLen=0, maxLen=60)
15007
15030
  elif myarg in {'password', 'notifypassword'}:
15008
15031
  body['password'] = notify['password'] = getString(Cmd.OB_PASSWORD, maxLen=100)
15009
- elif myarg == 'replace':
15010
- _getTagReplacement(tagReplacements, False)
15032
+ elif _getTagReplacement(myarg, tagReplacements, False):
15033
+ pass
15011
15034
  elif myarg == 'attach':
15012
15035
  attachments.append((getFilename(), getCharSet()))
15013
15036
  elif myarg == 'embedimage':
@@ -39086,7 +39109,10 @@ def _updateCalendarEvents(origUser, user, origCal, calIds, count, calendarEventE
39086
39109
  if 'description' in updateFieldList and 'description' in event:
39087
39110
  body['description'] = event['description']
39088
39111
  for replacement in parameters['replaceDescription']:
39089
- body['description'] = re.sub(replacement[0], replacement[1], body['description'])
39112
+ try:
39113
+ body['description'] = re.sub(replacement[0], replacement[1], body['description'])
39114
+ except re.error as e:
39115
+ systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e)))
39090
39116
  if 'attendees' in updateFieldList:
39091
39117
  if not parameters['clearAttendees']:
39092
39118
  if 'attendees' in event:
@@ -39410,7 +39436,10 @@ def _showCalendarEvent(primaryEmail, calId, eventEntityType, event, k, kcount, F
39410
39436
  Ind.Increment()
39411
39437
  for field in EVENT_SHOW_ORDER:
39412
39438
  if field in event:
39413
- showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
39439
+ if field != 'description':
39440
+ showJSON(field, event[field], skipObjects, EVENT_TIME_OBJECTS)
39441
+ else:
39442
+ printKeyValueWithCRsNLs(field, event[field])
39414
39443
  skipObjects.add(field)
39415
39444
  showJSON(None, event, skipObjects)
39416
39445
  Ind.Decrement()
@@ -42837,8 +42866,8 @@ def getUserAttributes(cd, updateCmd, noUid=False):
42837
42866
  notify['mailbox'] = getString(Cmd.OB_EMAIL_ADDRESS)
42838
42867
  elif PwdOpts.ProcessArgument(myarg, notify, notFoundBody):
42839
42868
  pass
42840
- elif myarg == 'replace':
42841
- _getTagReplacement(tagReplacements, True)
42869
+ elif _getTagReplacement(myarg, tagReplacements, True):
42870
+ pass
42842
42871
  elif myarg == 'admin':
42843
42872
  value = getBoolean()
42844
42873
  if updateCmd or value:
@@ -43255,9 +43284,9 @@ def createUserAddAliases(cd, user, aliasList, i, count):
43255
43284
  # [from <EmailAaddress>]
43256
43285
  # [replyto <EmailAaddress>]
43257
43286
  # [<NotifyMessageContent>]
43258
- # (replace <Tag> <UserReplacement>)*]
43287
+ # (replace <Tag> <UserReplacement>)*
43288
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
43259
43289
  # [logpassword <FileName>] [ignorenullpassword]
43260
- # [verifynotinvitable]
43261
43290
  # [addnumericsuffixonduplicate <Number>]
43262
43291
  def doCreateUser():
43263
43292
  cd = buildGAPIObject(API.DIRECTORY)
@@ -43356,8 +43385,9 @@ def verifyUserPrimaryEmail(cd, user, createIfNotFound, i, count):
43356
43385
  # [notifypassword <String>]
43357
43386
  # [from <EmailAaddress>]
43358
43387
  # [replyto <EmailAaddress>]
43359
- # [<NotifyMessageContent>]
43360
- # (replace <Tag> <UserReplacement>)*]
43388
+ # [<NotifyMessageContent>
43389
+ # (replace <Tag> <UserReplacement>)*
43390
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
43361
43391
  # [notifyonupdate [<Boolean>]]
43362
43392
  # [logpassword <FileName>] [ignorenullpassword]
43363
43393
  def updateUsers(entityList):
@@ -57350,7 +57380,10 @@ def writeReturnIdLink(returnIdLink, mimeType, result):
57350
57380
 
57351
57381
  def processFilenameReplacements(name, replacements):
57352
57382
  for replacement in replacements:
57353
- name = re.sub(replacement[0], replacement[1], name)
57383
+ try:
57384
+ name = re.sub(replacement[0], replacement[1], name)
57385
+ except re.error as e:
57386
+ systemErrorExit(ACTION_FAILED_RC, Msg.REGEX_REPLACEMENT_ERROR.format(replacement[1], str(e)))
57354
57387
  return name
57355
57388
 
57356
57389
  def addTimestampToFilename(parameters, body):
@@ -69993,8 +70026,8 @@ def _draftImportInsertMessage(users, operation):
69993
70026
  internalDateSource = 'dateHeader'
69994
70027
  if checkArgumentPresent('emlutf8'):
69995
70028
  emlEncoding = UTF8
69996
- elif myarg == 'replace':
69997
- _getTagReplacement(tagReplacements, True)
70029
+ elif _getTagReplacement(myarg, tagReplacements, True):
70030
+ pass
69998
70031
  elif operation in IMPORT_INSERT and myarg == 'addlabel':
69999
70032
  addLabelNames.append(getString(Cmd.OB_LABEL_NAME, minLen=1))
70000
70033
  elif operation in IMPORT_INSERT and myarg == 'labels':
@@ -70129,7 +70162,9 @@ def _draftImportInsertMessage(users, operation):
70129
70162
  userGmailServiceNotEnabledWarning(user, i, count)
70130
70163
 
70131
70164
  # gam <UserTypeEntity> draft message
70132
- # <MessageContent> (replace <Tag> <UserReplacement>)*
70165
+ # <MessageContent>
70166
+ # (replace <Tag> <UserReplacement>)*
70167
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70133
70168
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70134
70169
  # (attach <FileName> [charset <CharSet>])*
70135
70170
  # (embedimage <FileName> <String>)*
@@ -70137,7 +70172,9 @@ def draftMessage(users):
70137
70172
  _draftImportInsertMessage(users, 'draft')
70138
70173
 
70139
70174
  # gam <UserTypeEntity> import message
70140
- # <MessageContent> (replace <Tag> <UserReplacement>)*
70175
+ # <MessageContent>
70176
+ # (replace <Tag> <UserReplacement>)*
70177
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70141
70178
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70142
70179
  # (addlabel <LabelName>)* [labels <LabelNameList>]
70143
70180
  # (attach <FileName> [charset <CharSet>])*
@@ -70147,7 +70184,9 @@ def importMessage(users):
70147
70184
  _draftImportInsertMessage(users, 'import')
70148
70185
 
70149
70186
  # gam <UserTypeEntity> insert message
70150
- # <MessageContent> (replace <Tag> <UserReplacement>)*
70187
+ # <MessageContent>
70188
+ # (replace <Tag> <UserReplacement>)*
70189
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*
70151
70190
  # (<SMTPDateHeader> <Time>)* (<SMTPHeader> <String>)* (header <String> <String>)*
70152
70191
  # (addlabel <LabelName>)* [labels <LabelNameList>]
70153
70192
  # (attach <FileName> [charset <CharSet>])*
@@ -72434,8 +72473,8 @@ def _processSendAs(user, i, count, entityType, emailAddress, j, jcount, gmail, f
72434
72473
  return userDefined
72435
72474
 
72436
72475
  def getSendAsAttributes(myarg, body, tagReplacements):
72437
- if myarg == 'replace':
72438
- _getTagReplacement(tagReplacements, True)
72476
+ if _getTagReplacement(myarg, tagReplacements, True):
72477
+ pass
72439
72478
  elif myarg == 'name':
72440
72479
  body['displayName'] = getString(Cmd.OB_NAME, minLen=0)
72441
72480
  elif myarg == 'replyto':
@@ -72454,13 +72493,17 @@ SMTPMSA_SECURITY_MODES = ['none', 'ssl', 'starttls']
72454
72493
  SMTPMSA_REQUIRED_FIELDS = ['host', 'port', 'username', 'password']
72455
72494
 
72456
72495
  # gam <UserTypeEntity> [create] sendas <EmailAddress> [name] <String>
72457
- # [<SendAsContent> (replace <Tag> <UserReplacement>)*]
72496
+ # [<SendAsContent>
72497
+ # (replace <Tag> <UserReplacement>)*
72498
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
72458
72499
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
72459
72500
  # [smtpmsa.host <SMTPHostName> smtpmsa.port 25|465|587
72460
72501
  # smtpmsa.username <UserName> smtpmsa.password <Password>
72461
72502
  # [smtpmsa.securitymode none|ssl|starttls]]
72462
72503
  # gam <UserTypeEntity> update sendas <EmailAddress> [name <String>]
72463
- # [<SendAsContent> (replace <Tag> <UserReplacement>)*]
72504
+ # [<SendAsContent>
72505
+ # (replace <Tag> <UserReplacement>)*
72506
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
72464
72507
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
72465
72508
  def createUpdateSendAs(users):
72466
72509
  updateCmd = Act.Get() == Act.UPDATE
@@ -73297,6 +73340,7 @@ def printShowCSEKeyPairs(users):
73297
73340
  # gam <UserTypeEntity> signature|sig
73298
73341
  # <SignatureContent>
73299
73342
  # (replace <Tag> <String>)*
73343
+ # (replaceregex <RegularExpression> <String> <Tag> <String>)*
73300
73344
  # [html [<Boolean>]] [replyto <EmailAddress>] [default] [treatasalias <Boolean>]
73301
73345
  # [name <String>]
73302
73346
  # [primary]
@@ -73390,7 +73434,9 @@ def _showVacation(user, i, count, result, showDisabled, sigReplyFormat):
73390
73434
  Ind.Decrement()
73391
73435
 
73392
73436
  # gam <UserTypeEntity> vacation [<Boolean>] [subject <String>]
73393
- # [<VacationMessageContent> (replace <Tag> <UserReplacement>)*]
73437
+ # [<VacationMessageContent>
73438
+ # (replace <Tag> <UserReplacement>)*
73439
+ # (replaceregex <RegularExpression> <String> <Tag> <UserReplacement>)*]
73394
73440
  # [html [<Boolean>]] [contactsonly [<Boolean>]] [domainonly [<Boolean>]]
73395
73441
  # [start|startdate <Date>|Started] [end|enddate <Date>|NotSpecified]
73396
73442
  def setVacation(users):
@@ -73408,8 +73454,8 @@ def setVacation(users):
73408
73454
  message, _, html = getStringOrFile(myarg)
73409
73455
  if html:
73410
73456
  responseBodyType = 'responseBodyHtml'
73411
- elif myarg == 'replace':
73412
- _getTagReplacement(tagReplacements, True)
73457
+ elif _getTagReplacement(myarg, tagReplacements, True):
73458
+ pass
73413
73459
  elif myarg == 'html':
73414
73460
  if getBoolean():
73415
73461
  responseBodyType = 'responseBodyHtml'
@@ -465,6 +465,7 @@ REASON_ONLY_VALID_WITH_CONTENTRESTRICTIONS_READONLY_TRUE = 'reason only valid wi
465
465
  REAUTHENTICATION_IS_NEEDED = 'Reauthentication is needed, please run\n\ngam oauth create'
466
466
  RECOMMEND_RUNNING_GAM_ROTATE_SAKEY = 'Recommend running "gam rotate sakey" to get a new key\n'
467
467
  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.'
468
+ REGEX_REPLACEMENT_ERROR = 'Regular expression replacement string "{0}" error: {1}'
468
469
  REPLY_TO_CUSTOM_REQUIRES_EMAIL_ADDRESS = 'replyto REPLY_TO_CUSTOM requires customReplyTo <EmailAddress>'
469
470
  REQUEST_COMPLETED_NO_FILES = 'Request completed but no results/files were returned, try requesting again'
470
471
  REQUEST_NOT_COMPLETE = 'Request needs to be completed before downloading, current status is: {0}'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes