mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-03 12:21:35 +00:00
Compare commits
71 Commits
v7.06.01
...
20250422.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d38b20cec | ||
|
|
f401e96dd4 | ||
|
|
5700c6bc31 | ||
|
|
164b999802 | ||
|
|
f60750a647 | ||
|
|
6d7913f6cf | ||
|
|
f050017771 | ||
|
|
f53c8086e8 | ||
|
|
7bf5d8879b | ||
|
|
c52ee7887d | ||
|
|
677de0867b | ||
|
|
58b17dd1d8 | ||
|
|
41b1ce50da | ||
|
|
613aff99e2 | ||
|
|
0f0eaa40b8 | ||
|
|
c7f9303f58 | ||
|
|
430d23b17b | ||
|
|
9eb5743283 | ||
|
|
7f72dad9b8 | ||
|
|
c866d2f4ab | ||
|
|
9e8c110f08 | ||
|
|
d261bcef40 | ||
|
|
38e96397a1 | ||
|
|
c9ca0a472c | ||
|
|
aa3a0330d1 | ||
|
|
cda74bd758 | ||
|
|
6b5e19b1de | ||
|
|
7cfa8836f8 | ||
|
|
c7ae9cdd6a | ||
|
|
126320e2fb | ||
|
|
46008d4155 | ||
|
|
34a3893676 | ||
|
|
16862a19a3 | ||
|
|
fb8442a5e3 | ||
|
|
d2b7e339ff | ||
|
|
742a6f14fe | ||
|
|
b33c9bc213 | ||
|
|
0af09f7517 | ||
|
|
6113acce66 | ||
|
|
97578029d5 | ||
|
|
f846c81c01 | ||
|
|
13cc34fde6 | ||
|
|
7f90a1a950 | ||
|
|
1b234d5aa7 | ||
|
|
32dc4c9de4 | ||
|
|
a150288a6f | ||
|
|
df053c36a6 | ||
|
|
0d01850356 | ||
|
|
6e9a68627b | ||
|
|
904f743f39 | ||
|
|
64c194e4d0 | ||
|
|
98c7ea08f8 | ||
|
|
a55f065cfb | ||
|
|
8eed07cb2e | ||
|
|
01af866c7b | ||
|
|
614ebd11c5 | ||
|
|
da1266e7cc | ||
|
|
06a6fff029 | ||
|
|
6da2b14111 | ||
|
|
0a89e82f2d | ||
|
|
33051d10c4 | ||
|
|
0652a91f89 | ||
|
|
fed4caeac0 | ||
|
|
f82ced5ade | ||
|
|
56e9027f38 | ||
|
|
73dbec522f | ||
|
|
cc01655b33 | ||
|
|
ac52f936d8 | ||
|
|
b851758baa | ||
|
|
72acbea40f | ||
|
|
8ff87db537 |
BIN
.github/actions/creds.tar.xz.gpg
vendored
BIN
.github/actions/creds.tar.xz.gpg
vendored
Binary file not shown.
43
.github/actions/decrypt.sh
vendored
43
.github/actions/decrypt.sh
vendored
@@ -1,38 +1,19 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
credspath="$3"
|
credspath="$1"
|
||||||
if [ ! -d "$credspath" ]; then
|
if [ ! -d "$credspath" ]; then
|
||||||
echo "creating ${credspath}"
|
echo "creating ${credspath}"
|
||||||
mkdir -p "$credspath"
|
mkdir -p "$credspath"
|
||||||
fi
|
fi
|
||||||
gpgfile="$1"
|
credsfile="${credspath}/oauth2.txt"
|
||||||
if [ -f "$gpgfile" ]; then
|
echo "$oa2" > "$credsfile"
|
||||||
echo "source file is ${gpgfile}"
|
echo "File size:"
|
||||||
|
wc -c "$credsfile"
|
||||||
|
echo "File type:"
|
||||||
|
file "$credsfile"
|
||||||
|
echo "Validation:"
|
||||||
|
jq -e . "$credsfile" > /dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Valid JSON"
|
||||||
else
|
else
|
||||||
echo "ERROR: ${gpgfile} does not exist"
|
echo "Invalid JSON"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
credsfile="$2"
|
|
||||||
echo "target file is ${credsfile}"
|
|
||||||
if [ -z ${PASSCODE+x} ]; then
|
|
||||||
echo "ERROR: PASSCODE is unset";
|
|
||||||
exit 2
|
|
||||||
else
|
|
||||||
echo "PASSCODE is set";
|
|
||||||
fi
|
|
||||||
|
|
||||||
gpg --batch \
|
|
||||||
--yes \
|
|
||||||
--decrypt \
|
|
||||||
--passphrase="$PASSCODE" \
|
|
||||||
--output "$credsfile" \
|
|
||||||
"$gpgfile"
|
|
||||||
|
|
||||||
if [[ "$RUNNER_OS" == "macOS" ]]; then
|
|
||||||
tar="gtar"
|
|
||||||
else
|
|
||||||
tar="tar"
|
|
||||||
fi
|
|
||||||
|
|
||||||
"$tar" xlvvf "$credsfile" --directory "$credspath"
|
|
||||||
rm -rvf "$gpgfile"
|
|
||||||
rm -rvf "$credsfile"
|
|
||||||
|
|||||||
295
.github/workflows/build.yml
vendored
295
.github/workflows/build.yml
vendored
@@ -22,7 +22,7 @@ defaults:
|
|||||||
working-directory: src
|
working-directory: src
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SCRATCH_COUNTER: 13
|
SCRATCH_COUNTER: 14
|
||||||
OPENSSL_CONFIG_OPTS: no-fips --api=3.0.0
|
OPENSSL_CONFIG_OPTS: no-fips --api=3.0.0
|
||||||
OPENSSL_INSTALL_PATH: ${{ github.workspace }}/bin/ssl
|
OPENSSL_INSTALL_PATH: ${{ github.workspace }}/bin/ssl
|
||||||
OPENSSL_SOURCE_PATH: ${{ github.workspace }}/src/openssl
|
OPENSSL_SOURCE_PATH: ${{ github.workspace }}/src/openssl
|
||||||
@@ -39,79 +39,69 @@ jobs:
|
|||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04
|
||||||
jid: 1
|
jid: 1
|
||||||
goal: build
|
goal: build
|
||||||
arch: x86_64
|
name: Build Intel Ubuntu Jammy
|
||||||
openssl_archs: linux-x86_64
|
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
jid: 2
|
jid: 2
|
||||||
goal: build
|
goal: build
|
||||||
arch: x86_64
|
name: Build Intel Ubuntu Noble
|
||||||
openssl_archs: linux-x86_64
|
|
||||||
- os: ubuntu-24.04-arm
|
- os: ubuntu-24.04-arm
|
||||||
jid: 3
|
jid: 3
|
||||||
goal: build
|
goal: build
|
||||||
arch: aarch64
|
name: Build Arm Ubuntu Noble
|
||||||
openssl_archs: linux-aarch64
|
|
||||||
- os: ubuntu-22.04-arm
|
- os: ubuntu-22.04-arm
|
||||||
jid: 4
|
jid: 4
|
||||||
goal: build
|
goal: build
|
||||||
arch: aarch64
|
name: Build Arm Ubuntu Jammy
|
||||||
openssl_archs: linux-aarch64
|
|
||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04
|
||||||
jid: 5
|
jid: 5
|
||||||
goal: build
|
goal: build
|
||||||
arch: x86_64
|
|
||||||
openssl_archs: linux-x86_64
|
|
||||||
staticx: yes
|
staticx: yes
|
||||||
|
name: Build Intel StaticX Legacy
|
||||||
- os: ubuntu-22.04-arm
|
- os: ubuntu-22.04-arm
|
||||||
jid: 6
|
jid: 6
|
||||||
goal: build
|
goal: build
|
||||||
arch: aarch64
|
|
||||||
openssl_archs: linux-aarch64
|
|
||||||
staticx: yes
|
staticx: yes
|
||||||
|
name: Build Arm StaticX Legacy
|
||||||
- os: macos-13
|
- os: macos-13
|
||||||
jid: 7
|
jid: 7
|
||||||
goal: build
|
goal: build
|
||||||
arch: x86_64
|
name: Build Intel MacOS
|
||||||
openssl_archs: darwin64-x86_64
|
|
||||||
- os: macos-14
|
- os: macos-14
|
||||||
jid: 8
|
jid: 8
|
||||||
goal: build
|
goal: build
|
||||||
arch: aarch64
|
name: Build Arm MacOS 14
|
||||||
openssl_archs: darwin64-arm64
|
|
||||||
- os: macos-15
|
- os: macos-15
|
||||||
jid: 9
|
jid: 9
|
||||||
goal: build
|
goal: build
|
||||||
arch: aarch64
|
name: Build Arm MacOS 15
|
||||||
openssl_archs: darwin64-arm64
|
|
||||||
- os: windows-2022
|
- os: windows-2022
|
||||||
jid: 10
|
jid: 10
|
||||||
goal: build
|
goal: build
|
||||||
arch: Win64
|
name: Build Intel Windows
|
||||||
openssl_archs: VC-WIN64A
|
- os: windows-11-arm
|
||||||
# disable 3.9 test for now since it's oldest and due
|
jid: 11
|
||||||
# for removal in Oct 2025. We only have 13 jid accounts
|
goal: build
|
||||||
# so we need this one off but can re-enable at some point
|
name: Build Arm Windows
|
||||||
# if we feel the need.
|
|
||||||
#- os: ubuntu-24.04
|
|
||||||
# goal: test
|
|
||||||
# python: "3.9"
|
|
||||||
# jid: 11
|
|
||||||
# arch: x86_64
|
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.10"
|
python: "3.10"
|
||||||
jid: 11
|
jid: 12
|
||||||
arch: x86_64
|
name: Test Python 3.10
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.11"
|
python: "3.11"
|
||||||
jid: 12
|
jid: 13
|
||||||
arch: x86_64
|
name: Test Python 3.11
|
||||||
- os: ubuntu-24.04
|
- os: ubuntu-24.04
|
||||||
goal: test
|
goal: test
|
||||||
python: "3.12"
|
python: "3.12"
|
||||||
jid: 13
|
jid: 14
|
||||||
arch: x86_64
|
name: Test Python 3.12
|
||||||
|
- os: ubuntu-24.04
|
||||||
|
goal: test
|
||||||
|
python: "3.14-dev"
|
||||||
|
jid: 15
|
||||||
|
name: Test Python 3.14-dev
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
@@ -148,15 +138,25 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python }}
|
python-version: ${{ matrix.python }}
|
||||||
allow-prereleases: true
|
allow-prereleases: true
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
- name: common variables for all runs
|
- name: common variables for all runs
|
||||||
env:
|
env:
|
||||||
arch: ${{ matrix.arch }}
|
|
||||||
JID: ${{ matrix.jid }}
|
JID: ${{ matrix.jid }}
|
||||||
ACTIONS_CACHE: ${{ steps.cache-python-ssl.outputs.cache-hit }}
|
ACTIONS_CACHE: ${{ steps.cache-python-ssl.outputs.cache-hit }}
|
||||||
ACTIONS_GOAL: ${{ matrix.goal }}
|
ACTIONS_GOAL: ${{ matrix.goal }}
|
||||||
run: |
|
run: |
|
||||||
echo "arch=${arch}" >> $GITHUB_ENV
|
case $RUNNER_ARCH in
|
||||||
|
X64)
|
||||||
|
echo "arch=x86_64" >> $GITHUB_ENV
|
||||||
|
;;
|
||||||
|
ARM64)
|
||||||
|
echo "arch=arm64" >> $GITHUB_ENV
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "arch=${RUNNER_ARCH}" >> $GITHUB_ENV
|
||||||
|
;;
|
||||||
|
esac
|
||||||
echo "JID=${JID}" >> $GITHUB_ENV
|
echo "JID=${JID}" >> $GITHUB_ENV
|
||||||
echo "ACTIONS_CACHE=${ACTIONS_CACHE}" >> $GITHUB_ENV
|
echo "ACTIONS_CACHE=${ACTIONS_CACHE}" >> $GITHUB_ENV
|
||||||
echo "ACTIONS_GOAL=${ACTIONS_GOAL}" >> $GITHUB_ENV
|
echo "ACTIONS_GOAL=${ACTIONS_GOAL}" >> $GITHUB_ENV
|
||||||
@@ -170,20 +170,12 @@ jobs:
|
|||||||
echo "curl_retry=${curl_retry}" >> $GITHUB_ENV
|
echo "curl_retry=${curl_retry}" >> $GITHUB_ENV
|
||||||
# GAMCFGDIR should be recreated on every run
|
# GAMCFGDIR should be recreated on every run
|
||||||
GAMCFGDIR="${RUNNER_TEMP}/.gam"
|
GAMCFGDIR="${RUNNER_TEMP}/.gam"
|
||||||
if [ "$arch" == "Win64" ]; then
|
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
GAMCFGDIR=$(cygpath -u "$GAMCFGDIR")
|
GAMCFGDIR=$(cygpath -u "$GAMCFGDIR")
|
||||||
fi
|
fi
|
||||||
echo "GAMCFGDIR=${GAMCFGDIR}" >> $GITHUB_ENV
|
echo "GAMCFGDIR=${GAMCFGDIR}" >> $GITHUB_ENV
|
||||||
echo "GAMCFGDIR is: ${GAMCFGDIR}"
|
echo "GAMCFGDIR is: ${GAMCFGDIR}"
|
||||||
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
export GAMOS=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]')
|
||||||
GAMOS="macos"
|
|
||||||
elif [[ "${RUNNER_OS}" == "Linux" ]]; then
|
|
||||||
GAMOS="linux"
|
|
||||||
elif [[ "${RUNNER_OS}" == "Windows" ]]; then
|
|
||||||
GAMOS="windows"
|
|
||||||
else
|
|
||||||
GAMOS='unknown'
|
|
||||||
fi
|
|
||||||
echo "GAMOS=${GAMOS}" >> $GITHUB_ENV
|
echo "GAMOS=${GAMOS}" >> $GITHUB_ENV
|
||||||
echo "GAMOS is: ${GAMOS}"
|
echo "GAMOS is: ${GAMOS}"
|
||||||
|
|
||||||
@@ -232,23 +224,15 @@ jobs:
|
|||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
with:
|
with:
|
||||||
arch: ${{ matrix.arch }}
|
arch: ${{ runner.arch }}
|
||||||
|
|
||||||
- name: Set Env Variables for build
|
- name: Set Env Variables for build
|
||||||
if: matrix.goal == 'build'
|
if: matrix.goal == 'build'
|
||||||
env:
|
env:
|
||||||
openssl_archs: ${{ matrix.openssl_archs }}
|
|
||||||
staticx: ${{ matrix.staticx }}
|
staticx: ${{ matrix.staticx }}
|
||||||
run: |
|
run: |
|
||||||
echo "We are running on ${RUNNER_OS}"
|
echo "We are running on ${RUNNER_OS}"
|
||||||
LD_LIBRARY_PATH="${OPENSSL_INSTALL_PATH}/lib:${PYTHON_INSTALL_PATH}/lib:/usr/local/lib"
|
LD_LIBRARY_PATH="${OPENSSL_INSTALL_PATH}/lib:${PYTHON_INSTALL_PATH}/lib:/usr/local/lib"
|
||||||
if [[ "${arch}" == "Win64" ]]; then
|
|
||||||
PYEXTERNALS_PATH="amd64"
|
|
||||||
PYBUILDRELEASE_ARCH="x64"
|
|
||||||
GAM_ARCHIVE_ARCH="x86_64"
|
|
||||||
WIX_ARCH="x64"
|
|
||||||
CHOC_OPS=""
|
|
||||||
fi
|
|
||||||
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||||
MAKE=make
|
MAKE=make
|
||||||
MAKEOPT="-j$(sysctl -n hw.logicalcpu)"
|
MAKEOPT="-j$(sysctl -n hw.logicalcpu)"
|
||||||
@@ -266,9 +250,17 @@ jobs:
|
|||||||
MAKE=nmake
|
MAKE=nmake
|
||||||
MAKEOPT=""
|
MAKEOPT=""
|
||||||
PERL="c:\strawberry\perl\bin\perl.exe"
|
PERL="c:\strawberry\perl\bin\perl.exe"
|
||||||
|
if [[ "$RUNNER_ARCH" == "ARM64" ]]; then
|
||||||
|
PYEXTERNALS_PATH="arm64"
|
||||||
|
WIX_ARCH="arm64"
|
||||||
|
CHOC_OPS=""
|
||||||
|
elif [[ "$RUNNER_ARCH" == "X64" ]]; then
|
||||||
|
PYEXTERNALS_PATH="amd64"
|
||||||
|
WIX_ARCH="x64"
|
||||||
|
CHOC_OPS=""
|
||||||
|
fi
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_PATH}"
|
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_PATH}"
|
||||||
echo "PYTHON=${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_PATH}/python.exe" >> $GITHUB_ENV
|
echo "PYTHON=${PYTHON_SOURCE_PATH}/PCbuild/${PYEXTERNALS_PATH}/python.exe" >> $GITHUB_ENV
|
||||||
echo "GAM_ARCHIVE_ARCH=${GAM_ARCHIVE_ARCH}" >> $GITHUB_ENV
|
|
||||||
echo "WIX_ARCH=${WIX_ARCH}" >> $GITHUB_ENV
|
echo "WIX_ARCH=${WIX_ARCH}" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
echo "We'll run make with: ${MAKEOPT}"
|
echo "We'll run make with: ${MAKEOPT}"
|
||||||
@@ -278,8 +270,6 @@ jobs:
|
|||||||
echo "MAKEOPT=${MAKEOPT}" >> $GITHUB_ENV
|
echo "MAKEOPT=${MAKEOPT}" >> $GITHUB_ENV
|
||||||
echo "PERL=${PERL}" >> $GITHUB_ENV
|
echo "PERL=${PERL}" >> $GITHUB_ENV
|
||||||
echo "PYEXTERNALS_PATH=${PYEXTERNALS_PATH}" >> $GITHUB_ENV
|
echo "PYEXTERNALS_PATH=${PYEXTERNALS_PATH}" >> $GITHUB_ENV
|
||||||
echo "PYBUILDRELEASE_ARCH=${PYBUILDRELEASE_ARCH}" >> $GITHUB_ENV
|
|
||||||
echo "openssl_archs=${openssl_archs}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Get latest stable OpenSSL source
|
- name: Get latest stable OpenSSL source
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -293,29 +283,21 @@ jobs:
|
|||||||
git checkout "${LATEST_STABLE_TAG}"
|
git checkout "${LATEST_STABLE_TAG}"
|
||||||
export COMPILED_OPENSSL_VERSION=${LATEST_STABLE_TAG:8} # Trim the openssl- prefix
|
export COMPILED_OPENSSL_VERSION=${LATEST_STABLE_TAG:8} # Trim the openssl- prefix
|
||||||
echo "COMPILED_OPENSSL_VERSION=${COMPILED_OPENSSL_VERSION}" >> $GITHUB_ENV
|
echo "COMPILED_OPENSSL_VERSION=${COMPILED_OPENSSL_VERSION}" >> $GITHUB_ENV
|
||||||
if ([ "${RUNNER_OS}" == "macOS" ] && [ "$arch" == "universal2" ]); then
|
|
||||||
for openssl_arch in $openssl_archs; do
|
|
||||||
ssldir="${OPENSSL_SOURCE_PATH}-${openssl_arch}"
|
|
||||||
mkdir -v "${ssldir}"
|
|
||||||
cp -vrf ${OPENSSL_SOURCE_PATH}/* "${ssldir}/"
|
|
||||||
done
|
|
||||||
rm -vrf "${OPENSSL_SOURCE_PATH}"
|
|
||||||
else
|
|
||||||
mv -v "${OPENSSL_SOURCE_PATH}" "${OPENSSL_SOURCE_PATH}-${openssl_archs}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Windows NASM Install
|
- name: Windows NASM Install
|
||||||
uses: ilammy/setup-nasm@v1
|
uses: ilammy/setup-nasm@v1
|
||||||
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os == 'Windows' && runner.arch == 'X64' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
|
|
||||||
- name: Config OpenSSL
|
- name: Config OpenSSL
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
for openssl_arch in $openssl_archs; do
|
cd "${OPENSSL_SOURCE_PATH}"
|
||||||
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
|
# TODO: remove this once https://github.com/openssl/openssl/issues/26239 is fixed.
|
||||||
|
if ([ "$RUNNER_OS" == "Windows" ] && [ "$RUNNER_ARCH" == "ARM64" ]); then
|
||||||
|
export CFLAGS=-DNO_INTERLOCKEDOR64
|
||||||
|
fi
|
||||||
# --libdir=lib is needed so Python can find OpenSSL libraries
|
# --libdir=lib is needed so Python can find OpenSSL libraries
|
||||||
"${PERL}" ./Configure "${openssl_arch}" --libdir=lib --prefix="${OPENSSL_INSTALL_PATH}" $OPENSSL_CONFIG_OPTS
|
"${PERL}" ./Configure --libdir=lib --prefix="${OPENSSL_INSTALL_PATH}" $OPENSSL_CONFIG_OPTS
|
||||||
done
|
|
||||||
|
|
||||||
- name: Rename GNU link on Windows
|
- name: Rename GNU link on Windows
|
||||||
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -326,53 +308,29 @@ jobs:
|
|||||||
- name: Make OpenSSL
|
- name: Make OpenSSL
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
for openssl_arch in $openssl_archs; do
|
cd "${OPENSSL_SOURCE_PATH}"
|
||||||
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
|
# TODO: remove this once https://github.com/openssl/openssl/issues/26239 is fixed.
|
||||||
$MAKE "${MAKEOPT}"
|
if ([ "$RUNNER_OS" == "Windows" ] && [ "$RUNNER_ARCH" == "ARM64" ]); then
|
||||||
done
|
export CFLAGS=-DNO_INTERLOCKEDOR64
|
||||||
|
fi
|
||||||
|
$MAKE "$MAKEOPT"
|
||||||
|
|
||||||
- name: Install OpenSSL
|
- name: Install OpenSSL
|
||||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
if ([ "${RUNNER_OS}" == "macOS" ] && [ "$arch" == "universal2" ]); then
|
cd "${OPENSSL_SOURCE_PATH}"
|
||||||
for openssl_arch in $openssl_archs; do
|
|
||||||
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
|
|
||||||
# install_sw saves us ages processing man pages :-)
|
# install_sw saves us ages processing man pages :-)
|
||||||
$MAKE install_sw
|
$MAKE install_sw
|
||||||
mv -v "${OPENSSL_INSTALL_PATH}" "${GITHUB_WORKSPACE}/bin/ssl-${openssl_arch}"
|
|
||||||
done
|
|
||||||
mkdir -vp "${OPENSSL_INSTALL_PATH}/lib"
|
|
||||||
mkdir -vp "${OPENSSL_INSTALL_PATH}/bin"
|
|
||||||
for archlib in libcrypto.3.dylib libssl.3.dylib libcrypto.a libssl.a; do
|
|
||||||
lipo -create "${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/lib/${archlib}" \
|
|
||||||
"${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64/lib/${archlib}" \
|
|
||||||
-output "${GITHUB_WORKSPACE}/bin/ssl/lib/${archlib}"
|
|
||||||
done
|
|
||||||
mv ${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/include ${GITHUB_WORKSPACE}/bin/ssl/
|
|
||||||
lipo -create "${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64/bin/openssl" \
|
|
||||||
"${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64/bin/openssl" \
|
|
||||||
-output "${GITHUB_WORKSPACE}/bin/ssl/bin/openssl"
|
|
||||||
rm -rf ${GITHUB_WORKSPACE}/bin/ssl-darwin64-x86_64
|
|
||||||
rm -rf ${GITHUB_WORKSPACE}/bin/ssl-darwin64-arm64
|
|
||||||
else
|
|
||||||
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_archs}"
|
|
||||||
# install_sw saves us ages processing man pages :-)
|
|
||||||
$MAKE install_sw
|
|
||||||
fi
|
|
||||||
if [[ "${RUNNER_OS}" != "Windows" ]]; then
|
if [[ "${RUNNER_OS}" != "Windows" ]]; then
|
||||||
echo "LDFLAGS=-L${OPENSSL_INSTALL_PATH}/lib" >> $GITHUB_ENV
|
echo "LDFLAGS=-L${OPENSSL_INSTALL_PATH}/lib" >> $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
echo "CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1" >> $GITHUB_ENV
|
echo "CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1" >> $GITHUB_ENV
|
||||||
case $arch in
|
case $RUNNER_ARCH in
|
||||||
universal2)
|
X64)
|
||||||
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include -arch arm64 -arch x86_64 ${CFLAGS}" >> $GITHUB_ENV
|
|
||||||
echo "ARCHFLAGS=-arch x86_64 -arch arm64" >> $GITHUB_ENV
|
|
||||||
;;
|
|
||||||
x86_64)
|
|
||||||
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include ${CFLAGS}" >> $GITHUB_ENV
|
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include ${CFLAGS}" >> $GITHUB_ENV
|
||||||
echo "ARCHFLAGS=-arch x86_64" >> $GITHUB_ENV
|
echo "ARCHFLAGS=-arch x86_64" >> $GITHUB_ENV
|
||||||
;;
|
;;
|
||||||
aarch64)
|
ARM64)
|
||||||
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include ${CFLAGS}" >> $GITHUB_ENV
|
echo "CFLAGS=-I${OPENSSL_INSTALL_PATH}/include ${CFLAGS}" >> $GITHUB_ENV
|
||||||
echo "ARCHFLAGS=-arch arm64" >> $GITHUB_ENV
|
echo "ARCHFLAGS=-arch arm64" >> $GITHUB_ENV
|
||||||
;;
|
;;
|
||||||
@@ -399,18 +357,12 @@ jobs:
|
|||||||
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
cd "${PYTHON_SOURCE_PATH}"
|
cd "${PYTHON_SOURCE_PATH}"
|
||||||
if ([ "${RUNNER_OS}" == "macOS" ] && [ "$arch" == "universal2" ]); then
|
|
||||||
extra_args=( "--enable-universalsdk" "--with-universal-archs=universal2" )
|
|
||||||
else
|
|
||||||
extra_args=( )
|
|
||||||
fi
|
|
||||||
./configure --with-openssl="${OPENSSL_INSTALL_PATH}" \
|
./configure --with-openssl="${OPENSSL_INSTALL_PATH}" \
|
||||||
--prefix="${PYTHON_INSTALL_PATH}" \
|
--prefix="${PYTHON_INSTALL_PATH}" \
|
||||||
--enable-shared \
|
--enable-shared \
|
||||||
--with-ensurepip=upgrade \
|
--with-ensurepip=upgrade \
|
||||||
--enable-optimizations \
|
--enable-optimizations \
|
||||||
--with-lto \
|
--with-lto || : # exit 0
|
||||||
"${extra_args[@]}" || : # exit 0
|
|
||||||
cat config.log
|
cat config.log
|
||||||
|
|
||||||
- name: Windows Get External Python deps
|
- name: Windows Get External Python deps
|
||||||
@@ -430,10 +382,15 @@ jobs:
|
|||||||
Remove-Item -recurse -force "${env:OPENSSL_EXT_PATH}*"
|
Remove-Item -recurse -force "${env:OPENSSL_EXT_PATH}*"
|
||||||
# Emulate what this script does:
|
# Emulate what this script does:
|
||||||
# https://github.com/python/cpython/blob/main/PCbuild/openssl.vcxproj
|
# https://github.com/python/cpython/blob/main/PCbuild/openssl.vcxproj
|
||||||
$env:OPENSSL_EXT_TARGET_PATH = "${env:OPENSSL_EXT_PATH}${env:PYEXTERNALS_PATH}"
|
if (${env:RUNNER_ARCH} -eq "X64") {
|
||||||
|
$env:ossl_path = "amd64"
|
||||||
|
} elseif (${env:RUNNER_ARCH} -eq "ARM64") {
|
||||||
|
$env:ossl_path = "arm64"
|
||||||
|
}
|
||||||
|
$env:OPENSSL_EXT_TARGET_PATH = "${env:OPENSSL_EXT_PATH}${env:ossl_path}"
|
||||||
echo "Copying our OpenSSL to ${env:OPENSSL_EXT_TARGET_PATH}"
|
echo "Copying our OpenSSL to ${env:OPENSSL_EXT_TARGET_PATH}"
|
||||||
mkdir "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
|
mkdir "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
|
||||||
Copy-Item -Path "${env:GITHUB_WORKSPACE}/src/openssl-${env:openssl_archs}\LICENSE.txt" -Destination "${env:OPENSSL_EXT_TARGET_PATH}\LICENSE" -Verbose
|
Copy-Item -Path "${env:OPENSSL_SOURCE_PATH}\LICENSE.txt" -Destination "${env:OPENSSL_EXT_TARGET_PATH}\LICENSE"
|
||||||
cp -v "$env:OPENSSL_INSTALL_PATH\lib\*" "${env:OPENSSL_EXT_TARGET_PATH}"
|
cp -v "$env:OPENSSL_INSTALL_PATH\lib\*" "${env:OPENSSL_EXT_TARGET_PATH}"
|
||||||
cp -v "$env:OPENSSL_INSTALL_PATH\bin\*" "${env:OPENSSL_EXT_TARGET_PATH}"
|
cp -v "$env:OPENSSL_INSTALL_PATH\bin\*" "${env:OPENSSL_EXT_TARGET_PATH}"
|
||||||
cp -v "$env:OPENSSL_INSTALL_PATH\include\openssl\*" "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
|
cp -v "$env:OPENSSL_INSTALL_PATH\include\openssl\*" "${env:OPENSSL_EXT_TARGET_PATH}\include\openssl\"
|
||||||
@@ -454,8 +411,15 @@ jobs:
|
|||||||
cd "${env:PYTHON_SOURCE_PATH}"
|
cd "${env:PYTHON_SOURCE_PATH}"
|
||||||
# We need out custom openssl.props which uses OpenSSL 3 DLL names
|
# We need out custom openssl.props which uses OpenSSL 3 DLL names
|
||||||
Copy-Item -Path "${env:GITHUB_WORKSPACE}\src\tools\openssl.props" -Destination PCBuild\ -Verbose
|
Copy-Item -Path "${env:GITHUB_WORKSPACE}\src\tools\openssl.props" -Destination PCBuild\ -Verbose
|
||||||
echo "Building for ${env:PYBUILDRELEASE_ARCH}..."
|
if (${env:RUNNER_ARCH} -eq "X64") {
|
||||||
PCBuild\build.bat -m --pgo -c Release -p "${env:PYBUILDRELEASE_ARCH}"
|
$env:arch = "x64"
|
||||||
|
PCBuild\build.bat -c Release -p $env:arch --pgo
|
||||||
|
} elseif (${env:RUNNER_ARCH} -eq "ARM64") {
|
||||||
|
$env:arch = "ARM64"
|
||||||
|
# TODO: figure out why Windows ARM64 isn't compat with PGO optimiazation
|
||||||
|
# causes 10-20% slowdown in Python
|
||||||
|
PCBuild\build.bat -c Release -p $env:arch
|
||||||
|
}
|
||||||
|
|
||||||
- name: Mac/Linux Build Python
|
- name: Mac/Linux Build Python
|
||||||
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
if: matrix.goal == 'build' && runner.os != 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||||
@@ -482,46 +446,33 @@ jobs:
|
|||||||
- name: Upgrade pip, wheel, etc
|
- name: Upgrade pip, wheel, etc
|
||||||
run: |
|
run: |
|
||||||
curl $curl_retry -O https://bootstrap.pypa.io/get-pip.py
|
curl $curl_retry -O https://bootstrap.pypa.io/get-pip.py
|
||||||
"${PYTHON}" get-pip.py
|
"$PYTHON" get-pip.py
|
||||||
"${PYTHON}" -m pip install --upgrade pip
|
"$PYTHON" -m pip install --upgrade pip
|
||||||
"${PYTHON}" -m pip install --upgrade wheel
|
"$PYTHON" -m pip install --upgrade wheel
|
||||||
"${PYTHON}" -m pip install --upgrade setuptools
|
"$PYTHON" -m pip install --upgrade setuptools
|
||||||
|
|
||||||
|
- name: Custom wheels for Win arm64
|
||||||
|
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
||||||
|
run: |
|
||||||
|
latest_lxml_whl=$(curl https://api.github.com/repos/GAM-team/lxml-wheel/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
||||||
|
echo "Downloading ${latest_lxml_whl}..."
|
||||||
|
curl -O -L "$latest_lxml_whl"
|
||||||
|
"$PYTHON" -m pip install lxml*.whl
|
||||||
|
latest_crypt_whl=$(curl https://api.github.com/repos/jay0lee/cryptography/releases/latest -s | jq -r .assets.[0].browser_download_url)
|
||||||
|
echo "Downloading ${latest_crypt_whl}..."
|
||||||
|
curl -O -L "$latest_crypt_whl"
|
||||||
|
"$PYTHON" -m pip install cryptography*.whl
|
||||||
|
|
||||||
- name: Install pip requirements
|
- name: Install pip requirements
|
||||||
run: |
|
run: |
|
||||||
echo "before anything..."
|
echo "before anything..."
|
||||||
"${PYTHON}" -m pip list
|
"$PYTHON" -m pip list
|
||||||
if ([ "${RUNNER_OS}" == "macOS" ] && [ "$arch" == "universal2" ]); then
|
"$PYTHON" -m pip install --upgrade -r requirements.txt
|
||||||
# cffi is a dep of cryptography and doesn't ship
|
|
||||||
# a universal2 wheel so we must build one ourself :-/
|
|
||||||
export CFLAGS="-arch x86_64 -arch arm64"
|
|
||||||
export ARCHFLAGS="-arch x86_64 -arch arm64"
|
|
||||||
"${PYTHON}" -m pip install --upgrade --force-reinstall --no-binary :all: \
|
|
||||||
--no-cache-dir --no-deps --use-pep517 \
|
|
||||||
--use-feature=no-binary-enable-wheel-cache \
|
|
||||||
cffi
|
|
||||||
echo "before cryptography..."
|
|
||||||
"${PYTHON}" -m pip list
|
|
||||||
# cryptography has a universal2 wheel but getting it installed
|
|
||||||
# on x86-64 MacOS is a royal pain in the keester.
|
|
||||||
"${PYTHON}" -m pip download --only-binary :all: \
|
|
||||||
--dest . \
|
|
||||||
--no-cache \
|
|
||||||
--no-deps \
|
|
||||||
--platform macosx_10_15_universal2 \
|
|
||||||
cryptography
|
|
||||||
"${PYTHON}" -m pip install --force-reinstall --no-deps cryptography*.whl
|
|
||||||
echo "after cryptography..."
|
|
||||||
"${PYTHON}" -m pip list
|
|
||||||
"${PYTHON}" -m pip install --upgrade --no-binary :all: -r requirements.txt
|
|
||||||
else
|
|
||||||
"${PYTHON}" -m pip install --upgrade -r requirements.txt
|
|
||||||
echo "after requirements..."
|
echo "after requirements..."
|
||||||
"${PYTHON}" -m pip list
|
"$PYTHON" -m pip list
|
||||||
"${PYTHON}" -m pip install --force-reinstall --no-deps --upgrade cryptography
|
#"$PYTHON" -m pip install --force-reinstall --no-deps --upgrade cryptography
|
||||||
fi
|
|
||||||
echo "after everything..."
|
echo "after everything..."
|
||||||
"${PYTHON}" -m pip list
|
"$PYTHON" -m pip list
|
||||||
|
|
||||||
- name: Install PyInstaller
|
- name: Install PyInstaller
|
||||||
if: matrix.goal == 'build'
|
if: matrix.goal == 'build'
|
||||||
@@ -534,14 +485,7 @@ jobs:
|
|||||||
# remove pre-compiled bootloaders so we fail if bootloader compile fails
|
# remove pre-compiled bootloaders so we fail if bootloader compile fails
|
||||||
rm -rvf PyInstaller/bootloader/*-*/*
|
rm -rvf PyInstaller/bootloader/*-*/*
|
||||||
cd bootloader
|
cd bootloader
|
||||||
export PYINSTALLER_BUILD_ARGS=""
|
"${PYTHON}" ./waf all
|
||||||
case "${arch}" in
|
|
||||||
"Win64")
|
|
||||||
export PYINSTALLER_BUILD_ARGS="--target-arch=64bit"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
echo "PyInstaller build arguments: ${PYINSTALLER_BUILD_ARGS}"
|
|
||||||
"${PYTHON}" ./waf all $PYINSTALLER_BUILD_ARGS
|
|
||||||
cd ..
|
cd ..
|
||||||
echo "---- Installing PyInstaller ----"
|
echo "---- Installing PyInstaller ----"
|
||||||
"${PYTHON}" -m pip install .
|
"${PYTHON}" -m pip install .
|
||||||
@@ -652,14 +596,12 @@ jobs:
|
|||||||
echo "GAM Version ${GAMVERSION}"
|
echo "GAM Version ${GAMVERSION}"
|
||||||
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Configure service account auth
|
- name: Configure user and service account auth
|
||||||
id: configserviceaccount
|
id: configserviceaccount
|
||||||
env:
|
env:
|
||||||
PASSCODE: ${{ secrets.PASSCODE }}
|
oa2: ${{ secrets[format('GAM_GHA_{0}', matrix.jid)] }}
|
||||||
run: |
|
run: |
|
||||||
source ../.github/actions/decrypt.sh ../.github/actions/creds.tar.xz.gpg creds.tar.xz "${GAMCFGDIR}"
|
../.github/actions/decrypt.sh "${GAMCFGDIR}"
|
||||||
mv -v "${GAMCFGDIR}/oauth2.txt-gam-gha-${JID}" "${GAMCFGDIR}/oauth2.txt"
|
|
||||||
rm -v $GAMCFGDIR/oauth2.txt-gam*
|
|
||||||
$gam create signjwtserviceaccount
|
$gam create signjwtserviceaccount
|
||||||
|
|
||||||
- name: Upload gam.exe Windows for signing
|
- name: Upload gam.exe Windows for signing
|
||||||
@@ -707,22 +649,29 @@ jobs:
|
|||||||
else
|
else
|
||||||
libver="glibc$(ldd --version | awk '/ldd/{print $NF}')"
|
libver="glibc$(ldd --version | awk '/ldd/{print $NF}')"
|
||||||
fi
|
fi
|
||||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-linux-$(arch)-${libver}.tar.xz"
|
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-linux-${arch}-${libver}.tar.xz"
|
||||||
fi
|
fi
|
||||||
echo "GAM Archive ${GAM_ARCHIVE}"
|
echo "GAM Archive ${GAM_ARCHIVE}"
|
||||||
tar -C "${gampath}/.." --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam7
|
tar -C "${gampath}/.." --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam7
|
||||||
|
|
||||||
- name: Windows package
|
- name: Install Wix on Win ARM64
|
||||||
|
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
||||||
|
run: |
|
||||||
|
choco install wixtoolset
|
||||||
|
|
||||||
|
- name: Windows package zip
|
||||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||||
run: |
|
run: |
|
||||||
echo "started in $(pwd)"
|
echo "started in $(pwd)"
|
||||||
cd "${gampath}/.."
|
cd "${gampath}/.."
|
||||||
echo "moved to $(pwd)"
|
echo "moved to $(pwd)"
|
||||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.zip"
|
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${arch}.zip"
|
||||||
/c/Program\ Files/7-Zip/7z.exe a -tzip "$GAM_ARCHIVE" gam7 "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
/c/Program\ Files/7-Zip/7z.exe a -tzip "$GAM_ARCHIVE" gam7 "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
||||||
cd ../..
|
|
||||||
echo "moved to $(pwd)"
|
- name: Windows package MSI
|
||||||
export MSI_FILENAME="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.msi"
|
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||||
|
run: |
|
||||||
|
export MSI_FILENAME="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${arch}.msi"
|
||||||
# auto-generate a lib.wxs based on the files PyInstaller created for the lib/ directory
|
# auto-generate a lib.wxs based on the files PyInstaller created for the lib/ directory
|
||||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/heat.exe dir "${gampath}/lib" -ke -srd -cg Lib -gg -dr lib -directoryid lib -out lib.wxs
|
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/heat.exe dir "${gampath}/lib" -ke -srd -cg Lib -gg -dr lib -directoryid lib -out lib.wxs
|
||||||
$PYTHON tools/gen-wix-xml-filelist.py lib.wxs
|
$PYTHON tools/gen-wix-xml-filelist.py lib.wxs
|
||||||
|
|||||||
@@ -7163,7 +7163,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize] [showlastmodification]
|
[showsize] [showmimetypesize]
|
||||||
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
(addcsvdata <FieldName> <String>)*
|
(addcsvdata <FieldName> <String>)*
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
gam <UserTypeEntity> show filecounts
|
gam <UserTypeEntity> show filecounts
|
||||||
@@ -7178,7 +7179,8 @@ gam <UserTypeEntity> show filecounts
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize] [showlastmodification]
|
[showsize] [showmimetypesize]
|
||||||
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
|
|
||||||
gam <UserTypeEntity> print filesharecounts [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print filesharecounts [todrive <ToDriveAttribute>*]
|
||||||
@@ -7308,6 +7310,14 @@ gam <UserTypeEntity> print driveactivity [todrive <ToDriveAttribute>*]
|
|||||||
usageindrivetrash
|
usageindrivetrash
|
||||||
<DriveSettingsFieldNameList> ::= "<DriveSettingsFieldName>(,<DriveSettingsFieldName>)*"
|
<DriveSettingsFieldNameList> ::= "<DriveSettingsFieldName>(,<DriveSettingsFieldName>)*"
|
||||||
|
|
||||||
|
gam <UserTypeEntity> print drivelastmodification [todrive <ToDriveAttribute>*]
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
(addcsvdata <FieldName> <String>)*
|
||||||
|
gam <UserTypeEntity> show drivelastmodification
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
|
||||||
gam <UserTypeEntity> print drivesettings [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> print drivesettings [todrive <ToDriveAttribute>*]
|
||||||
[allfields|<DriveSettingsFieldName>*|(fields <DriveSettingsFieldNameList>)]
|
[allfields|<DriveSettingsFieldName>*|(fields <DriveSettingsFieldNameList>)]
|
||||||
[delimiter <Character>] [showusagebytes]
|
[delimiter <Character>] [showusagebytes]
|
||||||
|
|||||||
@@ -1,8 +1,46 @@
|
|||||||
|
7.06.06
|
||||||
|
|
||||||
|
Native support for Windows 11 Arm-based devices.
|
||||||
|
|
||||||
|
7.06.05
|
||||||
|
|
||||||
|
Updated code in `gam delete|update chromepolicy` to handle the `policyTargetKey[additionalTargetKeys]`
|
||||||
|
field in a more general manner for future use.
|
||||||
|
|
||||||
|
7.06.04
|
||||||
|
|
||||||
|
Fixed bug in `gam report <ActivityApplictionName>` where a report with no activities
|
||||||
|
was not displaying any output.
|
||||||
|
|
||||||
|
7.06.03
|
||||||
|
|
||||||
|
Fixed bug in `gam <UserTypeEntity> print|show drivelastmodification` that caused a trap
|
||||||
|
when an empty drive was specified.
|
||||||
|
|
||||||
|
7.06.02
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> print|show filecounts ... showlastmodification` to include
|
||||||
|
file mimetype and path information for the last modified file.
|
||||||
|
|
||||||
|
Added simple commands to get information about the last modified file on a drive.
|
||||||
|
By default, a user's My Drive is processed; optionally, a Shared Drive can be processed.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> print drivelastmodification [todrive <ToDriveAttribute>*]
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
(addcsvdata <FieldName> <String>)*
|
||||||
|
gam <UserTypeEntity> show drivelastmodification
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
```
|
||||||
|
|
||||||
7.06.01
|
7.06.01
|
||||||
|
|
||||||
Updated `gam <UserTypeEntity> create|update drivefileacl ... expiration <Time>`
|
Updated `gam <UserTypeEntity> create|update drivefileacl ... expiration <Time>`
|
||||||
to handle additional API errors.
|
to handle additional API errors.
|
||||||
|
|
||||||
|
Updated to Python 3.13.3.
|
||||||
|
|
||||||
7.06.00
|
7.06.00
|
||||||
|
|
||||||
Upgraded to OpenSSL 3.5.0.
|
Upgraded to OpenSSL 3.5.0.
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ fi
|
|||||||
case $gamos in
|
case $gamos in
|
||||||
[lL]inux)
|
[lL]inux)
|
||||||
gamos="linux"
|
gamos="linux"
|
||||||
download_urls=$(echo -e "$download_urls" | grep "\-linux-")
|
download_urls=$(echo -e "$download_urls" | grep -e "-linux-")
|
||||||
if [ "$osversion" == "" ]; then
|
if [ "$osversion" == "" ]; then
|
||||||
this_glibc_ver=$(ldd --version | awk '/ldd/{print $NF}')
|
this_glibc_ver=$(ldd --version | awk '/ldd/{print $NF}')
|
||||||
else
|
else
|
||||||
@@ -203,7 +203,7 @@ case $gamos in
|
|||||||
echo "This Linux distribution uses glibc $this_glibc_ver"
|
echo "This Linux distribution uses glibc $this_glibc_ver"
|
||||||
case $gamarch in
|
case $gamarch in
|
||||||
x86_64)
|
x86_64)
|
||||||
download_urls=$(echo -e "$download_urls" | grep "\-x86_64-")
|
download_urls=$(echo -e "$download_urls" | grep -e "-x86_64-")
|
||||||
gam_x86_64_glibc_vers=$(echo -e "$download_urls" | \
|
gam_x86_64_glibc_vers=$(echo -e "$download_urls" | \
|
||||||
grep --only-matching 'glibc[0-9\.]*\.tar\.xz$' \
|
grep --only-matching 'glibc[0-9\.]*\.tar\.xz$' \
|
||||||
| cut -c 6-9 )
|
| cut -c 6-9 )
|
||||||
@@ -218,7 +218,7 @@ case $gamos in
|
|||||||
download_url=$(echo -e "$download_urls" | grep "$useglibc")
|
download_url=$(echo -e "$download_urls" | grep "$useglibc")
|
||||||
;;
|
;;
|
||||||
arm|arm64|aarch64)
|
arm|arm64|aarch64)
|
||||||
download_urls=$(echo -e "$download_urls" | grep "\-aarch64-")
|
download_urls=$(echo -e "$download_urls" | grep -e "-arm64-\|-aarch64-")
|
||||||
gam_arm64_glibc_vers=$(echo -e "$download_urls" | \
|
gam_arm64_glibc_vers=$(echo -e "$download_urls" | \
|
||||||
grep --only-matching 'glibc[0-9\.]*\.tar\.xz$' | \
|
grep --only-matching 'glibc[0-9\.]*\.tar\.xz$' | \
|
||||||
cut -c 6-9)
|
cut -c 6-9)
|
||||||
@@ -243,13 +243,13 @@ case $gamos in
|
|||||||
# override osversion only if it wasn't set by cli arguments
|
# override osversion only if it wasn't set by cli arguments
|
||||||
osversion=${osversion:-${currentversion}}
|
osversion=${osversion:-${currentversion}}
|
||||||
# override osversion only if it wasn't set by cli arguments
|
# override osversion only if it wasn't set by cli arguments
|
||||||
download_urls=$(echo -e "$download_urls" | grep "\-macos")
|
download_urls=$(echo -e "$download_urls" | grep -e "-macos")
|
||||||
case $gamarch in
|
case $gamarch in
|
||||||
x86_64)
|
x86_64)
|
||||||
archgrep="\-x86_64"
|
archgrep="-x86_64"
|
||||||
;;
|
;;
|
||||||
arm|arm64|aarch64)
|
arm|arm64|aarch64)
|
||||||
archgrep="\-aarch64"
|
archgrep="-arm64\|-aarch64"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo_red "ERROR: this installer currently only supports x86_64 and arm64 MacOS. Looks like you're running on ${gamarch}. Exiting."
|
echo_red "ERROR: this installer currently only supports x86_64 and arm64 MacOS. Looks like you're running on ${gamarch}. Exiting."
|
||||||
@@ -257,13 +257,13 @@ case $gamos in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
gam_macos_urls=$(echo -e "$download_urls" | \
|
gam_macos_urls=$(echo -e "$download_urls" | \
|
||||||
grep "$archgrep")
|
grep -e $archgrep)
|
||||||
versionless_urls=$(echo -e "$gam_macos_urls" | \
|
versionless_urls=$(echo -e "$gam_macos_urls" | \
|
||||||
grep "\-macos-")
|
grep -e "-macos-")
|
||||||
if [ "$versionless_urls" == "" ]; then
|
if [ "$versionless_urls" == "" ]; then
|
||||||
# versions after 7.00.38 include MacOS version info
|
# versions after 7.00.38 include MacOS version info
|
||||||
gam_macos_vers=$(echo -e "$gam_macos_urls" | \
|
gam_macos_vers=$(echo -e "$gam_macos_urls" | \
|
||||||
grep --only-matching '\-macos[0-9\.]*' | \
|
grep --only-matching -e '-macos[0-9\.]*' | \
|
||||||
cut -c 7-10)
|
cut -c 7-10)
|
||||||
for gam_mac_ver in $gam_macos_vers; do
|
for gam_mac_ver in $gam_macos_vers; do
|
||||||
if version_gt $currentversion $gam_mac_ver; then
|
if version_gt $currentversion $gam_mac_ver; then
|
||||||
@@ -281,13 +281,12 @@ case $gamos in
|
|||||||
case $gamarch in
|
case $gamarch in
|
||||||
x86_64)
|
x86_64)
|
||||||
minimum_version=13
|
minimum_version=13
|
||||||
download_url=$(echo -e "$download_urls" | grep "\-x86_64")
|
|
||||||
;;
|
;;
|
||||||
arm|arm64|aarch64)
|
arm|arm64|aarch64)
|
||||||
download_url=$(echo -e "$download_urls" | grep "\-aarch64")
|
|
||||||
minimum_version=14
|
minimum_version=14
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
download_url=$(echo -e "$download_urls" | grep -e $archgrep)
|
||||||
if version_gt "$osversion" "$minimum_version"; then
|
if version_gt "$osversion" "$minimum_version"; then
|
||||||
echo_green "You are running MacOS ${osversion}, good. Downloading GAM from ${download_url}."
|
echo_green "You are running MacOS ${osversion}, good. Downloading GAM from ${download_url}."
|
||||||
else
|
else
|
||||||
@@ -304,7 +303,7 @@ case $gamos in
|
|||||||
gamos="windows"
|
gamos="windows"
|
||||||
echo "You are running Windows"
|
echo "You are running Windows"
|
||||||
download_url=$(echo -e "$download_urls" | \
|
download_url=$(echo -e "$download_urls" | \
|
||||||
grep "\-windows-" | \
|
grep -e "-windows-" | \
|
||||||
grep ".zip")
|
grep ".zip")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||||
__version__ = '7.06.01'
|
__version__ = '7.06.06'
|
||||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||||
|
|
||||||
#pylint: disable=wrong-import-position
|
#pylint: disable=wrong-import-position
|
||||||
@@ -14145,6 +14145,7 @@ def doReport():
|
|||||||
startDateTime += oneDay
|
startDateTime += oneDay
|
||||||
csvPF.writeCSVfile(f'Customer Report - {tryDate}')
|
csvPF.writeCSVfile(f'Customer Report - {tryDate}')
|
||||||
else: # activityReports
|
else: # activityReports
|
||||||
|
csvPF.SetTitles('name')
|
||||||
if addCSVData:
|
if addCSVData:
|
||||||
csvPF.AddTitles(sorted(addCSVData.keys()))
|
csvPF.AddTitles(sorted(addCSVData.keys()))
|
||||||
if select:
|
if select:
|
||||||
@@ -14304,7 +14305,6 @@ def doReport():
|
|||||||
if addCSVData:
|
if addCSVData:
|
||||||
row.update(addCSVData)
|
row.update(addCSVData)
|
||||||
csvPF.WriteRowTitles(row)
|
csvPF.WriteRowTitles(row)
|
||||||
csvPF.SetSortTitles(['name'])
|
|
||||||
else:
|
else:
|
||||||
if eventRowFilter:
|
if eventRowFilter:
|
||||||
csvPF.SetRowFilter([], GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE])
|
csvPF.SetRowFilter([], GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE])
|
||||||
@@ -28090,10 +28090,12 @@ def updatePolicyRequests(body, targetResource, printer_id, app_id):
|
|||||||
for request in body['requests']:
|
for request in body['requests']:
|
||||||
request.setdefault('policyTargetKey', {})
|
request.setdefault('policyTargetKey', {})
|
||||||
request['policyTargetKey']['targetResource'] = targetResource
|
request['policyTargetKey']['targetResource'] = targetResource
|
||||||
|
if app_id or printer_id:
|
||||||
|
request['policyTargetKey'].setdefault('additionalTargetKeys', {})
|
||||||
if app_id:
|
if app_id:
|
||||||
request['policyTargetKey']['additionalTargetKeys'] = {'app_id': app_id}
|
request['policyTargetKey']['additionalTargetKeys']['app_id'] = app_id
|
||||||
elif printer_id:
|
elif printer_id:
|
||||||
request['policyTargetKey']['additionalTargetKeys'] = {'printer_id': printer_id}
|
request['policyTargetKey']['additionalTargetKeys']['printer_id'] = printer_id
|
||||||
|
|
||||||
# gam delete chromepolicy
|
# gam delete chromepolicy
|
||||||
# (<SchemaName> [<JSONData>])+
|
# (<SchemaName> [<JSONData>])+
|
||||||
@@ -28126,9 +28128,9 @@ def doDeleteChromePolicy():
|
|||||||
if checkArgumentPresent('json'):
|
if checkArgumentPresent('json'):
|
||||||
jsonData = getJSON(['direct', 'name', 'orgUnitPath', 'parentOrgUnitPath', 'group'])
|
jsonData = getJSON(['direct', 'name', 'orgUnitPath', 'parentOrgUnitPath', 'group'])
|
||||||
if 'additionalTargetKeys' in jsonData:
|
if 'additionalTargetKeys' in jsonData:
|
||||||
body['requests'][-1].setdefault('policyTargetKey', {})
|
body['requests'][-1].setdefault('policyTargetKey', {'additionalTargetKeys': {}})
|
||||||
for atk in jsonData['additionalTargetKeys']:
|
for atk in jsonData['additionalTargetKeys']:
|
||||||
body['requests'][-1]['policyTargetKey']['additionalTargetKeys'] = {atk['name']: atk['value']}
|
body['requests'][-1]['policyTargetKey']['additionalTargetKeys'][atk['name']] = atk['value']
|
||||||
checkPolicyArgs(targetResource, printer_id, app_id)
|
checkPolicyArgs(targetResource, printer_id, app_id)
|
||||||
count = len(body['requests'])
|
count = len(body['requests'])
|
||||||
if count != 1:
|
if count != 1:
|
||||||
@@ -28152,10 +28154,18 @@ CHROME_SCHEMA_TYPE_MESSAGE = {
|
|||||||
{'autoupdatecheckperiodminutesnew':
|
{'autoupdatecheckperiodminutesnew':
|
||||||
{'casedField': 'autoUpdateCheckPeriodMinutesNew',
|
{'casedField': 'autoUpdateCheckPeriodMinutesNew',
|
||||||
'type': 'duration', 'minVal': 1, 'maxVal': 720, 'scale': 60}},
|
'type': 'duration', 'minVal': 1, 'maxVal': 720, 'scale': 60}},
|
||||||
|
'chrome.users.AutoUpdateCheckPeriodNewV2':
|
||||||
|
{'autoupdatecheckperiodminutesnew':
|
||||||
|
{'casedField': 'autoUpdateCheckPeriodMinutesNew',
|
||||||
|
'type': 'duration', 'minVal': 1, 'maxVal': 720, 'scale': 60}},
|
||||||
'chrome.users.BrowserSwitcherDelayDuration':
|
'chrome.users.BrowserSwitcherDelayDuration':
|
||||||
{'browserswitcherdelayduration':
|
{'browserswitcherdelayduration':
|
||||||
{'casedField': 'browserSwitcherDelayDuration',
|
{'casedField': 'browserSwitcherDelayDuration',
|
||||||
'type': 'duration', 'minVal': 0, 'maxVal': 30, 'scale': 1}},
|
'type': 'duration', 'minVal': 0, 'maxVal': 30, 'scale': 1}},
|
||||||
|
'chrome.users.CloudReportingUploadFrequencyV2':
|
||||||
|
{'cloudreportinguploadfrequency':
|
||||||
|
{'casedField': 'cloudReportingUploadFrequency',
|
||||||
|
'type': 'count', 'minVal': 3, 'maxVal': 24, 'scale': 1}},
|
||||||
'chrome.users.FetchKeepaliveDurationSecondsOnShutdown':
|
'chrome.users.FetchKeepaliveDurationSecondsOnShutdown':
|
||||||
{'fetchkeepalivedurationsecondsonshutdown':
|
{'fetchkeepalivedurationsecondsonshutdown':
|
||||||
{'casedField': 'fetchKeepaliveDurationSecondsOnShutdown',
|
{'casedField': 'fetchKeepaliveDurationSecondsOnShutdown',
|
||||||
@@ -28172,6 +28182,10 @@ CHROME_SCHEMA_TYPE_MESSAGE = {
|
|||||||
{'printjobhistoryexpirationperioddaysnew':
|
{'printjobhistoryexpirationperioddaysnew':
|
||||||
{'casedField': 'printJobHistoryExpirationPeriodDaysNew',
|
{'casedField': 'printJobHistoryExpirationPeriodDaysNew',
|
||||||
'type': 'duration', 'minVal': -1, 'maxVal': None, 'scale': 86400}},
|
'type': 'duration', 'minVal': -1, 'maxVal': None, 'scale': 86400}},
|
||||||
|
'chrome.users.RelaunchNotificationWithDurationV2':
|
||||||
|
{'relaunchnotificationperiodduration':
|
||||||
|
{'casedField': 'relaunchNotificationPeriodDuration',
|
||||||
|
'type': 'duration', 'minVal': -1, 'maxVal': None, 'scale': 3600}},
|
||||||
'chrome.users.SecurityTokenSessionSettings':
|
'chrome.users.SecurityTokenSessionSettings':
|
||||||
{'securitytokensessionnotificationseconds':
|
{'securitytokensessionnotificationseconds':
|
||||||
{'casedField': 'securityTokenSessionNotificationSeconds',
|
{'casedField': 'securityTokenSessionNotificationSeconds',
|
||||||
@@ -28269,9 +28283,9 @@ def doUpdateChromePolicy():
|
|||||||
jsonData = getJSON(['direct', 'name', 'orgUnitPath', 'parentOrgUnitPath', 'group'])
|
jsonData = getJSON(['direct', 'name', 'orgUnitPath', 'parentOrgUnitPath', 'group'])
|
||||||
schemaNameAppId = schemaName
|
schemaNameAppId = schemaName
|
||||||
if 'additionalTargetKeys' in jsonData:
|
if 'additionalTargetKeys' in jsonData:
|
||||||
body['requests'][-1].setdefault('policyTargetKey', {})
|
body['requests'][-1].setdefault('policyTargetKey', {'additionalTargetKeys': {}})
|
||||||
for atk in jsonData['additionalTargetKeys']:
|
for atk in jsonData['additionalTargetKeys']:
|
||||||
body['requests'][-1]['policyTargetKey']['additionalTargetKeys'] = {atk['name']: atk['value']}
|
body['requests'][-1]['policyTargetKey']['additionalTargetKeys'][atk['name']] = atk['value']
|
||||||
if atk['name'] == 'app_id':
|
if atk['name'] == 'app_id':
|
||||||
schemaNameAppId += f"({atk['value']})"
|
schemaNameAppId += f"({atk['value']})"
|
||||||
schemaNameList[-1] = schemaNameAppId
|
schemaNameList[-1] = schemaNameAppId
|
||||||
@@ -56474,6 +56488,45 @@ def printFileParentTree(users):
|
|||||||
kcount -= 1
|
kcount -= 1
|
||||||
csvPF.writeCSVfile('Drive File Parent Tree')
|
csvPF.writeCSVfile('Drive File Parent Tree')
|
||||||
|
|
||||||
|
# Last file modification utilities
|
||||||
|
def _initLastModification():
|
||||||
|
return {'lastModifiedFileId': '', 'lastModifiedFileName': '',
|
||||||
|
'lastModifiedFileMimeType': '', 'lastModifiedFilePath': '',
|
||||||
|
'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME,
|
||||||
|
'fileEntryInfo': {}}
|
||||||
|
|
||||||
|
def _checkUpdateLastModifiction(f_file, userLastModification):
|
||||||
|
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['lastModifiedFileMimeType'] = f_file['mimeType']
|
||||||
|
userLastModification['lastModifiedTime'] = f_file['modifiedTime']
|
||||||
|
userLastModification['lastModifyingUser'] = f_file['lastModifyingUser'].get('emailAddress',
|
||||||
|
f_file['lastModifyingUser'].get('displayName', UNKNOWN))
|
||||||
|
userLastModification['fileEntryInfo'] = f_file.copy()
|
||||||
|
|
||||||
|
def _getLastModificationPath(drive, userLastModification, pathDelimiter):
|
||||||
|
if userLastModification['fileEntryInfo']:
|
||||||
|
filePathInfo = initFilePathInfo(pathDelimiter)
|
||||||
|
_, paths, _ = getFilePaths(drive, {}, userLastModification['fileEntryInfo'], filePathInfo)
|
||||||
|
userLastModification['lastModifiedFilePath'] = paths[0] if paths else UNKNOWN
|
||||||
|
|
||||||
|
def _showLastModification(lastModification):
|
||||||
|
printKeyValueList(['lastModifiedFileId', lastModification['lastModifiedFileId']])
|
||||||
|
printKeyValueList(['lastModifiedFileName', lastModification['lastModifiedFileName']])
|
||||||
|
printKeyValueList(['lastModifiedFileMimeType', lastModification['lastModifiedFileMimeType']])
|
||||||
|
printKeyValueList(['lastModifiedFilePath', lastModification['lastModifiedFilePath']])
|
||||||
|
printKeyValueList(['lastModifyingUser', lastModification['lastModifyingUser']])
|
||||||
|
printKeyValueList(['lastModifiedTime', formatLocalTime(lastModification['lastModifiedTime'])])
|
||||||
|
|
||||||
|
def _updateLastModificationRow(row, lastModification):
|
||||||
|
row.update({'lastModifiedFileId': lastModification['lastModifiedFileId'],
|
||||||
|
'lastModifiedFileName': lastModification['lastModifiedFileName'],
|
||||||
|
'lastModifiedFileMimeType': lastModification['lastModifiedFileMimeType'],
|
||||||
|
'lastModifiedFilePath': lastModification['lastModifiedFilePath'],
|
||||||
|
'lastModifyingUser': lastModification['lastModifyingUser'],
|
||||||
|
'lastModifiedTime': formatLocalTime(lastModification['lastModifiedTime'])})
|
||||||
|
|
||||||
# gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
# gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
||||||
# [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)*]
|
# [((query <QueryDriveFile>) | (fullquery <QueryDriveFile>) | <DriveFileQueryShortcut>) (querytime<String> <Time>)*]
|
||||||
# [continueoninvalidquery [<Boolean>]]
|
# [continueoninvalidquery [<Boolean>]]
|
||||||
@@ -56485,7 +56538,8 @@ def printFileParentTree(users):
|
|||||||
# [filenamematchpattern <REMatchPattern>]
|
# [filenamematchpattern <REMatchPattern>]
|
||||||
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
# [excludetrashed] (addcsvdata <FieldName> <String>)*
|
# [excludetrashed] (addcsvdata <FieldName> <String>)*
|
||||||
# [showsize] [showmimetypesize] [showlastmodification]
|
# [showsize] [showmimetypesize]
|
||||||
|
# [showlastmodification] [pathdelimiter <Character>]
|
||||||
# (addcsvdata <FieldName> <String>)*
|
# (addcsvdata <FieldName> <String>)*
|
||||||
# [summary none|only|plus] [summaryuser <String>]
|
# [summary none|only|plus] [summaryuser <String>]
|
||||||
# gam <UserTypeEntity> show filecounts
|
# gam <UserTypeEntity> show filecounts
|
||||||
@@ -56499,7 +56553,8 @@ def printFileParentTree(users):
|
|||||||
# [filenamematchpattern <REMatchPattern>]
|
# [filenamematchpattern <REMatchPattern>]
|
||||||
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
# <PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
# [excludetrashed]
|
# [excludetrashed]
|
||||||
# [showsize] [showmimetypesize] [showlastmodification]
|
# [showsize] [showmimetypesize]
|
||||||
|
# [showlastmodification] [pathdelimiter <Character>]
|
||||||
# [summary none|only|plus] [summaryuser <String>]
|
# [summary none|only|plus] [summaryuser <String>]
|
||||||
def printShowFileCounts(users):
|
def printShowFileCounts(users):
|
||||||
def _setSelectionFields():
|
def _setSelectionFields():
|
||||||
@@ -56508,7 +56563,7 @@ def printShowFileCounts(users):
|
|||||||
if showSize or (DLP.minimumFileSize is not None) or (DLP.maximumFileSize is not None):
|
if showSize or (DLP.minimumFileSize is not None) or (DLP.maximumFileSize is not None):
|
||||||
fieldsList.append(sizeField)
|
fieldsList.append(sizeField)
|
||||||
if showLastModification:
|
if showLastModification:
|
||||||
fieldsList.extend(['id,name,modifiedTime,lastModifyingUser(me, displayName, emailAddress)'])
|
fieldsList.extend(['id,name,modifiedTime,lastModifyingUser(me, displayName, emailAddress),parents'])
|
||||||
if DLP.filenameMatchPattern:
|
if DLP.filenameMatchPattern:
|
||||||
fieldsList.append('name')
|
fieldsList.append('name')
|
||||||
if DLP.excludeTrashed:
|
if DLP.excludeTrashed:
|
||||||
@@ -56544,9 +56599,7 @@ def printShowFileCounts(users):
|
|||||||
printEntityKVList(kvList, dataList, i, count)
|
printEntityKVList(kvList, dataList, i, count)
|
||||||
Ind.Increment()
|
Ind.Increment()
|
||||||
if showLastModification:
|
if showLastModification:
|
||||||
printKeyValueList(['lastModifiedFile', f"{lastModification['lastModifiedFileName']}({lastModification['lastModifiedFileId']})",
|
_showLastModification(lastModification)
|
||||||
'lastModifyingUser', lastModification['lastModifyingUser'],
|
|
||||||
'lastModifiedTime', formatLocalTime(lastModification['lastModifiedTime'])])
|
|
||||||
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
|
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
|
||||||
if not showMimeTypeSize:
|
if not showMimeTypeSize:
|
||||||
printKeyValueList([mimeType, mtinfo['count']])
|
printKeyValueList([mimeType, mtinfo['count']])
|
||||||
@@ -56561,10 +56614,7 @@ def printShowFileCounts(users):
|
|||||||
if showSize:
|
if showSize:
|
||||||
row['Size'] = sizeTotal
|
row['Size'] = sizeTotal
|
||||||
if showLastModification:
|
if showLastModification:
|
||||||
row.update({'lastModifiedFileId': lastModification['lastModifiedFileId'],
|
_updateLastModificationRow(row, lastModification)
|
||||||
'lastModifiedFileName': lastModification['lastModifiedFileName'],
|
|
||||||
'lastModifyingUser': lastModification['lastModifyingUser'],
|
|
||||||
'lastModifiedTime': formatLocalTime(lastModification['lastModifiedTime'])})
|
|
||||||
if addCSVData:
|
if addCSVData:
|
||||||
row.update(addCSVData)
|
row.update(addCSVData)
|
||||||
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
|
for mimeType, mtinfo in sorted(iter(mimeTypeInfo.items())):
|
||||||
@@ -56578,6 +56628,7 @@ def printShowFileCounts(users):
|
|||||||
csvPF.SetZeroBlankMimeTypeCounts(True)
|
csvPF.SetZeroBlankMimeTypeCounts(True)
|
||||||
fieldsList = ['mimeType']
|
fieldsList = ['mimeType']
|
||||||
DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': True})
|
DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': True, 'allowQuery': True, 'mimeTypeInQuery': True})
|
||||||
|
pathDelimiter = '/'
|
||||||
sharedDriveId = sharedDriveName = ''
|
sharedDriveId = sharedDriveName = ''
|
||||||
continueOnInvalidQuery = showSize = showLastModification = showMimeTypeSize = False
|
continueOnInvalidQuery = showSize = showLastModification = showMimeTypeSize = False
|
||||||
sizeField = 'quotaBytesUsed'
|
sizeField = 'quotaBytesUsed'
|
||||||
@@ -56586,9 +56637,7 @@ def printShowFileCounts(users):
|
|||||||
summaryMimeTypeInfo = {}
|
summaryMimeTypeInfo = {}
|
||||||
fileIdEntity = {}
|
fileIdEntity = {}
|
||||||
addCSVData = {}
|
addCSVData = {}
|
||||||
summaryLastModification = {
|
summaryLastModification = _initLastModification()
|
||||||
'lastModifiedFileId': '', 'lastModifiedFileName': '',
|
|
||||||
'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME}
|
|
||||||
while Cmd.ArgumentsRemaining():
|
while Cmd.ArgumentsRemaining():
|
||||||
myarg = getArgument()
|
myarg = getArgument()
|
||||||
if csvPF and myarg == 'todrive':
|
if csvPF and myarg == 'todrive':
|
||||||
@@ -56611,6 +56660,8 @@ def printShowFileCounts(users):
|
|||||||
summary = getChoice(FILECOUNT_SUMMARY_CHOICE_MAP, mapChoice=True)
|
summary = getChoice(FILECOUNT_SUMMARY_CHOICE_MAP, mapChoice=True)
|
||||||
elif myarg == 'summaryuser':
|
elif myarg == 'summaryuser':
|
||||||
summaryUser = getString(Cmd.OB_STRING)
|
summaryUser = getString(Cmd.OB_STRING)
|
||||||
|
elif myarg == 'pathdelimiter':
|
||||||
|
pathDelimiter = getCharacter()
|
||||||
elif csvPF and myarg == 'addcsvdata':
|
elif csvPF and myarg == 'addcsvdata':
|
||||||
k = getString(Cmd.OB_STRING)
|
k = getString(Cmd.OB_STRING)
|
||||||
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
||||||
@@ -56637,7 +56688,9 @@ def printShowFileCounts(users):
|
|||||||
if showSize:
|
if showSize:
|
||||||
sortTitles.insert(sortTitles.index('Total')+1, 'Size')
|
sortTitles.insert(sortTitles.index('Total')+1, 'Size')
|
||||||
if showLastModification:
|
if showLastModification:
|
||||||
sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName', 'lastModifyingUser', 'lastModifiedTime'])
|
sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName',
|
||||||
|
'lastModifiedFileMimeType', 'lastModifiedFilePath',
|
||||||
|
'lastModifyingUser', 'lastModifiedTime'])
|
||||||
if addCSVData:
|
if addCSVData:
|
||||||
sortTitles.extend(sorted(addCSVData.keys()))
|
sortTitles.extend(sorted(addCSVData.keys()))
|
||||||
csvPF.SetTitles(sortTitles)
|
csvPF.SetTitles(sortTitles)
|
||||||
@@ -56652,9 +56705,7 @@ def printShowFileCounts(users):
|
|||||||
sharedDriveId = fileIdEntity.get('shareddrive', {}).get('driveId', '')
|
sharedDriveId = fileIdEntity.get('shareddrive', {}).get('driveId', '')
|
||||||
sharedDriveName = _getSharedDriveNameFromId(sharedDriveId) if sharedDriveId else ''
|
sharedDriveName = _getSharedDriveNameFromId(sharedDriveId) if sharedDriveId else ''
|
||||||
mimeTypeInfo = {}
|
mimeTypeInfo = {}
|
||||||
userLastModification = {
|
userLastModification = _initLastModification()
|
||||||
'lastModifiedFileId': '', 'lastModifiedFileName': '',
|
|
||||||
'lastModifyingUser': '', 'lastModifiedTime': NEVER_TIME}
|
|
||||||
gettingEntity = _getGettingEntity(user, fileIdEntity)
|
gettingEntity = _getGettingEntity(user, fileIdEntity)
|
||||||
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=DLP.fileIdEntity['query'])
|
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count, query=DLP.fileIdEntity['query'])
|
||||||
try:
|
try:
|
||||||
@@ -56697,12 +56748,8 @@ def printShowFileCounts(users):
|
|||||||
mimeTypeInfo[f_file['mimeType']]['count'] += 1
|
mimeTypeInfo[f_file['mimeType']]['count'] += 1
|
||||||
mimeTypeInfo[f_file['mimeType']]['size'] += int(f_file.get(sizeField, '0'))
|
mimeTypeInfo[f_file['mimeType']]['size'] += int(f_file.get(sizeField, '0'))
|
||||||
if showLastModification:
|
if showLastModification:
|
||||||
if f_file.get('modifiedTime', NEVER_TIME) > userLastModification['lastModifiedTime'] and 'lastModifyingUser' in f_file:
|
_checkUpdateLastModifiction(f_file, userLastModification)
|
||||||
userLastModification['lastModifiedFileId'] = f_file['id']
|
_getLastModificationPath(drive, userLastModification, pathDelimiter)
|
||||||
userLastModification['lastModifiedFileName'] = _stripControlCharsFromName(f_file['name'])
|
|
||||||
userLastModification['lastModifiedTime'] = f_file['modifiedTime']
|
|
||||||
userLastModification['lastModifyingUser'] = f_file['lastModifyingUser'].get('emailAddress',
|
|
||||||
f_file['lastModifyingUser'].get('displayName', UNKNOWN))
|
|
||||||
showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, userLastModification, i, count)
|
showMimeTypeInfo(user, mimeTypeInfo, sharedDriveId, sharedDriveName, userLastModification, i, count)
|
||||||
if showLastModification and userLastModification['lastModifiedTime'] > summaryLastModification['lastModifiedTime']:
|
if showLastModification and userLastModification['lastModifiedTime'] > summaryLastModification['lastModifiedTime']:
|
||||||
summaryLastModification = userLastModification.copy()
|
summaryLastModification = userLastModification.copy()
|
||||||
@@ -56726,6 +56773,110 @@ def printShowFileCounts(users):
|
|||||||
if csvPF:
|
if csvPF:
|
||||||
csvPF.writeCSVfile('Drive File Counts')
|
csvPF.writeCSVfile('Drive File Counts')
|
||||||
|
|
||||||
|
# gam <UserTypeEntity> print drivelastmodification [todrive <ToDriveAttribute>*]
|
||||||
|
# [select <SharedDriveEntity>]
|
||||||
|
# [pathdelimiter <Character>]
|
||||||
|
# (addcsvdata <FieldName> <String>)*
|
||||||
|
# gam <UserTypeEntity> show drivelastmodification
|
||||||
|
# [select <SharedDriveEntity>]
|
||||||
|
# [pathdelimiter <Character>]
|
||||||
|
def printShowDrivelastModifications(users):
|
||||||
|
def showLastModificationInfo(user, sharedDriveId, sharedDriveName, lastModification, i, count):
|
||||||
|
if not csvPF:
|
||||||
|
if sharedDriveId:
|
||||||
|
kvList = [Ent.USER, user, Ent.SHAREDDRIVE, f'{sharedDriveName} ({sharedDriveId})']
|
||||||
|
else:
|
||||||
|
kvList = [Ent.USER, user]
|
||||||
|
printEntity(kvList, i, count)
|
||||||
|
Ind.Increment()
|
||||||
|
_showLastModification(lastModification)
|
||||||
|
Ind.Decrement()
|
||||||
|
else:
|
||||||
|
if sharedDriveId:
|
||||||
|
row = {'User': user, 'id': sharedDriveId, 'name': sharedDriveName}
|
||||||
|
else:
|
||||||
|
row = {'User': user}
|
||||||
|
_updateLastModificationRow(row, lastModification)
|
||||||
|
if addCSVData:
|
||||||
|
row.update(addCSVData)
|
||||||
|
csvPF.WriteRowTitles(row)
|
||||||
|
|
||||||
|
csvPF = CSVPrintFile() if Act.csvFormat() else None
|
||||||
|
fieldsList = ['id', 'driveId', 'name', 'mimeType', 'lastModifyingUser', 'modifiedTime', 'parents']
|
||||||
|
DLP = DriveListParameters({'allowChoose': False, 'allowCorpora': False, 'allowQuery': False, 'mimeTypeInQuery': True})
|
||||||
|
pathDelimiter = '/'
|
||||||
|
sharedDriveId = sharedDriveName = ''
|
||||||
|
fileIdEntity = {}
|
||||||
|
addCSVData = {}
|
||||||
|
while Cmd.ArgumentsRemaining():
|
||||||
|
myarg = getArgument()
|
||||||
|
if csvPF and myarg == 'todrive':
|
||||||
|
csvPF.GetTodriveParameters()
|
||||||
|
elif myarg == 'select':
|
||||||
|
if fileIdEntity:
|
||||||
|
usageErrorExit(Msg.CAN_NOT_BE_SPECIFIED_MORE_THAN_ONCE.format('select'))
|
||||||
|
fileIdEntity = getSharedDriveEntity()
|
||||||
|
elif myarg == 'pathdelimiter':
|
||||||
|
pathDelimiter = getCharacter()
|
||||||
|
elif csvPF and myarg == 'addcsvdata':
|
||||||
|
k = getString(Cmd.OB_STRING)
|
||||||
|
addCSVData[k] = getString(Cmd.OB_STRING, minLen=0)
|
||||||
|
else:
|
||||||
|
unknownArgumentExit()
|
||||||
|
if not fileIdEntity:
|
||||||
|
fileIdEntity = DLP.GetFileIdEntity()
|
||||||
|
if not fileIdEntity.get('shareddrive'):
|
||||||
|
btkwargs = DLP.kwargs
|
||||||
|
else:
|
||||||
|
btkwargs = fileIdEntity['shareddrive']
|
||||||
|
fieldsList.append('driveId')
|
||||||
|
DLP.Finalize(fileIdEntity)
|
||||||
|
if csvPF:
|
||||||
|
sortTitles = ['User', 'id', 'name'] if fileIdEntity.get('shareddrive') else ['User']
|
||||||
|
sortTitles.extend(['lastModifiedFileId', 'lastModifiedFileName',
|
||||||
|
'lastModifiedFileMimeType', 'lastModifiedFilePath',
|
||||||
|
'lastModifyingUser', 'lastModifiedTime'])
|
||||||
|
if addCSVData:
|
||||||
|
sortTitles.extend(sorted(addCSVData.keys()))
|
||||||
|
csvPF.SetTitles(sortTitles)
|
||||||
|
csvPF.SetSortAllTitles()
|
||||||
|
pagesFields = getItemFieldsFromFieldsList('files', fieldsList)
|
||||||
|
i, count, users = getEntityArgument(users)
|
||||||
|
for user in users:
|
||||||
|
i += 1
|
||||||
|
user, drive = _validateUserSharedDrive(user, i, count, fileIdEntity)
|
||||||
|
if not drive:
|
||||||
|
continue
|
||||||
|
sharedDriveId = fileIdEntity.get('shareddrive', {}).get('driveId', '')
|
||||||
|
sharedDriveName = _getSharedDriveNameFromId(sharedDriveId) if sharedDriveId else ''
|
||||||
|
userLastModification = _initLastModification()
|
||||||
|
gettingEntity = _getGettingEntity(user, fileIdEntity)
|
||||||
|
printGettingAllEntityItemsForWhom(Ent.DRIVE_FILE_OR_FOLDER, gettingEntity, i, count)
|
||||||
|
try:
|
||||||
|
feed = yieldGAPIpages(drive.files(), 'list', 'files',
|
||||||
|
pageMessage=getPageMessageForWhom(),
|
||||||
|
throwReasons=GAPI.DRIVE_USER_THROW_REASONS+[GAPI.INVALID, GAPI.BAD_REQUEST, GAPI.FILE_NOT_FOUND,
|
||||||
|
GAPI.NOT_FOUND, GAPI.TEAMDRIVE_MEMBERSHIP_REQUIRED],
|
||||||
|
retryReasons=[GAPI.UNKNOWN_ERROR],
|
||||||
|
fields=pagesFields, pageSize=GC.Values[GC.DRIVE_MAX_RESULTS], **btkwargs)
|
||||||
|
for files in feed:
|
||||||
|
for f_file in files:
|
||||||
|
_checkUpdateLastModifiction(f_file, userLastModification)
|
||||||
|
_getLastModificationPath(drive, userLastModification, pathDelimiter)
|
||||||
|
showLastModificationInfo(user, sharedDriveId, sharedDriveName, userLastModification, i, count)
|
||||||
|
except (GAPI.invalid, GAPI.badRequest) as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user, Ent.DRIVE_FILE_OR_FOLDER, None], str(e), i, count)
|
||||||
|
continue
|
||||||
|
except GAPI.fileNotFound:
|
||||||
|
printGotEntityItemsForWhom(0)
|
||||||
|
except (GAPI.notFound, GAPI.teamDriveMembershipRequired) as e:
|
||||||
|
entityActionFailedWarning([Ent.USER, user, Ent.SHAREDDRIVE_ID, sharedDriveId], str(e), i, count)
|
||||||
|
except (GAPI.serviceNotAvailable, GAPI.authError, GAPI.domainPolicy) as e:
|
||||||
|
userDriveServiceNotEnabledWarning(user, str(e), i, count)
|
||||||
|
continue
|
||||||
|
if csvPF:
|
||||||
|
csvPF.writeCSVfile('Drive File Last Modification')
|
||||||
|
|
||||||
DISKUSAGE_SHOW_CHOICES = {'all', 'summary', 'summaryandtrash'}
|
DISKUSAGE_SHOW_CHOICES = {'all', 'summary', 'summaryandtrash'}
|
||||||
|
|
||||||
# gam <UserTypeEntity> print diskusage <DriveFileEntity> [todrive <ToDriveAttribute>*]
|
# gam <UserTypeEntity> print diskusage <DriveFileEntity> [todrive <ToDriveAttribute>*]
|
||||||
@@ -76543,6 +76694,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
|||||||
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
||||||
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
||||||
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
||||||
|
Cmd.ARG_DRIVELASTMODIFICATION: printShowDrivelastModifications,
|
||||||
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
||||||
Cmd.ARG_EMPTYDRIVEFOLDERS: printEmptyDriveFolders,
|
Cmd.ARG_EMPTYDRIVEFOLDERS: printEmptyDriveFolders,
|
||||||
Cmd.ARG_EVENT: printShowCalendarEvents,
|
Cmd.ARG_EVENT: printShowCalendarEvents,
|
||||||
@@ -76650,6 +76802,7 @@ USER_COMMANDS_WITH_OBJECTS = {
|
|||||||
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
Cmd.ARG_DRIVEFILEACL: printShowDriveFileACLs,
|
||||||
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
Cmd.ARG_DRIVELABEL: printShowDriveLabels,
|
||||||
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
Cmd.ARG_DRIVELABELPERMISSION: printShowDriveLabelPermissions,
|
||||||
|
Cmd.ARG_DRIVELASTMODIFICATION: printShowDrivelastModifications,
|
||||||
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
Cmd.ARG_DRIVESETTINGS: printShowDriveSettings,
|
||||||
Cmd.ARG_EVENT: printShowCalendarEvents,
|
Cmd.ARG_EVENT: printShowCalendarEvents,
|
||||||
Cmd.ARG_FILECOMMENT: printShowFileComments,
|
Cmd.ARG_FILECOMMENT: printShowFileComments,
|
||||||
@@ -76874,13 +77027,14 @@ USER_COMMANDS_OBJ_ALIASES = {
|
|||||||
Cmd.ARG_DOMAINCONTACT: Cmd.ARG_PEOPLECONTACT,
|
Cmd.ARG_DOMAINCONTACT: Cmd.ARG_PEOPLECONTACT,
|
||||||
Cmd.ARG_DOMAINCONTACTS: Cmd.ARG_PEOPLECONTACT,
|
Cmd.ARG_DOMAINCONTACTS: Cmd.ARG_PEOPLECONTACT,
|
||||||
Cmd.ARG_DRIVEFILEACLS: Cmd.ARG_DRIVEFILEACL,
|
Cmd.ARG_DRIVEFILEACLS: Cmd.ARG_DRIVEFILEACL,
|
||||||
Cmd.ARG_FILEDRIVELABELS: Cmd.ARG_FILEDRIVELABEL,
|
|
||||||
Cmd.ARG_DRIVEFILESHORTCUTS: Cmd.ARG_DRIVEFILESHORTCUT,
|
Cmd.ARG_DRIVEFILESHORTCUTS: Cmd.ARG_DRIVEFILESHORTCUT,
|
||||||
Cmd.ARG_DRIVELABELS: Cmd.ARG_DRIVELABEL,
|
Cmd.ARG_DRIVELABELS: Cmd.ARG_DRIVELABEL,
|
||||||
Cmd.ARG_DRIVELABELPERMISSIONS: Cmd.ARG_DRIVELABELPERMISSION,
|
Cmd.ARG_DRIVELABELPERMISSIONS: Cmd.ARG_DRIVELABELPERMISSION,
|
||||||
|
Cmd.ARG_DRIVELASTMODIFICATIONS: Cmd.ARG_DRIVELASTMODIFICATION,
|
||||||
Cmd.ARG_EVENTS: Cmd.ARG_EVENT,
|
Cmd.ARG_EVENTS: Cmd.ARG_EVENT,
|
||||||
Cmd.ARG_FILECOMMENTS: Cmd.ARG_FILECOMMENT,
|
Cmd.ARG_FILECOMMENTS: Cmd.ARG_FILECOMMENT,
|
||||||
Cmd.ARG_FILECOUNTS: Cmd.ARG_FILECOUNT,
|
Cmd.ARG_FILECOUNTS: Cmd.ARG_FILECOUNT,
|
||||||
|
Cmd.ARG_FILEDRIVELABELS: Cmd.ARG_FILEDRIVELABEL,
|
||||||
Cmd.ARG_FILEPATHS: Cmd.ARG_FILEPATH,
|
Cmd.ARG_FILEPATHS: Cmd.ARG_FILEPATH,
|
||||||
Cmd.ARG_FILEREVISIONS: Cmd.ARG_FILEREVISION,
|
Cmd.ARG_FILEREVISIONS: Cmd.ARG_FILEREVISION,
|
||||||
Cmd.ARG_FILESHARECOUNTS: Cmd.ARG_FILESHARECOUNT,
|
Cmd.ARG_FILESHARECOUNTS: Cmd.ARG_FILESHARECOUNT,
|
||||||
|
|||||||
@@ -579,6 +579,8 @@ class GamCLArgs():
|
|||||||
ARG_DRIVELABELS = 'drivelabels'
|
ARG_DRIVELABELS = 'drivelabels'
|
||||||
ARG_DRIVELABELPERMISSION = 'drivelabelpermission'
|
ARG_DRIVELABELPERMISSION = 'drivelabelpermission'
|
||||||
ARG_DRIVELABELPERMISSIONS = 'drivelabelpermissions'
|
ARG_DRIVELABELPERMISSIONS = 'drivelabelpermissions'
|
||||||
|
ARG_DRIVELASTMODIFICATION = 'drivelastmodification'
|
||||||
|
ARG_DRIVELASTMODIFICATIONS = 'drivelastmodifications'
|
||||||
ARG_DRIVESETTINGS = 'drivesettings'
|
ARG_DRIVESETTINGS = 'drivesettings'
|
||||||
ARG_DRIVETRASH = 'drivetrash'
|
ARG_DRIVETRASH = 'drivetrash'
|
||||||
ARG_EMPTYDRIVEFOLDERS = 'emptydrivefolders'
|
ARG_EMPTYDRIVEFOLDERS = 'emptydrivefolders'
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ chardet
|
|||||||
cryptography
|
cryptography
|
||||||
distro; sys_platform=='linux'
|
distro; sys_platform=='linux'
|
||||||
filelock
|
filelock
|
||||||
google-api-python-client>=2.1
|
google-api-python-client>=2.166.0
|
||||||
google-auth-httplib2
|
google-auth-httplib2>=0.2.0
|
||||||
google-auth-oauthlib>=0.4.1
|
google-auth-oauthlib>=1.2.1
|
||||||
google-auth>=2.3.2
|
google-auth>=2.38.0
|
||||||
httplib2>=0.17.0
|
httplib2>=0.22.0
|
||||||
lxml
|
lxml
|
||||||
passlib>=1.7.2
|
passlib>=1.7.4
|
||||||
pathvalidate
|
pathvalidate
|
||||||
python-dateutil
|
python-dateutil
|
||||||
yubikey-manager[yubikey]>=5.0
|
yubikey-manager[yubikey]>=5.6.1
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ You can skip these steps if you know that untrusted third-party apps are allowed
|
|||||||
* `<ServiceAccountDisplayName>` - `<ProjectName>`
|
* `<ServiceAccountDisplayName>` - `<ProjectName>`
|
||||||
* `<ServiceAccountDescription>` - `<ServiceAccountDisplayName>`
|
* `<ServiceAccountDescription>` - `<ServiceAccountDisplayName>`
|
||||||
|
|
||||||
### Basic
|
### Basic Create
|
||||||
Create a project with default values for the project and service account.
|
Create a project with default values for the project and service account.
|
||||||
```
|
```
|
||||||
gam create project [<EmailAddress>] [<ProjectID>]
|
gam create project [<EmailAddress>] [<ProjectID>]
|
||||||
@@ -291,7 +291,7 @@ gam create project [<EmailAddress>] [<ProjectID>]
|
|||||||
* `<EmailAddress>` - Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
|
* `<EmailAddress>` - Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
|
||||||
* `<ProjectID>` - A new Google project ID; if omitted, a default value will be used
|
* `<ProjectID>` - A new Google project ID; if omitted, a default value will be used
|
||||||
|
|
||||||
### Advanced
|
### Advanced Create
|
||||||
Create a project with user-specified values for the project and service account.
|
Create a project with user-specified values for the project and service account.
|
||||||
```
|
```
|
||||||
gam create project [admin <EmailAddress>] [project <ProjectID>]
|
gam create project [admin <EmailAddress>] [project <ProjectID>]
|
||||||
@@ -326,7 +326,7 @@ Use an existing project to create and download two files: `client_secrets.json`
|
|||||||
* `<ServiceAccountDisplayName>` - `<ProjectName>`
|
* `<ServiceAccountDisplayName>` - `<ProjectName>`
|
||||||
* `<ServiceAccountDescription>` - `<ServiceAccountDisplayName>`
|
* `<ServiceAccountDescription>` - `<ServiceAccountDisplayName>`
|
||||||
|
|
||||||
### Basic
|
### Basic Use
|
||||||
Use an existing uninitialized/uncredentialed project and configure it to be a GAM project; this typically used when
|
Use an existing uninitialized/uncredentialed project and configure it to be a GAM project; this typically used when
|
||||||
the GCP administrators have created a basic project because project creation is not available for most users.
|
the GCP administrators have created a basic project because project creation is not available for most users.
|
||||||
|
|
||||||
@@ -338,12 +338,13 @@ gam use project [<EmailAddress>] [project <ProjectID>]
|
|||||||
* `<EmailAddress>` - Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
|
* `<EmailAddress>` - Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
|
||||||
* `<ProjectID>` - An existing Google project ID; if omitted, you will be prompted for the ID
|
* `<ProjectID>` - An existing Google project ID; if omitted, you will be prompted for the ID
|
||||||
|
|
||||||
### Advanced
|
### Advanced Use
|
||||||
Use an existing project with user-specified values for the service account. If the project is already
|
Use an existing project with user-specified values for the service account. If the project is already
|
||||||
a GAM project you must use `saname <ServiceAccountName>` as the existing service account information
|
a GAM project you must use `saname <ServiceAccountName>` as the existing service account information
|
||||||
can not be re-downloaded.
|
can not be re-downloaded.
|
||||||
```
|
```
|
||||||
gam use project [admin <EmailAddress>] [project <ProjectID>]
|
gam use project [admin <EmailAddress>] [project <ProjectID>]
|
||||||
|
[appname <String>] [supportemail <EmailAddress>]
|
||||||
[saname <ServiceAccountName>] [sadisplayname <ServiceAccountDisplayName>]
|
[saname <ServiceAccountName>] [sadisplayname <ServiceAccountDisplayName>]
|
||||||
[sadescription <ServiceAccountDescription>]
|
[sadescription <ServiceAccountDescription>]
|
||||||
[(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
|
[(algorithm KEY_ALG_RSA_1024|KEY_ALG_RSA_2048)|
|
||||||
|
|||||||
@@ -725,6 +725,13 @@ chrome.devices.DevicePostQuantumKeyAgreementEnabled: Post-quantum TLS.
|
|||||||
FALSE: Do not allow post-quantum key agreement in TLS connections.
|
FALSE: Do not allow post-quantum key agreement in TLS connections.
|
||||||
TRUE: Allow post-quantum key agreement in TLS connections.
|
TRUE: Allow post-quantum key agreement in TLS connections.
|
||||||
|
|
||||||
|
chrome.devices.DevicePowerBatteryChargingOptimization: Battery charging optimization.
|
||||||
|
devicePowerBatteryChargingOptimization: TYPE_ENUM
|
||||||
|
UNSET: Allow the user to decide.
|
||||||
|
STANDARD: Enforce standard charging.
|
||||||
|
ADAPTIVE: Enforce adaptive charging.
|
||||||
|
LIMITED: Enforce limited charging.
|
||||||
|
|
||||||
chrome.devices.DevicePowerwashAllowed: Powerwash.
|
chrome.devices.DevicePowerwashAllowed: Powerwash.
|
||||||
devicePowerwashAllowed: TYPE_BOOL
|
devicePowerwashAllowed: TYPE_BOOL
|
||||||
true: Allow powerwash to be triggered.
|
true: Allow powerwash to be triggered.
|
||||||
@@ -1694,6 +1701,11 @@ chrome.devices.managedguest.DataUrlInSvgUseEnabled: Data URL support for SVGUseE
|
|||||||
true: Enable Data URL support in SVGUseElement.
|
true: Enable Data URL support in SVGUseElement.
|
||||||
false: Disable Data URL support in SVGUseElement.
|
false: Disable Data URL support in SVGUseElement.
|
||||||
|
|
||||||
|
chrome.devices.managedguest.DataUrlWhitespacePreservationEnabled: Data URL whitespace preservation for all media types.
|
||||||
|
dataUrlWhitespacePreservationEnabled: TYPE_BOOL
|
||||||
|
true: Keep whitespace for all mime-types.
|
||||||
|
false: Only keep whitespace for text and xml mime-types.
|
||||||
|
|
||||||
chrome.devices.managedguest.DefaultInsecureContentSetting: Control use of insecure content exceptions.
|
chrome.devices.managedguest.DefaultInsecureContentSetting: Control use of insecure content exceptions.
|
||||||
defaultInsecureContentSetting: TYPE_ENUM
|
defaultInsecureContentSetting: TYPE_ENUM
|
||||||
BLOCK_INSECURE_CONTENT: Do not allow any site to load blockable mixed content.
|
BLOCK_INSECURE_CONTENT: Do not allow any site to load blockable mixed content.
|
||||||
@@ -1995,14 +2007,14 @@ chrome.devices.managedguest.GenAiVcBackgroundSettings: Video conference backgrou
|
|||||||
ALLOWED: Allow Generative AI VC background and improve AI models.
|
ALLOWED: Allow Generative AI VC background and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow Generative AI VC background without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow Generative AI VC background without improving AI models.
|
||||||
DISABLED: Do not allow Generative AI VC background.
|
DISABLED: Do not allow Generative AI VC background.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.devices.managedguest.GenAiWallpaperSettings: Wallpaper settings.
|
chrome.devices.managedguest.GenAiWallpaperSettings: Wallpaper settings.
|
||||||
genAiWallpaperSettings: TYPE_ENUM
|
genAiWallpaperSettings: TYPE_ENUM
|
||||||
ALLOWED: Allow Generative AI wallpaper and improve AI models.
|
ALLOWED: Allow Generative AI wallpaper and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow Generative AI wallpaper without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow Generative AI wallpaper without improving AI models.
|
||||||
DISABLED: Do not allow Generative AI wallpaper.
|
DISABLED: Do not allow Generative AI wallpaper.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.devices.managedguest.GloballyScopeHttpAuthCacheEnabled: Globally scoped HTTP authentication cache.
|
chrome.devices.managedguest.GloballyScopeHttpAuthCacheEnabled: Globally scoped HTTP authentication cache.
|
||||||
globallyScopeHttpAuthCacheEnabled: TYPE_BOOL
|
globallyScopeHttpAuthCacheEnabled: TYPE_BOOL
|
||||||
@@ -2304,6 +2316,10 @@ chrome.devices.managedguest.MonoAudioEnabled: Mono audio.
|
|||||||
FALSE: Disable mono audio.
|
FALSE: Disable mono audio.
|
||||||
TRUE: Enable mono audio.
|
TRUE: Enable mono audio.
|
||||||
|
|
||||||
|
chrome.devices.managedguest.MultiScreenCaptureAllowedForUrls: URLs allowed for multi-screen capture .
|
||||||
|
multiScreenCaptureAllowedForUrls: TYPE_LIST
|
||||||
|
URLs allowed for multi-screen capture . The getAllScreensMedia API allows isolated web applications to capture multiple surfaces at once without additional user permission.
|
||||||
|
|
||||||
chrome.devices.managedguest.MutationEventsEnabled: Mutation Events.
|
chrome.devices.managedguest.MutationEventsEnabled: Mutation Events.
|
||||||
mutationEventsEnabled: TYPE_BOOL
|
mutationEventsEnabled: TYPE_BOOL
|
||||||
true: Temporarily re-enable mutation events.
|
true: Temporarily re-enable mutation events.
|
||||||
@@ -2708,6 +2724,9 @@ chrome.devices.managedguest.SearchSuggest: Search suggest.
|
|||||||
UNSET: Allow the user to decide.
|
UNSET: Allow the user to decide.
|
||||||
FALSE: Never allow users to use Search Suggest.
|
FALSE: Never allow users to use Search Suggest.
|
||||||
TRUE: Always allow users to use Search Suggest.
|
TRUE: Always allow users to use Search Suggest.
|
||||||
|
searchSuggestPolicyMode: TYPE_ENUM
|
||||||
|
MANDATORY: Do not allow users to override.
|
||||||
|
RECOMMENDED: Allow users to override.
|
||||||
|
|
||||||
chrome.devices.managedguest.SecurityTokenSessionSettings: Security token removal.
|
chrome.devices.managedguest.SecurityTokenSessionSettings: Security token removal.
|
||||||
securityTokenSessionBehavior: TYPE_ENUM
|
securityTokenSessionBehavior: TYPE_ENUM
|
||||||
@@ -2941,6 +2960,8 @@ chrome.devices.managedguest.SystemShortcutBehavior: Override system shortcuts.
|
|||||||
DEFAULT: Do not override system shortcuts.
|
DEFAULT: Do not override system shortcuts.
|
||||||
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS: Override some system shortcuts.
|
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS: Override some system shortcuts.
|
||||||
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS_FULLSCREEN_ONLY: Override some system shortcuts while in fullscreen.
|
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS_FULLSCREEN_ONLY: Override some system shortcuts while in fullscreen.
|
||||||
|
ALLOW_PASSTHROUGH_OF_SEARCH_BASED_SHORTCUTS: Prioritize active app over OS for Search key shortcuts.
|
||||||
|
ALLOW_PASSTHROUGH_OF_SEARCH_BASED_SHORTCUTS_FULLSCREEN_ONLY: Prioritize active app over OS for Search key shortcuts while in fullscreen.
|
||||||
|
|
||||||
chrome.devices.managedguest.TabDiscardingExceptions: Exceptions to tab discarding.
|
chrome.devices.managedguest.TabDiscardingExceptions: Exceptions to tab discarding.
|
||||||
tabDiscardingExceptions: TYPE_LIST
|
tabDiscardingExceptions: TYPE_LIST
|
||||||
@@ -3001,7 +3022,7 @@ chrome.devices.managedguest.UnthrottledNestedTimeoutEnabled: JavaScript setTimeo
|
|||||||
|
|
||||||
chrome.devices.managedguest.UrlBlocking: URL blocking.
|
chrome.devices.managedguest.UrlBlocking: URL blocking.
|
||||||
urlBlocklist: TYPE_LIST
|
urlBlocklist: TYPE_LIST
|
||||||
Blocked URLs. Any URL in this list will be blocked, unless it also appears in the list of exceptions specified in 'urlAllowlist'. Maximum of 1000 URLs. Note: to block OS and browser settings set the 'chrome.users.SystemFeaturesDisableList' policy instead of blocking 'chrome://' URLs.
|
Blocked URLs. Any URL in this list will be blocked, unless it also appears in the list of exceptions specified in 'urlAllowlist'. Maximum of 1000 URLs.
|
||||||
urlAllowlist: TYPE_LIST
|
urlAllowlist: TYPE_LIST
|
||||||
Blocked URL exceptions. Any URL that matches an entry in this exception list will be allowed, even if it matches an entry in the blocked URLs. Wildcards ("*") are allowed when appended to a URL, but cannot be entered alone. Maximum of 1000 URLs. .
|
Blocked URL exceptions. Any URL that matches an entry in this exception list will be allowed, even if it matches an entry in the blocked URLs. Wildcards ("*") are allowed when appended to a URL, but cannot be entered alone. Maximum of 1000 URLs. .
|
||||||
chromeInternalUrlsBlocked: TYPE_BOOL
|
chromeInternalUrlsBlocked: TYPE_BOOL
|
||||||
@@ -3920,7 +3941,7 @@ chrome.users.appsconfig.ChromeWebStorePagesAndContent: Pages & content.
|
|||||||
false: Use default Web Store pages and content.
|
false: Use default Web Store pages and content.
|
||||||
cwsPagesContentDiscoverPageEnabled: TYPE_BOOL
|
cwsPagesContentDiscoverPageEnabled: TYPE_BOOL
|
||||||
true: Show Discover page.
|
true: Show Discover page.
|
||||||
false: Hide Discover page (recommended).
|
false: Hide Discover page.
|
||||||
cwsPagesContentEnabledPreviews: TYPE_LIST
|
cwsPagesContentEnabledPreviews: TYPE_LIST
|
||||||
{'value': 'recommended', 'description': 'Show the recommended extensions preview.'}
|
{'value': 'recommended', 'description': 'Show the recommended extensions preview.'}
|
||||||
cwsPagesContentCategories: TYPE_LIST
|
cwsPagesContentCategories: TYPE_LIST
|
||||||
@@ -4492,7 +4513,7 @@ chrome.users.CreateThemesSettings: Create themes with AI.
|
|||||||
ALLOWED: Allow create themes and improve AI models.
|
ALLOWED: Allow create themes and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow create themes without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow create themes without improving AI models.
|
||||||
DISABLED: Do not allow create themes.
|
DISABLED: Do not allow create themes.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.CredentialProviderPromoEnabled: Credential provider extension promo.
|
chrome.users.CredentialProviderPromoEnabled: Credential provider extension promo.
|
||||||
credentialProviderPromoEnabled: TYPE_BOOL
|
credentialProviderPromoEnabled: TYPE_BOOL
|
||||||
@@ -4520,6 +4541,9 @@ chrome.users.CursorHighlightEnabled: Cursor highlight.
|
|||||||
FALSE: Disable cursor highlight.
|
FALSE: Disable cursor highlight.
|
||||||
TRUE: Enable cursor highlight.
|
TRUE: Enable cursor highlight.
|
||||||
|
|
||||||
|
chrome.users.CustomTermsOfService: Custom terms of service.
|
||||||
|
downloadUri: TYPE_STRING
|
||||||
|
|
||||||
chrome.users.DataCompressionProxy: Data compression proxy.
|
chrome.users.DataCompressionProxy: Data compression proxy.
|
||||||
dataCompressionProxyEnabled: TYPE_ENUM
|
dataCompressionProxyEnabled: TYPE_ENUM
|
||||||
UNSET: Allow the user to decide.
|
UNSET: Allow the user to decide.
|
||||||
@@ -4536,6 +4560,11 @@ chrome.users.DataUrlInSvgUseEnabled: Data URL support for SVGUseElement.
|
|||||||
true: Enable Data URL support in SVGUseElement.
|
true: Enable Data URL support in SVGUseElement.
|
||||||
false: Disable Data URL support in SVGUseElement.
|
false: Disable Data URL support in SVGUseElement.
|
||||||
|
|
||||||
|
chrome.users.DataUrlWhitespacePreservationEnabled: Data URL whitespace preservation for all media types.
|
||||||
|
dataUrlWhitespacePreservationEnabled: TYPE_BOOL
|
||||||
|
true: Keep whitespace for all mime-types.
|
||||||
|
false: Only keep whitespace for text and xml mime-types.
|
||||||
|
|
||||||
chrome.users.DefaultBrowserSettingEnabled: Default browser check.
|
chrome.users.DefaultBrowserSettingEnabled: Default browser check.
|
||||||
defaultBrowserSettingEnabled: TYPE_ENUM
|
defaultBrowserSettingEnabled: TYPE_ENUM
|
||||||
UNSET: Allow the user to decide.
|
UNSET: Allow the user to decide.
|
||||||
@@ -4638,7 +4667,7 @@ chrome.users.DevToolsGenAiSettings: DevTools AI features.
|
|||||||
ALLOWED: Allow DevTools Generative AI features and improve AI models.
|
ALLOWED: Allow DevTools Generative AI features and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow DevTools Generative AI features without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow DevTools Generative AI features without improving AI models.
|
||||||
DISABLED: Do not allow DevTools Generative AI features.
|
DISABLED: Do not allow DevTools Generative AI features.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.DictationEnabled: Dictation.
|
chrome.users.DictationEnabled: Dictation.
|
||||||
dictationEnabled: TYPE_ENUM
|
dictationEnabled: TYPE_ENUM
|
||||||
@@ -4981,14 +5010,14 @@ chrome.users.GenAiVcBackgroundSettings: Video conference background settings.
|
|||||||
ALLOWED: Allow Generative AI VC background and improve AI models.
|
ALLOWED: Allow Generative AI VC background and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow Generative AI VC background without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow Generative AI VC background without improving AI models.
|
||||||
DISABLED: Do not allow Generative AI VC background.
|
DISABLED: Do not allow Generative AI VC background.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.GenAiWallpaperSettings: Wallpaper settings.
|
chrome.users.GenAiWallpaperSettings: Wallpaper settings.
|
||||||
genAiWallpaperSettings: TYPE_ENUM
|
genAiWallpaperSettings: TYPE_ENUM
|
||||||
ALLOWED: Allow Generative AI wallpaper and improve AI models.
|
ALLOWED: Allow Generative AI wallpaper and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow Generative AI wallpaper without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow Generative AI wallpaper without improving AI models.
|
||||||
DISABLED: Do not allow Generative AI wallpaper.
|
DISABLED: Do not allow Generative AI wallpaper.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.Geolocation: Geolocation.
|
chrome.users.Geolocation: Geolocation.
|
||||||
defaultGeolocationSetting: TYPE_ENUM
|
defaultGeolocationSetting: TYPE_ENUM
|
||||||
@@ -5043,14 +5072,14 @@ chrome.users.HelpMeReadSettings: Help me read.
|
|||||||
ALLOWED: Allow help me read and improve AI models.
|
ALLOWED: Allow help me read and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow help me read without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow help me read without improving AI models.
|
||||||
DISABLED: Do not allow help me read.
|
DISABLED: Do not allow help me read.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.HelpMeWriteSettings: Help me write.
|
chrome.users.HelpMeWriteSettings: Help me write.
|
||||||
helpMeWriteSettings: TYPE_ENUM
|
helpMeWriteSettings: TYPE_ENUM
|
||||||
ALLOWED: Allow help me write and improve AI models.
|
ALLOWED: Allow help me write and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow help me write without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow help me write without improving AI models.
|
||||||
DISABLED: Do not allow help me write.
|
DISABLED: Do not allow help me write.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.HighContrastEnabled: High contrast.
|
chrome.users.HighContrastEnabled: High contrast.
|
||||||
highContrastEnabled: TYPE_ENUM
|
highContrastEnabled: TYPE_ENUM
|
||||||
@@ -5069,7 +5098,7 @@ chrome.users.HistorySearchSettings: History search settings.
|
|||||||
ALLOWED: Allow AI history search and improve AI models.
|
ALLOWED: Allow AI history search and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow AI history search without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow AI history search without improving AI models.
|
||||||
DISABLED: Do not allow AI history search.
|
DISABLED: Do not allow AI history search.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.HomeAndEndKeysModifier: Control the shortcut used to trigger the Home/End "six pack" keys.
|
chrome.users.HomeAndEndKeysModifier: Control the shortcut used to trigger the Home/End "six pack" keys.
|
||||||
homeAndEndKeysModifier: TYPE_ENUM
|
homeAndEndKeysModifier: TYPE_ENUM
|
||||||
@@ -5434,6 +5463,7 @@ chrome.users.LocalUserFilesAllowed: Local storage configuration.
|
|||||||
GOOGLE_DRIVE: Migrate existing local files to Google Drive.
|
GOOGLE_DRIVE: Migrate existing local files to Google Drive.
|
||||||
MICROSOFT_ONEDRIVE: Migrate existing local files to OneDrive.
|
MICROSOFT_ONEDRIVE: Migrate existing local files to OneDrive.
|
||||||
READ_ONLY: Keep existing local files in read-only mode.
|
READ_ONLY: Keep existing local files in read-only mode.
|
||||||
|
DELETE: Delete existing local files.
|
||||||
|
|
||||||
chrome.users.LockIconInAddressBarEnabled: Lock icon in the omnibox for secure connections.
|
chrome.users.LockIconInAddressBarEnabled: Lock icon in the omnibox for secure connections.
|
||||||
lockIconInAddressBarEnabled: TYPE_BOOL
|
lockIconInAddressBarEnabled: TYPE_BOOL
|
||||||
@@ -5551,6 +5581,10 @@ chrome.users.MultipleSignInAccess: Multiple sign-in access.
|
|||||||
UNRESTRICTED: Unrestricted user access (allow any user to be added to any other user's session).
|
UNRESTRICTED: Unrestricted user access (allow any user to be added to any other user's session).
|
||||||
NOT_ALLOWED: Block multiple sign-in access for users in this organization.
|
NOT_ALLOWED: Block multiple sign-in access for users in this organization.
|
||||||
|
|
||||||
|
chrome.users.MultiScreenCaptureAllowedForUrls: URLs allowed for multi-screen capture .
|
||||||
|
multiScreenCaptureAllowedForUrls: TYPE_LIST
|
||||||
|
URLs allowed for multi-screen capture . The getAllScreensMedia API allows isolated web applications to capture multiple surfaces at once without additional user permission.
|
||||||
|
|
||||||
chrome.users.MutationEventsEnabled: Mutation Events.
|
chrome.users.MutationEventsEnabled: Mutation Events.
|
||||||
mutationEventsEnabled: TYPE_BOOL
|
mutationEventsEnabled: TYPE_BOOL
|
||||||
true: Temporarily re-enable mutation events.
|
true: Temporarily re-enable mutation events.
|
||||||
@@ -6325,6 +6359,9 @@ chrome.users.SearchSuggest: Search suggest.
|
|||||||
UNSET: Allow the user to decide.
|
UNSET: Allow the user to decide.
|
||||||
FALSE: Never allow users to use Search Suggest.
|
FALSE: Never allow users to use Search Suggest.
|
||||||
TRUE: Always allow users to use Search Suggest.
|
TRUE: Always allow users to use Search Suggest.
|
||||||
|
searchSuggestPolicyMode: TYPE_ENUM
|
||||||
|
MANDATORY: Do not allow users to override.
|
||||||
|
RECOMMENDED: Allow users to override.
|
||||||
|
|
||||||
chrome.users.SecondaryGoogleAccountSignin: Sign-in to secondary accounts.
|
chrome.users.SecondaryGoogleAccountSignin: Sign-in to secondary accounts.
|
||||||
secondaryGoogleAccountSigninAllowed: TYPE_ENUM
|
secondaryGoogleAccountSigninAllowed: TYPE_ENUM
|
||||||
@@ -6683,6 +6720,8 @@ chrome.users.SystemShortcutBehavior: Override system shortcuts.
|
|||||||
DEFAULT: Do not override system shortcuts.
|
DEFAULT: Do not override system shortcuts.
|
||||||
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS: Override some system shortcuts.
|
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS: Override some system shortcuts.
|
||||||
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS_FULLSCREEN_ONLY: Override some system shortcuts while in fullscreen.
|
SHOULD_IGNORE_COMMON_VDI_SHORTCUTS_FULLSCREEN_ONLY: Override some system shortcuts while in fullscreen.
|
||||||
|
ALLOW_PASSTHROUGH_OF_SEARCH_BASED_SHORTCUTS: Prioritize active app over OS for Search key shortcuts.
|
||||||
|
ALLOW_PASSTHROUGH_OF_SEARCH_BASED_SHORTCUTS_FULLSCREEN_ONLY: Prioritize active app over OS for Search key shortcuts while in fullscreen.
|
||||||
|
|
||||||
chrome.users.SystemTerminalSshAllowed: SSH in terminal system app.
|
chrome.users.SystemTerminalSshAllowed: SSH in terminal system app.
|
||||||
systemTerminalSshAllowed: TYPE_ENUM
|
systemTerminalSshAllowed: TYPE_ENUM
|
||||||
@@ -6695,7 +6734,7 @@ chrome.users.TabCompareSettings: Tab compare.
|
|||||||
ALLOWED: Allow tab compare and improve AI models.
|
ALLOWED: Allow tab compare and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow tab compare without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow tab compare without improving AI models.
|
||||||
DISABLED: Do not allow tab compare.
|
DISABLED: Do not allow tab compare.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.TabDiscardingExceptions: Exceptions to tab discarding.
|
chrome.users.TabDiscardingExceptions: Exceptions to tab discarding.
|
||||||
tabDiscardingExceptions: TYPE_LIST
|
tabDiscardingExceptions: TYPE_LIST
|
||||||
@@ -6706,7 +6745,7 @@ chrome.users.TabOrganizerSettings: Tab organizer.
|
|||||||
ALLOWED: Allow tab organizer and improve AI models.
|
ALLOWED: Allow tab organizer and improve AI models.
|
||||||
ALLOWED_WITHOUT_LOGGING: Allow tab organizer without improving AI models.
|
ALLOWED_WITHOUT_LOGGING: Allow tab organizer without improving AI models.
|
||||||
DISABLED: Do not allow tab organizer.
|
DISABLED: Do not allow tab organizer.
|
||||||
UNSET: Use the default Chrome behavior.
|
UNSET: Use the value specified in the Generative AI policy defaults setting.
|
||||||
|
|
||||||
chrome.users.TargetBlankImpliesNoOpener: Pop-up interactions.
|
chrome.users.TargetBlankImpliesNoOpener: Pop-up interactions.
|
||||||
targetBlankImpliesNoOpener: TYPE_BOOL
|
targetBlankImpliesNoOpener: TYPE_BOOL
|
||||||
@@ -6813,7 +6852,7 @@ chrome.users.UpdatesSuppressed: Suppress auto-update check.
|
|||||||
|
|
||||||
chrome.users.UrlBlocking: URL blocking.
|
chrome.users.UrlBlocking: URL blocking.
|
||||||
urlBlocklist: TYPE_LIST
|
urlBlocklist: TYPE_LIST
|
||||||
Blocked URLs. Any URL in this list will be blocked, unless it also appears in the list of exceptions specified in 'urlAllowlist'. Maximum of 1000 URLs. Note: to block OS and browser settings set the 'chrome.users.SystemFeaturesDisableList' policy instead of blocking 'chrome://' URLs.
|
Blocked URLs. Any URL in this list will be blocked, unless it also appears in the list of exceptions specified in 'urlAllowlist'. Maximum of 1000 URLs.
|
||||||
urlAllowlist: TYPE_LIST
|
urlAllowlist: TYPE_LIST
|
||||||
Blocked URL exceptions. Any URL that matches an entry in this exception list will be allowed, even if it matches an entry in the blocked URLs. Wildcards ("*") are allowed when appended to a URL, but cannot be entered alone. Maximum of 1000 URLs. .
|
Blocked URL exceptions. Any URL that matches an entry in this exception list will be allowed, even if it matches an entry in the blocked URLs. Wildcards ("*") are allowed when appended to a URL, but cannot be entered alone. Maximum of 1000 URLs. .
|
||||||
chromeInternalUrlsBlocked: TYPE_BOOL
|
chromeInternalUrlsBlocked: TYPE_BOOL
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ Typically, you will enclose the entire list in double quotes and quote each item
|
|||||||
* ```"item item item"```
|
* ```"item item item"```
|
||||||
- Items, separated by commas, with spaces, commas or single quotes in the items themselves
|
- Items, separated by commas, with spaces, commas or single quotes in the items themselves
|
||||||
* ```"'it em','it,em',\"it'em\""``` - Linux, MacOS, Windows Command Prompt
|
* ```"'it em','it,em',\"it'em\""``` - Linux, MacOS, Windows Command Prompt
|
||||||
* ```"'it em','it,em',`"it'em`""``` - Windows Power Shell
|
* ```"'it\ em','it,em',`"it\'em`""``` - Windows Power Shell
|
||||||
- Items, separated by spaces, with spaces, commas or single quotes in the items themselves
|
- Items, separated by spaces, with spaces, commas or single quotes in the items themselves
|
||||||
* ```"'it em' 'it,em' \"it'em\""``` - Linux, MacOS, Windows Command Prompt
|
* ```"'it em' 'it,em' \"it'em\""``` - Linux, MacOS, Windows Command Prompt
|
||||||
* ```"'it em' 'it,em' `"it'em`""``` - Windows Power Shell
|
* ```"'it\ em' 'it,em' `"it\'em`""``` - Windows Power Shell
|
||||||
|
|
||||||
Typical places where these rules apply are lists of OUs and Contact Groups.
|
Typical places where these rules apply are lists of OUs and Contact Groups.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,45 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
|||||||
|
|
||||||
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
See [Downloads-Installs-GAM7](https://github.com/GAM-team/GAM/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||||
|
|
||||||
|
### 7.06.05
|
||||||
|
|
||||||
|
Updated code in `gam delete|update chromepolicy` to handle the `policyTargetKey[additionalTargetKeys]`
|
||||||
|
field in a more general manner for future use.
|
||||||
|
|
||||||
|
### 7.06.04
|
||||||
|
|
||||||
|
Fixed bug in `gam report <ActivityApplictionName>` where a report with no activities
|
||||||
|
was not displaying any output.
|
||||||
|
|
||||||
|
### 7.06.03
|
||||||
|
|
||||||
|
Fixed bug in `gam <UserTypeEntity> print|show drivelastmodification` that caused a trap
|
||||||
|
when an empty drive was specified.
|
||||||
|
|
||||||
|
### 7.06.02
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> print|show filecounts ... showlastmodification` to include
|
||||||
|
file mimetype and path information for the last modified file.
|
||||||
|
|
||||||
|
Added simple commands to get information about the last modified file on a drive.
|
||||||
|
By default, a user's My Drive is processed; optionally, a Shared Drive can be processed.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> print drivelastmodification [todrive <ToDriveAttribute>*]
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
(addcsvdata <FieldName> <String>)*
|
||||||
|
gam <UserTypeEntity> show drivelastmodification
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.06.01
|
||||||
|
|
||||||
|
Updated `gam <UserTypeEntity> create|update drivefileacl ... expiration <Time>`
|
||||||
|
to handle additional API errors.
|
||||||
|
|
||||||
|
Updated to Python 3.13.3.
|
||||||
|
|
||||||
### 7.06.00
|
### 7.06.00
|
||||||
|
|
||||||
Upgraded to OpenSSL 3.5.0.
|
Upgraded to OpenSSL 3.5.0.
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
# Introduction
|
# Introduction
|
||||||
GAM7 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
|
GAM7 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
|
||||||
|
|
||||||
GAM7 is a rewrite/extension of Jay Lee's Legacy GAM, without his efforts, this version wouldn't exist.
|
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
GAM7 requires paid, or Education/Non-profit, editions of Google Workspace. G Suite Legacy Free Edition has limited API support and not all GAM commands work.
|
GAM7 requires paid, or Education/Non-profit, editions of Google Workspace. G Suite Legacy Free Edition has limited API support and not all GAM commands work.
|
||||||
|
|
||||||
|
|||||||
@@ -251,10 +251,10 @@ writes the credentials into the file oauth2.txt.
|
|||||||
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
admin@server:/Users/admin$ rm -f /Users/admin/GAMConfig/oauth2.txt
|
||||||
admin@server:/Users/admin$ gam version
|
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
|
WARNING: Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: /Users/admin/GAMConfig/oauth2.txt, Not Found
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.06.05 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
MacOS Sequoia 15.4 x86_64
|
MacOS Sequoia 15.4.1 x86_64
|
||||||
Path: /Users/admin/bin/gam7
|
Path: /Users/admin/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|
||||||
@@ -989,9 +989,9 @@ writes the credentials into the file oauth2.txt.
|
|||||||
C:\>del C:\GAMConfig\oauth2.txt
|
C:\>del C:\GAMConfig\oauth2.txt
|
||||||
C:\>gam version
|
C:\>gam version
|
||||||
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
WARNING: Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, Item: oauth2_txt, Value: C:\GAMConfig\oauth2.txt, Not Found
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM - pythonsource
|
GAM 7.06.05 - https://github.com/GAM-team/GAM - pythonsource
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
Windows-10-10.0.17134 AMD64
|
Windows-10-10.0.17134 AMD64
|
||||||
Path: C:\GAM7
|
Path: C:\GAM7
|
||||||
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: C:\GAMConfig\gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ The `columndelimiter <Character>` subargument sets the intercolumn delimiter of
|
|||||||
is the value of `csv_output_column_delimiter` in `gam.cfg` which defaults to comma.
|
is the value of `csv_output_column_delimiter` in `gam.cfg` which defaults to comma.
|
||||||
|
|
||||||
The `quotechar <Character>` subargument sets the character used to quote fields in the CSV file
|
The `quotechar <Character>` subargument sets the character used to quote fields in the CSV file
|
||||||
that contaim special charactere; the default value is the value of `csv_output_quote_char` in `gam.cfg`
|
that contain special charactere; the default value is the value of `csv_output_quote_char` in `gam.cfg`
|
||||||
which defaults to double quote.
|
which defaults to double quote.
|
||||||
|
|
||||||
The `noescapechar <Boolean>` subargument controls whether `\` is used as an escape character when writing the CSV file; the default value
|
The `noescapechar <Boolean>` subargument controls whether `\` is used as an escape character when writing the CSV file; the default value
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
- [Display Shared Drive access for specific Shared Drives](#display-shared-drive-access-for-specific-shared-drives)
|
- [Display Shared Drive access for specific Shared Drives](#display-shared-drive-access-for-specific-shared-drives)
|
||||||
- [Display Shared Drive access for selected Shared Drives](#display-shared-drive-access-for-selected-shared-drives)
|
- [Display Shared Drive access for selected Shared Drives](#display-shared-drive-access-for-selected-shared-drives)
|
||||||
- [Display members of all Shared Drives](#display-members-of-all-shared-drives)
|
- [Display members of all Shared Drives](#display-members-of-all-shared-drives)
|
||||||
|
- [Display external members of all Shared Drives](#display-external-members-of-all-shared-drives)
|
||||||
- [Display ACLs for Shared Drives with no organizers](#display-acls-for-shared-drives-with-no-organizers)
|
- [Display ACLs for Shared Drives with no organizers](#display-acls-for-shared-drives-with-no-organizers)
|
||||||
- [Display ACLs for Shared Drives with all organizers outside of your domain](#display-acls-for-shared-drives-with-all-organizers-outside-of-your-domain)
|
- [Display ACLs for Shared Drives with all organizers outside of your domain](#display-acls-for-shared-drives-with-all-organizers-outside-of-your-domain)
|
||||||
- [Display ACLs for Shared Drives with all ACLs outside of your domain](#display-acls-for-shared-drives-with-all-acls-outside-of-your-domain)
|
- [Display ACLs for Shared Drives with all ACLs outside of your domain](#display-acls-for-shared-drives-with-all-acls-outside-of-your-domain)
|
||||||
@@ -569,6 +570,12 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
|
|||||||
gam config csv_output_header_drop_filter "User,createdTime,permission.photoLink,permission.permissionDetails" redirect csv ./SharedDriveMembers.csv print shareddriveacls oneitemperrow
|
gam config csv_output_header_drop_filter "User,createdTime,permission.photoLink,permission.permissionDetails" redirect csv ./SharedDriveMembers.csv print shareddriveacls oneitemperrow
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Display external members of all Shared Drives
|
||||||
|
Replace `<InternalDomainList>` with your list of internal domains.
|
||||||
|
```
|
||||||
|
gam config csv_output_header_drop_filter "User,createdTime,permission.photoLink,permission.permissionDetails" redirect csv ./SharedDriveExternalMembers.csv print shareddriveacls pm notdomainlist <InternalDomainList> em oneitemperrow
|
||||||
|
```
|
||||||
|
|
||||||
## Display Shared Drive access for selected Shared Drives
|
## Display Shared Drive access for selected Shared Drives
|
||||||
```
|
```
|
||||||
gam [<UserTypeEntity>] show teamdriveacls
|
gam [<UserTypeEntity>] show teamdriveacls
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
- [Handle empty file lists](#handle-empty-file-lists)
|
- [Handle empty file lists](#handle-empty-file-lists)
|
||||||
- [Display disk usage](#display-disk-usage)
|
- [Display disk usage](#display-disk-usage)
|
||||||
- [Display files published to the web](#display-files-published-to-the-web)
|
- [Display files published to the web](#display-files-published-to-the-web)
|
||||||
|
- [Display information about last modified file on a drive](#display-information-about-last-modified-file-on-a-drive)
|
||||||
|
|
||||||
## API documentation
|
## API documentation
|
||||||
* [Drive API - Files](https://developers.google.com/drive/api/v3/reference/files)
|
* [Drive API - Files](https://developers.google.com/drive/api/v3/reference/files)
|
||||||
@@ -704,7 +705,8 @@ gam <UserTypeEntity> print filecounts [todrive <ToDriveAttribute>*]
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize] [showlastmodification]
|
[showsize] [showmimetypesize]
|
||||||
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
(addcsvdata <FieldName> <String>)*
|
(addcsvdata <FieldName> <String>)*
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
gam <UserTypeEntity> show filecounts
|
gam <UserTypeEntity> show filecounts
|
||||||
@@ -719,7 +721,8 @@ gam <UserTypeEntity> show filecounts
|
|||||||
[filenamematchpattern <REMatchPattern>]
|
[filenamematchpattern <REMatchPattern>]
|
||||||
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
<PermissionMatch>* [<PermissionMatchMode>] [<PermissionMatchAction>]
|
||||||
[excludetrashed]
|
[excludetrashed]
|
||||||
[showsize] [showmimetypesize] [showlastmodification]
|
[showsize] [showmimetypesize]
|
||||||
|
[showlastmodification] [pathdelimiter <Character>]
|
||||||
[summary none|only|plus] [summaryuser <String>]
|
[summary none|only|plus] [summaryuser <String>]
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -736,7 +739,7 @@ The `showsize` option displays the total size (in bytes) of the files counted.
|
|||||||
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
|
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
|
||||||
|
|
||||||
The option `showlastmodification` displays the following fields:
|
The option `showlastmodification` displays the following fields:
|
||||||
`lastModifiedFileId,lastModifiedFileName,lastModifyingUser,lastModifiedTime`;
|
`lastModifiedFileId,lastModifiedFileName,lastModifiedFileMimeType,lastModifiedFilePath,lastModifyingUser,lastModifiedTime`;
|
||||||
these are for the most recently modified file.
|
these are for the most recently modified file.
|
||||||
|
|
||||||
For print filecouts, add additional columns of data from the command line to the output:
|
For print filecouts, add additional columns of data from the command line to the output:
|
||||||
@@ -1748,3 +1751,24 @@ gam config csv_output_header_filter "Owner,id,revisions.0.published,revisions.0.
|
|||||||
# Get the files name, MIMEtype and path
|
# Get the files name, MIMEtype and path
|
||||||
gam redirect csv ./PublishedDocsWithName.csv multiprocess redirect stderr - multiprocess csv ./PublishedDocs.csv gam user "~Owner" print filelist select "~id" fields id,name,mimetype fullpath addcsvdata published "~revisions.0.published" addcsvdata publishedOutsideDomain "~revisions.0.publishedOutsideDomain"
|
gam redirect csv ./PublishedDocsWithName.csv multiprocess redirect stderr - multiprocess csv ./PublishedDocs.csv gam user "~Owner" print filelist select "~id" fields id,name,mimetype fullpath addcsvdata published "~revisions.0.published" addcsvdata publishedOutsideDomain "~revisions.0.publishedOutsideDomain"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Display information about last modified file on a drive
|
||||||
|
Use these commands to display information about the most recently modified file on a drive.
|
||||||
|
|
||||||
|
By default, a user's My Drive is processed; optionally, a Shared Drive can be processed.
|
||||||
|
```
|
||||||
|
gam <UserTypeEntity> print drivelastmodification [todrive <ToDriveAttribute>*]
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
(addcsvdata <FieldName> <String>)*
|
||||||
|
gam <UserTypeEntity> show drivelastmodification
|
||||||
|
[select <SharedDriveEntity>]
|
||||||
|
[pathdelimiter <Character>]
|
||||||
|
```
|
||||||
|
In addition to the user and optional Shared Drive information, The following fields are displayed
|
||||||
|
`lastModifiedFileId,lastModifiedFileName,lastModifiedFileMimeType,lastModifiedFilePath,lastModifyingUser,lastModifiedTime`
|
||||||
|
|
||||||
|
By default, file path components are separated by `/`; use `pathdelimiter <Character>` to use `<Character>` as the separator.
|
||||||
|
|
||||||
|
For print drivelastmodification, 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
|
||||||
|
|||||||
@@ -1161,10 +1161,10 @@ The `quotechar <Character>` option allows you to choose an alternate quote chara
|
|||||||
Print a CSV file with headers `domain,count` that gives the number of users in each domain
|
Print a CSV file with headers `domain,count` that gives the number of users in each domain
|
||||||
### Print domain counts for users in a specific domain and/or selected by a query
|
### Print domain counts for users in a specific domain and/or selected by a query
|
||||||
```
|
```
|
||||||
gam print users [todrive <ToDriveAttribute>*]
|
gam print users countonly [todrive <ToDriveAttribute>*]
|
||||||
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
([domain|domains <DomainNameEntity>] [(query <QueryUser>)|(queries <QueryUserList>)]
|
||||||
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
|
[limittoou <OrgUnitItem>] [deleted_only|only_deleted])
|
||||||
[formatjson [quotechar <Character>]] [countonly]
|
[formatjson [quotechar <Character>]]
|
||||||
[issuspended <Boolean>]
|
[issuspended <Boolean>]
|
||||||
```
|
```
|
||||||
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
|
By default, users in all domains in the account are selected; these options allow selection of subsets of users:
|
||||||
@@ -1177,10 +1177,10 @@ By default, users in all domains in the account are selected; these options allo
|
|||||||
|
|
||||||
### Print domain counts for users specified by `<UserTypeEntity>`
|
### Print domain counts for users specified by `<UserTypeEntity>`
|
||||||
```
|
```
|
||||||
gam print users [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
gam print users countonly [todrive <ToDriveAttribute>*] select <UserTypeEntity>
|
||||||
[formatjson [quotechar <Character>]] [countonly]
|
[formatjson [quotechar <Character>]]
|
||||||
gam <UserTypeEntity> print users [todrive <ToDriveAttribute>*]
|
gam <UserTypeEntity> countonly print users [todrive <ToDriveAttribute>*]
|
||||||
[formatjson [quotechar <Character>]] [countonly]
|
[formatjson [quotechar <Character>]]
|
||||||
```
|
```
|
||||||
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format:
|
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format:
|
||||||
* `formatjson` - Display the fields in JSON format.
|
* `formatjson` - Display the fields in JSON format.
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ k
|
|||||||
Print the current version of Gam with details
|
Print the current version of Gam with details
|
||||||
```
|
```
|
||||||
gam version
|
gam version
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.06.05 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
MacOS Sequoia 15.4 x86_64
|
MacOS Sequoia 15.4.1 x86_64
|
||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2023-06-02T21:10:00-07:00
|
Time: 2023-06-02T21:10:00-07:00
|
||||||
@@ -16,10 +16,10 @@ Time: 2023-06-02T21:10:00-07:00
|
|||||||
Print the current version of Gam with details and time offset information
|
Print the current version of Gam with details and time offset information
|
||||||
```
|
```
|
||||||
gam version timeoffset
|
gam version timeoffset
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.06.05 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
MacOS Sequoia 15.4 x86_64
|
MacOS Sequoia 15.4.1 x86_64
|
||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Your system time differs from www.googleapis.com by less than 1 second
|
Your system time differs from www.googleapis.com by less than 1 second
|
||||||
@@ -28,10 +28,10 @@ Your system time differs from www.googleapis.com by less than 1 second
|
|||||||
Print the current version of Gam with extended details and SSL information
|
Print the current version of Gam with extended details and SSL information
|
||||||
```
|
```
|
||||||
gam version extended
|
gam version extended
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM - pyinstaller
|
GAM 7.06.05 - https://github.com/GAM-team/GAM - pyinstaller
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
MacOS Sequoia 15.4 x86_64
|
MacOS Sequoia 15.4.1 x86_64
|
||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2023-06-02T21:10:00-07:00
|
Time: 2023-06-02T21:10:00-07:00
|
||||||
@@ -65,7 +65,7 @@ MacOS High Sierra 10.13.6 x86_64
|
|||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Version Check:
|
Version Check:
|
||||||
Current: 5.35.08
|
Current: 5.35.08
|
||||||
Latest: 7.06.00
|
Latest: 7.06.05
|
||||||
echo $?
|
echo $?
|
||||||
1
|
1
|
||||||
```
|
```
|
||||||
@@ -73,7 +73,7 @@ echo $?
|
|||||||
Print the current version number without details
|
Print the current version number without details
|
||||||
```
|
```
|
||||||
gam version simple
|
gam version simple
|
||||||
7.06.00
|
7.06.05
|
||||||
```
|
```
|
||||||
In Linux/MacOS you can do:
|
In Linux/MacOS you can do:
|
||||||
```
|
```
|
||||||
@@ -83,10 +83,10 @@ echo $VER
|
|||||||
Print the current version of Gam and address of this Wiki
|
Print the current version of Gam and address of this Wiki
|
||||||
```
|
```
|
||||||
gam help
|
gam help
|
||||||
GAM 7.06.00 - https://github.com/GAM-team/GAM
|
GAM 7.06.05 - https://github.com/GAM-team/GAM
|
||||||
GAM Team <google-apps-manager@googlegroups.com>
|
GAM Team <google-apps-manager@googlegroups.com>
|
||||||
Python 3.13.2 64-bit final
|
Python 3.13.3 64-bit final
|
||||||
MacOS Sequoia 15.4 x86_64
|
MacOS Sequoia 15.4.1 x86_64
|
||||||
Path: /Users/Admin/bin/gam7
|
Path: /Users/Admin/bin/gam7
|
||||||
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
Config File: /Users/admin/GAMConfig/gam.cfg, Section: DEFAULT, customer_id: my_customer, domain: domain.com
|
||||||
Time: 2023-06-02T21:10:00-07:00
|
Time: 2023-06-02T21:10:00-07:00
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Need more help? Ask on the [GAM Discussion Group](https://groups.google.com/forum/#!forum/google-apps-manager)
|
|
||||||
@@ -1 +1,3 @@
|
|||||||
Need more help? Ask on the [GAM Discussion Group](https://groups.google.com/forum/#!forum/google-apps-manager)
|
Need more help? Ask on the [GAM Discussion Group](https://groups.google.com/forum/#!forum/google-apps-manager) or [Chat Space](https://github.com/GAM-team/GAM/wiki/GAM-Public-Chat-Room).
|
||||||
|
|
||||||
|
You can suggest edits to these Wiki pages by submitting pull requests against [the wiki files](https://github.com/GAM-team/GAM/tree/main/wiki).
|
||||||
|
|||||||
Reference in New Issue
Block a user