Compare commits

..

22 Commits

Author SHA1 Message Date
Jay Lee
b7a20ceb4f actions: fix typo in create printer 2024-09-17 19:15:08 -04:00
Jay Lee
bbc965d38f [no ci] fix build status badge 2024-09-17 19:11:50 -04:00
Jay Lee
8935cf7041 actions: give zip file for notarization a name we can track
Some checks are pending
Build and test GAM / build (Win64, build, 9, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, [self-hosted linux arm64]) (push) Waiting to run
Build and test GAM / build (aarch64, build, 5, linux-aarch64, [self-hosted linux arm64], yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 7, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-20.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 4, linux-x86_64, ubuntu-20.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 6, darwin64-x86_64, macos-12) (push) Waiting to run
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.8) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.9) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 8, ubuntu-22.04, 3.11) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2024-09-17 13:05:44 -04:00
Jay Lee
4583f6d996 actions: need team-id to notarize 2024-09-17 12:36:23 -04:00
Jay Lee
92282fb493 actions: use newer tool for notarization 2024-09-17 12:30:39 -04:00
Jay Lee
65ea328f2a actions: attempt to notarize macos binaries 2024-09-17 12:15:13 -04:00
Jay Lee
2da4833a0d actions: file is a .plist, not .xml 2024-09-17 11:55:22 -04:00
Jay Lee
631ce68126 actions: actually try to sign gam binary for MacOS 2024-09-17 11:52:34 -04:00
Jay Lee
480aca680d actions: create entitlements.plist file for MacOS signing 2024-09-17 11:45:45 -04:00
Jay Lee
6e3ab6700d actions: actually comment out create admin line 2024-09-17 11:41:26 -04:00
Jay Lee
61319fa08e actions: just create at root and don't make delegated admin 2024-09-17 11:36:39 -04:00
Jay Lee
673e9f88ad actions: sleep 5 min each 2024-09-17 11:18:45 -04:00
Jay Lee
f2b8200a3b actions: sleep 3m (bleh) 2024-09-17 11:11:21 -04:00
Jay Lee
0383624c72 actions: sleep before and after user creation (create admin was also failing) 2024-09-17 11:01:50 -04:00
Jay Lee
cb03b8d9d4 [no ci] actions: print that we're intentionally sleeping 2024-09-17 10:56:46 -04:00
Jay Lee
e7e821ca3d actions: sleep 5 min to wait for OU creation to work for user creation (yuck) 2024-09-17 10:47:36 -04:00
Jay Lee
6b21fdbcc6 actions: early work to add MacOS code signing 2024-09-17 07:47:28 -04:00
Ross Scroggs
ee326c6fe3 Updated print filecounts and update filerevisions
Some checks are pending
Build and test GAM / build (Win64, build, 9, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, [self-hosted linux arm64]) (push) Waiting to run
Build and test GAM / build (aarch64, build, 5, linux-aarch64, [self-hosted linux arm64], yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 7, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-20.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 4, linux-x86_64, ubuntu-20.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 6, darwin64-x86_64, macos-12) (push) Waiting to run
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.8) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.9) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 8, ubuntu-22.04, 3.11) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2024-09-16 15:20:04 -07:00
Ross Scroggs
8945fd163c Updated print filecounts and update filerevisions 2024-09-16 14:12:43 -07:00
Jay Lee
4dab0bd4bb actions: re-arrange job order
Some checks are pending
Build and test GAM / build (Win64, build, 9, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, [self-hosted linux arm64]) (push) Waiting to run
Build and test GAM / build (aarch64, build, 5, linux-aarch64, [self-hosted linux arm64], yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 7, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-20.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 4, linux-x86_64, ubuntu-20.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 6, darwin64-x86_64, macos-12) (push) Waiting to run
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.8) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.9) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 8, ubuntu-22.04, 3.11) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
2024-09-16 12:07:08 -04:00
Jay Lee
49ec0c6df4 actions: rebuild to get Python 3.12.6
Some checks failed
Build and test GAM / build (Win64, build, 9, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, [self-hosted linux arm64]) (push) Waiting to run
Build and test GAM / build (aarch64, build, 5, linux-aarch64, [self-hosted linux arm64], yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 7, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-20.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 4, linux-x86_64, ubuntu-20.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 6, darwin64-x86_64, macos-12) (push) Waiting to run
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.8) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.9) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-22.04, 3.11) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
Check for Google Root CA Updates / check-apis (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
2024-09-16 03:29:37 -04:00
Ross Scroggs
f3d29c47e2 Added option shownames to gam <UserTypeEntity> print|show sheet
Some checks are pending
Build and test GAM / build (Win64, build, 9, VC-WIN64A, windows-2022) (push) Waiting to run
Build and test GAM / build (aarch64, build, 3, linux-aarch64, [self-hosted linux arm64]) (push) Waiting to run
Build and test GAM / build (aarch64, build, 5, linux-aarch64, [self-hosted linux arm64], yes) (push) Waiting to run
Build and test GAM / build (aarch64, build, 7, darwin64-arm64, macos-14) (push) Waiting to run
Build and test GAM / build (x86_64, build, 1, linux-x86_64, ubuntu-22.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 2, linux-x86_64, ubuntu-20.04) (push) Waiting to run
Build and test GAM / build (x86_64, build, 4, linux-x86_64, ubuntu-20.04, yes) (push) Waiting to run
Build and test GAM / build (x86_64, build, 6, darwin64-x86_64, macos-12) (push) Waiting to run
Build and test GAM / build (x86_64, test, 10, ubuntu-22.04, 3.8) (push) Waiting to run
Build and test GAM / build (x86_64, test, 11, ubuntu-22.04, 3.9) (push) Waiting to run
Build and test GAM / build (x86_64, test, 12, ubuntu-22.04, 3.10) (push) Waiting to run
Build and test GAM / build (x86_64, test, 13, ubuntu-22.04, 3.11) (push) Waiting to run
Build and test GAM / merge (push) Blocked by required conditions
Build and test GAM / publish (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Check for Google Root CA Updates / check-apis (push) Waiting to run
Added build for ubuntu-22.04, it is my most common Linux download
2024-09-14 20:01:04 -07:00
14 changed files with 257 additions and 67 deletions

13
.github/actions/entitlements.plist vendored Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- These are required for binaries built by PyInstaller -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>

View File

@@ -31,68 +31,68 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-22.04
jid: 1
goal: build
arch: x86_64
openssl_archs: linux-x86_64
- os: [self-hosted, linux, arm64]
- os: ubuntu-20.04
jid: 2
goal: build
arch: x86_64
openssl_archs: linux-x86_64
- os: [self-hosted, linux, arm64]
jid: 3
goal: build
arch: aarch64
openssl_archs: linux-aarch64
- os: ubuntu-20.04
jid: 3
jid: 4
goal: build
arch: x86_64
openssl_archs: linux-x86_64
staticx: yes
- os: [self-hosted, linux, arm64]
jid: 4
jid: 5
goal: build
arch: aarch64
openssl_archs: linux-aarch64
staticx: yes
- os: macos-12
jid: 5
jid: 6
goal: build
arch: x86_64
openssl_archs: darwin64-x86_64
- os: macos-14
jid: 6
jid: 7
goal: build
arch: aarch64
openssl_archs: darwin64-arm64
# - os: macos-14
# jid: 7
# goal: build
# arch: universal2
# openssl_archs: darwin64-arm64 darwin64-x86_64
- os: windows-2022
jid: 8
jid: 9
goal: build
arch: Win64
openssl_archs: VC-WIN64A
- os: ubuntu-22.04
goal: test
python: "3.8"
jid: 9
arch: x86_64
- os: ubuntu-22.04
goal: test
python: "3.9"
jid: 10
arch: x86_64
- os: ubuntu-22.04
goal: test
python: "3.10"
python: "3.9"
jid: 11
arch: x86_64
- os: ubuntu-22.04
goal: test
python: "3.11"
python: "3.10"
jid: 12
arch: x86_64
- os: ubuntu-22.04
goal: test
python: "3.11"
jid: 8
arch: x86_64
steps:
@@ -115,7 +115,7 @@ jobs:
with:
path: |
cache.tar.xz
key: gam-${{ matrix.jid }}-20240903
key: gam-${{ matrix.jid }}-20240916
- name: Untar Cache archive
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
@@ -201,6 +201,14 @@ jobs:
#brew install swig
#brew install ncurses
- name: MacOS import developer certificates for signing
if: runner.os == 'macOS'
uses: apple-actions/import-codesign-certs@v3
with:
keychain: signing_temp
p12-file-base64: ${{ secrets.CERTIFICATES_P12 }}
p12-password: ${{ secrets.CERTIFICATES_P12_PASSWORD }}
- name: Windows Configure VCode
uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
@@ -596,9 +604,27 @@ jobs:
;;
esac
echo "ldlib=${ldlib}"
$PYTHON -m staticx -l "${ldlib}" "${gam}" "${gam}-staticx"
rm -v "${gam}"
mv -v "${gam}-staticx" "${gam}"
$PYTHON -m staticx -l "${ldlib}" "$gam" "${gam}-staticx"
rm -v "$gam"
mv -v "${gam}-staticx" "$gam"
- name: MacOS sign GAM binary
if: runner.os == 'macOS'
run: |
security find-identity -v signing_temp.keychain
codesign --force --deep --sign "Jay Lee" --options=runtime --entitlements "${GITHUB_WORKSPACE}/.github/actions/entitlements.plist" --timestamp "$gam"
codesign -dv --verbose=4 "$gam"
- name: MacOS send GAM binary for Apple notarization
if: runner.os == 'macOS'
env:
ASP_NOTARIZE: ${{ secrets.ASP_NOTARIZE }}
run: |
# Apple wants some kind of "package" submitted so just add gam to a .zip
# name it something we can track and link in Apple's notarize process
zipfilename="./gam-${RUNNER_ARCH}-${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}.zip"
zip "$zipfilename" "$gam"
xcrun notarytool submit --apple-id "jay0lee@gmail.com" --password "$ASP_NOTARIZE" --team-id GZ85H2DRLM "$zipfilename"
- name: Basic Tests all jobs
id: basictests
@@ -715,7 +741,8 @@ jobs:
done
driveid=$($gam user $gam_user add shareddrive "${newbase}" returnidonly)
echo "Created shared drive ${driveid}"
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random ou "${newou}" recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB-
# 9/17/24 - temp create in root due to Google API issues creating users in new OUs
$gam create user $newuser firstname GHA lastname $JID displayname "Github Actions ${JID}" password random recoveryphone 12125121110 recoveryemail jay0lee@gmail.com gha.jid $JID languages en+,en-GB- # ou "${newou}"
$gam user $newuser update photo https://dummyimage.com/400x600/000/fff
$gam user $newuser get photo
$gam user $newuser delete photo
@@ -734,7 +761,8 @@ jobs:
$gam update group $newgroup add owner $gam_user
$gam update group $newgroup add member $newuser
$gam config enable_dasa false save
$gam create admin $newuser _GROUPS_EDITOR_ROLE CUSTOMER # condition nonsecuritygroup
# 9/17/24 temp disable due to Google API sluggishness to see new users for admin commands
# $gam create admin $newuser _GROUPS_EDITOR_ROLE CUSTOMER # condition nonsecuritygroup
$gam create admin $newgroup _HELP_DESK_ADMIN_ROLE org_unit "${newou}"
$gam config csv_output_row_filter "assignedToUser:regex:${newuser}" print admins | $gam csv - gam delete admin "~roleAssignmentId"
$gam config csv_output_row_filter "assignedToGroup:regex:${newgroup}" print admins | $gam csv - gam delete admin "~roleAssignmentId"
@@ -858,7 +886,7 @@ jobs:
echo "printer model count:"
$gam print printermodels | wc -l
$gam print printers
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by $(gam_user)" ou "${newou}" nodetails | awk '{print substr($2, 1, length($2)-1)}')
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by ${gam_user}" ou "${newou}" nodetails | awk '{print substr($2, 1, length($2)-1)}')
$gam info printer "$printerid"
$gam delete printer "$printerid"
$gam delete ou "${newou}"

View File

@@ -1,6 +1,6 @@
GAM is a command line tool for Google Workspace admins to manage domain and user settings quickly and easily.
![Build Status](https://github.com/GAM-team/GAM/workflows/Build%20and%20test%20GAM/badge.svg)
[![Build StatusM](https://github.com/GAM-team/GAM/actions/workflows/build.yml/badge.svg)](https://github.com/GAM-team/GAM/actions/workflows/build.yml)
# Quick Start

View File

@@ -14,8 +14,10 @@
- [Display Chrome policies](#display-chrome-policies)
- [Copy simple policies set directly in one OU to another OU](#copy-simple-policies-set-directly-in-one-ou-to-another-ou)
- [Copy simple and complex policies set directly in one OU to another OU](#copy-simple-and-complex-policies-set-directly-in-one-ou-to-another-ou)
- [Copy simple and complex policies set directly in one OU to multiple other OUs](#copy-simple-and-complex-policies-set-directly-in-one-ou-to-multiple-other-ous)
- [Copy simple policies in one Group to another Group](#copy-simple-policies-in-one-group-to-another-group)
- [Copy simple and complex policies in one Group to another Group](#copy-simple-and-complex-policies-in-one-group-to-another-group)
- [Copy simple and complex policies in one Group to multiple other Groups](#copy-simple-and-complex-policies-in-one-group-to-multiple-other-groups)
- [Create Chrome network](#create-chrome-network)
- [Delete Chrome network](#delete-chrome-network)
- [Chrome Policy Schema Table](#chrome-policy-schema-table)
@@ -356,6 +358,22 @@ gam redirect csv ChromePolicies.csv print chromepolicies ou "/Path/To/OU1" forma
gam config csv_input_row_filter "direct:boolean:true" csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU2"
```
## Copy simple and complex policies set directly in one OU to multiple other OUs
Display direct policies, update all
```
gam redirect csv ChromePolicies.csv print chromepolicies ou "/Path/To/OU1" show direct formatjson quotechar "'"
```
Make a batch file (SetPolicies.bat) with a line for each target OU
```
gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU2"
gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" ou "/Path/To/OU3"
...
```
Execute batch
```
gam redirect stdout ./SetPolicies.log multiprocess redirect stderr stdout tbatch SetPolicies.bat
```
## Copy simple policies in one Group to another Group
Display all policies, update all
```
@@ -369,6 +387,22 @@ gam redirect csv ChromePolicies.csv print chromepolicies group group1@domain.com
gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group2@domain.com
```
## Copy simple and complex policies in one Group to multiple other Groups
Display all policies, update all
```
gam redirect csv ChromePolicies.csv print chromepolicies group group1@domain.com formatjson quotechar "'"
```
Make a batch file (SetPolicies.bat) with a line for each target group
```
gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group2@domain.com
gam csv ChromePolicies.csv quotechar "'" gam update chromepolicy "~name" json "~JSON" group group3@domain.com
...
```
Execute batch
```
gam redirect stdout ./SetPolicies.log multiprocess redirect stderr stdout tbatch SetPolicies.bat
```
## Create Chrome network
See: [Chrome Policy Schema Table](#chrome-policy-schema-table) for the allowed network settings.
* chrome.networks.ethernet.Details: Ethernet network configuration details.

View File

@@ -10,6 +10,26 @@ 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
### 7.00.02
Added option `showlastmodification` to `gam <UserTypeEntity> print|show filecounts` that adds
the following fields to the output: `lastModifiedFileId,lastModifiedFileName,lastModifyingUser,lastModifiedTime`;
these are for the most recently modified file.
Added option `keepforever [<Boolean>]` to `gam <UserTypeEntity> update filerevisions` that allows setting
`Keep forever` in revisions.
Upgraded to Python 3.12.6 where possible.
### 7.00.01
Added option `shownames` to `gam <UserTypeEntity> print|show sheet` that causes GAM
to make an additional API call to get and display the sheet file name that is not supplied by the Sheets API.
### 7.00.00
Merged GAM-Team version
### 6.81.02
Updated `gam update group postmaster@domain.com` to handle the error that is generated.

View File

@@ -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.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
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.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.5 64-bit final
Windows-10-10.0.17134 AMD64

View File

@@ -693,7 +693,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[showsize] [showmimetypesize] (addcsvdata <FieldName> <String>)*
[showsize] [showmimetypesize] [showlastmodification]
(addcsvdata <FieldName> <String>)*
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
@@ -707,13 +708,13 @@ gam <UserTypeEntity> show filecounts
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[showsize] [showmimetypesize]
[showsize] [showmimetypesize] [showlastmodification]
[summary none|only|plus] [summaryuser <String>]
```
By default, print filecounts displays counts of all files owned by the specified [`<UserTypeEntity>`](Collections-of-Users).
The option `continueoninvalidquery [<Boolean>] can be used in special cases where a query of the form
The option `continueoninvalidquery [<Boolean>] can be used in special cases where a query of the form
`query "'labels/mRoha85IbwCRl490E00xGLvBsSbkwIiuZ6PRNNEbwxyz' in labels" causes Google to issue an error
saying that the query is invalid when, in fact, it is but the user does not have a license that suppprts drive file labels.
When `continueoninvalidquery` is true, GAM prints an error message and proceeds to the next user rather that terminating
@@ -723,6 +724,10 @@ The `showsize` option displays the total size (in bytes) of the files counted.
The showmimetypesize' displays the total size (in bytes) of each MIME type counted.
The option `showlastmodification` displays the following fields:
`lastModifiedFileId,lastModifiedFileName,lastModifyingUser,lastModifiedTime`;
these are for the most recently modified file.
For print filecouts, add additional columns of data from the command line to the output:
* `addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output

View File

@@ -85,6 +85,8 @@ gam <UserTypeEntity> update filerevisions <DriveFileEntity> select <DriveFileRev
```
When `select <DriveFileRevisionIDEntity>` is omitted, all revisions are updated.
* `keepforever true` - Keep revision forever, even if it is no longer the head revision
* `keepforever false` - Do not keep revision forever
* `published true` - Publish these revision to the web
* `published false` - Do not publish these revision to the web
* `publishauto true` - Automaticaly publish subsequent revisions to the web

View File

@@ -231,18 +231,24 @@ gam user testuser@domain.com update sheet <DriveFileItem> json file Sheet.json
gam <UserTypeEntity> info|show sheet <DriveFileEntity>
[fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
(range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
[includegriddata [<Boolean>]]
[includegriddata [<Boolean>]] [shownames]
[formatjson]
```
By default, the Sheets API does not return the sheet file name, use the `shownames` option to have GAM
make an additional API call to get and display the sheet file name.
The output is formatted for human readability. Use the following option to produce JSON output for program parsing.
* `formatjson` - Display output in JSON format.
```
gam <UserTypeEntity> print sheet <DriveFileEntity> [todrive <ToDriveAttribute>*]
[fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
(range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
[includegriddata [<Boolean>]]
[includegriddata [<Boolean>]] [shownames]
[formatjson [quotechar <Character>]]
```
By default, the Sheets API does not return the sheet file name, use the `shownames` option to have GAM
make an additional API call to get and display the sheet file name.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.

View File

@@ -3,7 +3,7 @@
Print the current version of Gam with details
```
gam version
GAMADV-XTD3 6.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
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.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
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.81.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
Ross Scroggs <ross.scroggs@gmail.com>
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.81.02
Latest: 7.00.02
echo $?
1
```
@@ -72,7 +72,7 @@ echo $?
Print the current version number without details
```
gam version simple
6.81.02
7.00.02
```
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.81.02 - https://github.com/taers232c/GAMADV-XTD3
GAM 7.00.02 - https://github.com/taers232c/GAMADV-XTD3
Ross Scroggs <ross.scroggs@gmail.com>
Python 3.12.5 64-bit final
MacOS Sonoma 14.5 x86_64

View File

@@ -3541,11 +3541,11 @@ gam [<UserTypeEntity>] show drivelabels
[formatjson] [adminaccess|asadmin]
`
gam [<UserTypeEntity>] create drivelabelpermission <DriveLabelNameEntity>
(user <UserItem>) | (group <GroupItem) | (audience <String>)
(user <UserItem>) | (group <GroupItem>) | (audience <String>)
role applier|editor|organizer|reader
[formatjson] [adminaccess|asadmin]
gam [<UserTypeEntity>] delete drivelabelpermission <DriveLabelNameEntity>
(user <UserItem>) | (group <GroupItem) | (audience <String>)
(user <UserItem>) | (group <GroupItem>) | (audience <String>)
[adminaccess|asadmin]
gam [<UserTypeEntity>] remove drivelabelpermission <DriveLabelPermissionNameEntity>
[adminaccess|asadmin]
@@ -7043,7 +7043,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[showsize] [showmimetypesize] (addcsvdata <FieldName> <String>)*
[showsize] [showmimetypesize] [showlastmodification]
(addcsvdata <FieldName> <String>)*
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> show filecounts
[((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>)
@@ -7052,12 +7053,12 @@ gam <UserTypeEntity> show filecounts
[corpora <CorporaAttribute>]
[select <SharedDriveEntity>]
[anyowner|(showownedby any|me|others)]
[showmimetype [not] <MimeTypeList>] [`<showmimetype category <MimeTypeNameList>]
[showmimetype [not] <MimeTypeList>] [showmimetype category <MimeTypeNameList>]
[sizefield quotabytesused|size] [minimumfilesize <Integer>] [maximumfilesize <Integer>]
[filenamematchpattern <RegularExpression>]
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
[excludetrashed]
[showsize] [showmimetypesize]
[showsize] [showmimetypesize] [showlastmodification]
[summary none|only|plus] [summaryuser <String>]
gam <UserTypeEntity> print filesharecounts [todrive <ToDriveAttribute>*]
@@ -8244,12 +8245,12 @@ gam <UserTypeEntity> update sheet <DriveFileEntity>
gam <UserTypeEntity> info|show sheet <DriveFileEntity>
[fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
(range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
[includegriddata [<Boolean>]]
[includegriddata [<Boolean>]] [shownames]
[formatjson]
gam <UserTypeEntity> print sheet <DriveFileEntity> [todrive <ToDriveAttribute>*]
[fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
(range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
[includegriddata [<Boolean>]]
[includegriddata [<Boolean>]] [shownames]
[formatjson [quotechar <Character>]]
See: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values#ValueRange

View File

@@ -1,3 +1,19 @@
7.00.02
Added option `showlastmodification` to `gam <UserTypeEntity> print|show filecounts` that adds
the following fields to the output: `lastModifiedFileId,lastModifiedFileName,lastModifyingUser,lastModifiedTime`;
these are for the most recently modified file.
Added option `keepforever [<Boolean>]` to `gam <UserTypeEntity> update filerevisions` that allows setting
`Keep forever` in revisions.
Upgraded to Python 3.12.6 where possible.
7.00.01
Added option `shownames` to `gam <UserTypeEntity> print|show sheet` that causes GAM
to make an additional API call to get and display the sheet file name that is not supplied by the Sheets API.
7.00.00
Merged GAM-Team version

View File

@@ -16,7 +16,7 @@ OPTIONS:
-u Admin user email address to use with GAM. Default is to prompt.
-r Regular user email address. Used to test service account access to user data. Default is to prompt.
-v Version to install (latest, prerelease, draft, 3.8, etc). Default is latest.
-s Strip gam7 component from extracted files, files will be downloaded directly to $target_dir
-s Strip gam component from extracted files, files will be downloaded directly to $target_dir
EOF
}
@@ -30,7 +30,7 @@ upgrade_only=false
gamversion="latest"
adminuser=""
regularuser=""
gam_x86_64_glibc_vers="2.31"
gam_x86_64_glibc_vers="2.35 2.31"
gam_arm64_glibc_vers="2.31"
strip_gam="--strip-components 0"
@@ -172,7 +172,9 @@ case $gamos in
;;
esac
if [ "$gamversion" == "latest" -o "$gamversion" == "prerelease" -o "$gamversion" == "draft" ]; then
if [ "$gamversion" == "latest" ]; then
release_url="https://api.github.com/repos/GAM-team/GAM/releases/latest"
elif [ "$gamversion" == "prerelease" -o "$gamversion" == "draft" ]; then
release_url="https://api.github.com/repos/GAM-team/GAM/releases"
else
release_url="https://api.github.com/repos/GAM-team/GAM/releases/tags/v$gamversion"

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.00.00'
__version__ = '7.00.02'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
#pylint: disable=wrong-import-position
@@ -53967,12 +53967,14 @@ def deleteFileRevisions(users):
Ind.Decrement()
REVISIONS_FIELDS_CHOICE_MAP = {
'keepforever': 'keepForever',
'published': 'published',
'publishauto': 'publishAuto',
'publishedoutsidedomain': 'publishedOutsideDomain'
}
# gam <UserTypeEntity> update filerevisions <DriveFileEntity> select <DriveFileRevisionIdEntity> [previewupdate]
# [published [<Boolean>]] [publishauto [<Boolean>]] [publishedoutsidedomain [<Boolean>]]
# [keepforever [<Boolean>]}
# [showtitles] [doit] [max_to_update <Number>]
def updateFileRevisions(users):
fileIdEntity = getDriveFileEntity()
@@ -56118,7 +56120,8 @@ def printFileParentTree(users):
# [filenamematchpattern <RegularExpression>]
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
# [excludetrashed] (addcsvdata <FieldName> <String>)*
# [showsize] [showmimetypesize]
# [showsize] [showmimetypesize] [showlastmodification]
# (addcsvdata <FieldName> <String>)*
# [summary none|only|plus] [summaryuser <String>]
# gam <UserTypeEntity> show filecounts
# [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)*]
@@ -56131,7 +56134,7 @@ def printFileParentTree(users):
# [filenamematchpattern <RegularExpression>]
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
# [excludetrashed]
# [showsize] [showmimetypesize]
# [showsize] [showmimetypesize] [showlastmodification]
# [summary none|only|plus] [summaryuser <String>]
def printShowFileCounts(users):
def _setSelectionFields():
@@ -56139,6 +56142,8 @@ def printShowFileCounts(users):
fieldsList.extend(OWNED_BY_ME_FIELDS_TITLES)
if showSize or (DLP.minimumFileSize is not None) or (DLP.maximumFileSize is not None):
fieldsList.append(sizeField)
if showLastModification:
fieldsList.extend(['id,name,modifiedTime,lastModifyingUser(emailAddress)'])
if DLP.filenameMatchPattern:
fieldsList.append('name')
if DLP.excludeTrashed:
@@ -56148,7 +56153,7 @@ def printShowFileCounts(users):
if DLP.onlySharedDrives or getPermissionsForSharedDrives:
fieldsList.append('driveId')
def showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, i, count):
def showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, lastModification, i, count):
if summary != FILECOUNT_SUMMARY_NONE:
if count != 0:
for mimeType, mtinfo in iter(mimeTypeInfo.items()):
@@ -56173,6 +56178,10 @@ def printShowFileCounts(users):
dataList.extend(['Item cap', f"{countTotal/SHARED_DRIVE_MAX_FILES_FOLDERS:.2%}"])
printEntityKVList(kvList, dataList, i, count)
Ind.Increment()
if showLastModification:
printKeyValueList(['lastModifiedFile', f"{lastModification['lastModifiedFileName']}({lastModification['lastModifiedFileId']})",
'lastModifyingUser', lastModification['lastModifyingUser'],
'lastModifiedTime', formatLocalTime(lastModification['lastModifiedTime'])])
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
if not showMimeTypeSize:
printKeyValueList([mimeType, mtinfo['count']])
@@ -56186,6 +56195,11 @@ def printShowFileCounts(users):
row = {'User': user, 'Total': countTotal}
if showSize:
row['Size'] = sizeTotal
if showLastModification:
row.update({'lastModifiedFileId': lastModification['lastModifiedFileId'],
'lastModifiedFileName': lastModification['lastModifiedFileName'],
'lastModifyingUser': lastModification['lastModifyingUser'],
'lastModifiedTime': formatLocalTime(lastModification['lastModifiedTime'])})
if addCSVData:
row.update(addCSVData)
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
@@ -56200,13 +56214,16 @@ def printShowFileCounts(users):
fieldsList = ['mimeType']
DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': True})
sharedDriveId = sharedDriveName = ''
continueOnInvalidQuery = showSize = showMimeTypeSize = False
continueOnInvalidQuery = showSize = showLastModification = showMimeTypeSize = False
sizeField = 'quotaBytesUsed'
summary = FILECOUNT_SUMMARY_NONE
summaryUser = FILECOUNT_SUMMARY_USER
summaryMimeTypeInfo = {}
fileIdEntity = {}
addCSVData = {}
summaryLastModification = {
'lastModifiedFileId': '', 'lastModifiedFileName': '',
'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME}
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -56221,6 +56238,8 @@ def printShowFileCounts(users):
showSize = True
elif myarg == 'sizefield':
sizeField = getChoice(SIZE_FIELD_CHOICE_MAP, mapChoice=True)
elif myarg == 'showlastmodification':
showLastModification = True
elif myarg == 'showmimetypesize':
showMimeTypeSize = showSize = True
elif myarg == 'summary':
@@ -56252,6 +56271,8 @@ def printShowFileCounts(users):
sortTitles = ['User', 'id', 'name', 'Total', 'Item cap'] if fileIdEntity.get('shareddrive') else ['User', 'Total']
if showSize:
sortTitles.insert(sortTitles.index('Total')+1, 'Size')
if showLastModification:
sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName', 'lastModifyingUser', 'lastModifiedTime'])
if addCSVData:
sortTitles.extend(sorted(addCSVData.keys()))
csvPF.SetTitles(sortTitles)
@@ -56269,6 +56290,9 @@ def printShowFileCounts(users):
else:
sharedDriveName = ''
mimeTypeInfo = {}
userLastModification = {
'lastModifiedFileId': '', 'lastModifiedFileName': '',
'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME}
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, user, i, count, query=DLP.fileIdEntity['query'])
try:
feed = yieldGAPIpages(drive.files(), 'list', 'files',
@@ -56309,7 +56333,15 @@ def printShowFileCounts(users):
mimeTypeInfo.setdefault(f_file['mimeType'], {'count': 0, 'size': 0})
mimeTypeInfo[f_file['mimeType']]['count'] += 1
mimeTypeInfo[f_file['mimeType']]['size'] += int(f_file.get(sizeField, '0'))
showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, i, count)
if showLastModification:
if f_file.get('modifiedTime', NEVER_TIME) > userLastModification['lastModifiedTime'] and 'lastModifyingUser' in f_file:
userLastModification['lastModifiedFileId'] = f_file['id']
userLastModification['lastModifiedFileName'] = _stripControlCharsFromName(f_file['name'])
userLastModification['lastModifiedTime'] = f_file['modifiedTime']
userLastModification['lastModifyingUser'] = f_file['lastModifyingUser'].get('emailAddress', UNKNOWN)
showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, userLastModification, i, count)
if showLastModification and userLastModification['lastModifiedTime'] > summaryLastModification['lastModifiedTime']:
summaryLastModification = userLastModification.copy()
except (GAPI.invalidQuery, GAPI.invalid, GAPI.badRequest):
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], invalidQuery(DLP.fileIdEntity['query']), i, count)
if not continueOnInvalidQuery:
@@ -56324,7 +56356,9 @@ def printShowFileCounts(users):
continue
if summary != FILECOUNT_SUMMARY_NONE:
showMimeTypeInfo(summaryUser, summaryMimeTypeInfo,
'' if count > 1 else sharedDriveId, '' if count > 1 else sharedDriveName, 0, 0)
'' if count > 1 else sharedDriveId,
'' if count > 1 else sharedDriveName,
summaryLastModification, 0, 0)
if csvPF:
csvPF.writeCSVfile('Drive File Counts')
@@ -66995,14 +67029,14 @@ SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP = {
}
# gam <UserTypeEntity> info|show sheet <DriveFileEntity>
# [fields <SpreadsheetFieldList>]
# [fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
# (range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
# [includegriddata [<Boolean>]]
# [includegriddata [<Boolean>]] [shownames]
# [formatjson]
# gam <UserTypeEntity> print sheet <DriveFileEntity> [todrive <ToDriveAttribute>*]
# [fields <SpreadsheetFieldList>]
# [fields <SpreadsheetFieldList>] [sheetsfields <SpreadsheetSheetsFieldList>]
# (range <SpreadsheetRange>)* (rangelist <SpreadsheetRangeList>)*
# [includegriddata [<Boolean>]]
# [includegriddata [<Boolean>]] [shownames]
# [formatjson [quotechar <Character>]]
def infoPrintShowSheets(users):
csvPF = CSVPrintFile(['User', 'spreadsheetId'], 'sortall') if Act.csvFormat() else None
@@ -67010,7 +67044,7 @@ def infoPrintShowSheets(users):
spreadsheetIdEntity = getDriveFileEntity()
fieldsList = []
ranges = []
includeGridData = False
includeGridData = showSheetNames = False
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if csvPF and myarg == 'todrive':
@@ -67029,8 +67063,16 @@ def infoPrintShowSheets(users):
fieldsList.append(SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP[field])
else:
invalidChoiceExit(field, SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP, True)
elif myarg == 'shownames':
showSheetNames = True
else:
FJQC.GetFormatJSONQuoteChar(myarg, True)
if csvPF and showSheetNames:
csvPF.AddTitles('spreadsheetName')
csvPF.SetSortAllTitles()
if FJQC.formatJSON:
csvPF.AddJSONTitles('spreadsheetName')
csvPF.MoveJSONTitlesToEnd(['JSON'])
if includeGridData and fieldsList:
fieldsList.append(SPREADSHEET_SHEETS_SUBFIELDS_CHOICE_MAP['data'])
fields = getFieldsFromFieldsList(fieldsList)
@@ -67040,6 +67082,10 @@ def infoPrintShowSheets(users):
user, sheet, jcount = _validateUserGetSpreadsheetIDs(user, i, count, spreadsheetIdEntity, not FJQC.formatJSON)
if jcount == 0:
continue
if showSheetNames:
_, drive = buildGAPIServiceObject(API.DRIVE3, user, i, count)
if not drive:
continue
Ind.Increment()
j = 0
for spreadsheetId in spreadsheetIdEntity['list']:
@@ -67051,11 +67097,25 @@ def infoPrintShowSheets(users):
if not includeGridData and 'sheets' in result:
for usheet in result['sheets']:
usheet.pop('data', None)
if showSheetNames:
try:
spreadsheetName = callGAPI(drive.files(), 'get',
throwReasons=GAPI.DRIVE_GET_THROW_REASONS,
fileId=spreadsheetId, fields='name', supportsAllDrives=True)['name']
except (GAPI.fileNotFound, GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy):
spreadsheetName = spreadsheetId
if not csvPF:
if FJQC.formatJSON:
printLine('{'+f'"User": "{user}", "spreadsheetId": "{spreadsheetId}", "JSON": {json.dumps(result, ensure_ascii=False, sort_keys=False)}'+'}')
baserow = {'User': user, 'spreadsheetId': spreadsheetId}
if showSheetNames:
baserow['spreadsheetName'] = spreadsheetName
baserow['JSON'] = result
printLine(json.dumps(baserow, ensure_ascii=False, sort_keys=False)+'\n')
continue
printEntity([Ent.SPREADSHEET, spreadsheetId], j, jcount)
if showSheetNames:
printEntity([Ent.SPREADSHEET, f'{spreadsheetName}({spreadsheetId})'], j, jcount)
else:
printEntity([Ent.SPREADSHEET, spreadsheetId], j, jcount)
Ind.Increment()
if 'spreadsheetUrl' in result:
printKeyValueList(['spreadsheetUrl', result['spreadsheetUrl']])
@@ -67074,12 +67134,15 @@ def infoPrintShowSheets(users):
Ind.Decrement()
Ind.Decrement()
else:
row = flattenJSON(result, flattened={'User': user, 'spreadsheetId': spreadsheetId})
baserow = {'User': user, 'spreadsheetId': spreadsheetId}
if showSheetNames:
baserow['spreadsheetName'] = spreadsheetName
row = flattenJSON(result, flattened=baserow.copy())
if not FJQC.formatJSON:
csvPF.WriteRowTitles(row)
elif csvPF.CheckRowTitles(row):
csvPF.WriteRowNoFilter({'User': user, 'spreadsheetId': spreadsheetId,
'JSON': json.dumps(result, ensure_ascii=False, sort_keys=False)})
baserow['JSON'] = json.dumps(cleanJSON(result), ensure_ascii=False, sort_keys=False)
csvPF.WriteRowNoFilter(baserow)
except (GAPI.notFound, GAPI.forbidden, GAPI.permissionDenied,
GAPI.internalError, GAPI.insufficientFilePermissions, GAPI.badRequest,
GAPI.invalid, GAPI.invalidArgument, GAPI.failedPrecondition) as e: