mirror of
https://github.com/GAM-team/GAM.git
synced 2026-06-13 18:51:36 +00:00
Compare commits
91 Commits
20240917.1
...
v7.00.08
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46d05e37d0 | ||
|
|
9dc87a060d | ||
|
|
3e638dd35e | ||
|
|
e4ad4fb26c | ||
|
|
cc63aee62c | ||
|
|
31806438a9 | ||
|
|
74ac351aa4 | ||
|
|
7e157dab42 | ||
|
|
8b2586ead2 | ||
|
|
ebcfd18457 | ||
|
|
cbb496e491 | ||
|
|
1ff93b1051 | ||
|
|
2fdb6156e7 | ||
|
|
f7c13a3063 | ||
|
|
c0470c35a9 | ||
|
|
304a897290 | ||
|
|
af2499a0ea | ||
|
|
52ccd735ca | ||
|
|
ffcb1c4ddf | ||
|
|
0dd74e226c | ||
|
|
bd5149d3f8 | ||
|
|
7c6649b24f | ||
|
|
cfd9447f39 | ||
|
|
820698d9d4 | ||
|
|
7645edee6b | ||
|
|
7e6f7b8bab | ||
|
|
ee77ae8319 | ||
|
|
0f2eba580d | ||
|
|
1cdf160b35 | ||
|
|
7e68c108c1 | ||
|
|
8ecbe67054 | ||
|
|
a6016825ff | ||
|
|
15221a1a20 | ||
|
|
6718938c1a | ||
|
|
acd1a9ad91 | ||
|
|
cce2894dac | ||
|
|
877ea0cc19 | ||
|
|
cd4c1fc7ac | ||
|
|
09292fd28b | ||
|
|
ccef86d2a0 | ||
|
|
ba34ef4494 | ||
|
|
26eca09bb9 | ||
|
|
64d4cc00e4 | ||
|
|
33b4de86a9 | ||
|
|
f33da85518 | ||
|
|
93ecbf479e | ||
|
|
ca2d6541ce | ||
|
|
db7154dca9 | ||
|
|
72bba3d948 | ||
|
|
07bbf4d4ea | ||
|
|
7aafbbe58e | ||
|
|
c2058211fe | ||
|
|
08a6cbb270 | ||
|
|
c5da8963d4 | ||
|
|
89b854ea57 | ||
|
|
42fd8cd1e8 | ||
|
|
0e0f49c540 | ||
|
|
f0b1b62e79 | ||
|
|
7606a40a58 | ||
|
|
ac5098522b | ||
|
|
d84ff8d392 | ||
|
|
4a0687cfe9 | ||
|
|
19e386ed21 | ||
|
|
8165c72606 | ||
|
|
5267992e31 | ||
|
|
1949b3346c | ||
|
|
38375b1710 | ||
|
|
281e790260 | ||
|
|
2b8b2521d1 | ||
|
|
52601edb35 | ||
|
|
5475f281eb | ||
|
|
b1f8893783 | ||
|
|
640cb322d7 | ||
|
|
c4f15cbf3a | ||
|
|
bef392cf7a | ||
|
|
abb49ed336 | ||
|
|
fe5bc5569d | ||
|
|
18615f246d | ||
|
|
7958632046 | ||
|
|
3e8bff23c4 | ||
|
|
0221781a05 | ||
|
|
e6ced7fff6 | ||
|
|
484238ece2 | ||
|
|
ee32bb87f0 | ||
|
|
73803acb89 | ||
|
|
a40df40f9b | ||
|
|
a33b89788c | ||
|
|
54f815e503 | ||
|
|
e54d3d274a | ||
|
|
b7a20ceb4f | ||
|
|
bbc965d38f |
1
.github/actions/package_exclusions.txt
vendored
1
.github/actions/package_exclusions.txt
vendored
@@ -2,6 +2,5 @@ oauth2.txt
|
||||
nobrowser.txt
|
||||
enabledasa.txt
|
||||
lastupdatecheck.txt
|
||||
*.json
|
||||
*.lck
|
||||
*.csv
|
||||
|
||||
220
.github/workflows/build.yml
vendored
220
.github/workflows/build.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
||||
arch: aarch64
|
||||
openssl_archs: linux-aarch64
|
||||
staticx: yes
|
||||
- os: macos-12
|
||||
- os: macos-13
|
||||
jid: 6
|
||||
goal: build
|
||||
arch: x86_64
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
openssl_archs: VC-WIN64A
|
||||
- os: ubuntu-22.04
|
||||
goal: test
|
||||
python: "3.8"
|
||||
python: "3.13"
|
||||
jid: 10
|
||||
arch: x86_64
|
||||
- os: ubuntu-22.04
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
with:
|
||||
path: |
|
||||
cache.tar.xz
|
||||
key: gam-${{ matrix.jid }}-20240916
|
||||
key: gam-${{ matrix.jid }}-20240918
|
||||
|
||||
- name: Untar Cache archive
|
||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit == 'true'
|
||||
@@ -301,7 +301,8 @@ jobs:
|
||||
- name: Rename GNU link on Windows
|
||||
if: matrix.goal == 'build' && runner.os == 'Windows' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: mv /usr/bin/link /usr/bin/gnulink
|
||||
run: |
|
||||
mv -v /usr/bin/link /usr/bin/gnulink
|
||||
|
||||
- name: Make OpenSSL
|
||||
if: matrix.goal == 'build' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||
@@ -319,7 +320,7 @@ jobs:
|
||||
cd "${GITHUB_WORKSPACE}/src/openssl-${openssl_arch}"
|
||||
# install_sw saves us ages processing man pages :-)
|
||||
$MAKE install_sw
|
||||
mv "${OPENSSL_INSTALL_PATH}" "${GITHUB_WORKSPACE}/bin/ssl-${openssl_arch}"
|
||||
mv -v "${OPENSSL_INSTALL_PATH}" "${GITHUB_WORKSPACE}/bin/ssl-${openssl_arch}"
|
||||
done
|
||||
mkdir -vp "${OPENSSL_INSTALL_PATH}/lib"
|
||||
mkdir -vp "${OPENSSL_INSTALL_PATH}/bin"
|
||||
@@ -529,61 +530,59 @@ jobs:
|
||||
- name: Build GAM with PyInstaller
|
||||
if: matrix.goal != 'test'
|
||||
run: |
|
||||
if [[ "${staticx}" == "yes" ]]; then
|
||||
export distpath="./dist/gam"
|
||||
export gampath="${distpath}"
|
||||
else
|
||||
export distpath="./dist"
|
||||
export gampath="${distpath}/gam"
|
||||
fi
|
||||
mkdir -p -v "${gampath}"
|
||||
export distpath="./dist/gam"
|
||||
mkdir -p -v "${distpath}"
|
||||
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||
# brew OpenSSL gets picked up by PyInstaller breaking our self-compiled version
|
||||
# Tell our gam.spec to use our code sign certificate
|
||||
export codesign_identity="Jay Lee"
|
||||
# brew OpenSSL gets picked up by PyInstaller
|
||||
# breaking our self-compiled version
|
||||
brew uninstall --ignore-dependencies openssl
|
||||
export gampath=$($PYTHON -c "import os; print(os.path.realpath('$gampath'))")
|
||||
elif [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
# Work around issue where PyInstaller picks up python3.dll from other Python versions
|
||||
# https://github.com/pyinstaller/pyinstaller/issues/7102
|
||||
export PATH="$(dirname ${PYTHON}):/usr/bin"
|
||||
else
|
||||
export gampath=$(realpath "${gampath}")
|
||||
fi
|
||||
export gam="${gampath}/gam"
|
||||
echo "gampath=${gampath}" >> $GITHUB_ENV
|
||||
# TEMP force everything back to one file.
|
||||
export PYINSTALLER_BUILD_ONEFILE="yes"
|
||||
export distpath="./dist/gam"
|
||||
export gampath="${distpath}"
|
||||
if ([ "${staticx}" != "yes" ] && [ "$RUNNER_OS" != "Windows" ]); then
|
||||
export PYINSTALLER_BUILD_ONEDIR=yes
|
||||
fi
|
||||
"${PYTHON}" -m PyInstaller --clean --noconfirm --distpath="${distpath}" gam.spec
|
||||
echo "WARNINGS FROM build/gam/warn-gam.txt"
|
||||
cat build/gam/warn-gam.txt
|
||||
echo "Analysis FROM build/gam/Analysis-00.toc"
|
||||
cat build/gam/Analysis-00.toc
|
||||
echo "EXE data FROM build/gam/EXE-00.toc"
|
||||
cat build/gam/EXE-00.toc
|
||||
if [ -x "$(command -v realpath)" ]; then
|
||||
realpath=realpath
|
||||
if [[ "$PYINSTALLER_BUILD_ONEDIR" == "yes" ]]; then
|
||||
mv -v "${distpath}/gam" "${distpath}/gam7"
|
||||
export gampath="${distpath}/gam7"
|
||||
else
|
||||
brew install coreutils
|
||||
realpath=grealpath
|
||||
mv -v "$distpath" "${distpath}7"
|
||||
export gampath="${distpath}7"
|
||||
fi
|
||||
export gam=$(realpath "$gam")
|
||||
export gampath=$(realpath "$gampath")
|
||||
echo "gampath ${gampath} results:"
|
||||
ls -alRF "$gampath"
|
||||
echo "---- WARNINGS FROM build/gam/warn-gam.txt"
|
||||
cat build/gam/warn-gam.txt
|
||||
echo "---- Analysis FROM build/gam/Analysis-00.toc"
|
||||
cat build/gam/Analysis-00.toc
|
||||
echo "---- EXE data FROM build/gam/EXE-00.toc"
|
||||
cat build/gam/EXE-00.toc
|
||||
export gam="${gampath}/gam"
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
export gam=$(cygpath -w "$gam")
|
||||
echo "GAM on Windows at ${gam}"
|
||||
else
|
||||
export gam=$(realpath "$gam")
|
||||
fi
|
||||
echo "gampath=${gampath}" >> $GITHUB_ENV
|
||||
echo "gam=${gam}" >> $GITHUB_ENV
|
||||
echo -e "GAM: ${gam}\nGAMPATH: ${gampath}"
|
||||
|
||||
- name: Copy extra package files
|
||||
if: matrix.goal == 'build'
|
||||
run: |
|
||||
cp -v cacerts.pem $gampath
|
||||
cp -v LICENSE $gampath
|
||||
cp -v GamCommands.txt $gampath
|
||||
cp -v GamUpdate.txt $gampath
|
||||
cp -v cacerts.pem "$gampath"
|
||||
cp -v LICENSE "$gampath"
|
||||
cp -v GamCommands.txt "$gampath"
|
||||
cp -v GamUpdate.txt "$gampath"
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
cp -v gam-setup.bat $gampath
|
||||
cp -v gam-setup.bat "$gampath"
|
||||
fi
|
||||
|
||||
- name: Install StaticX
|
||||
@@ -608,13 +607,6 @@ jobs:
|
||||
rm -v "$gam"
|
||||
mv -v "${gam}-staticx" "$gam"
|
||||
|
||||
- name: MacOS sign GAM binary
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
security find-identity -v signing_temp.keychain
|
||||
codesign --force --deep --sign "Jay Lee" --options=runtime --entitlements "${GITHUB_WORKSPACE}/.github/actions/entitlements.plist" --timestamp "$gam"
|
||||
codesign -dv --verbose=4 "$gam"
|
||||
|
||||
- name: MacOS send GAM binary for Apple notarization
|
||||
if: runner.os == 'macOS'
|
||||
env:
|
||||
@@ -623,8 +615,9 @@ jobs:
|
||||
# Apple wants some kind of "package" submitted so just add gam to a .zip
|
||||
# name it something we can track and link in Apple's notarize process
|
||||
zipfilename="./gam-${RUNNER_ARCH}-${GITHUB_RUN_ID}-${GITHUB_RUN_NUMBER}.zip"
|
||||
zip "$zipfilename" "$gam"
|
||||
zip -r "$zipfilename" "$gampath"
|
||||
xcrun notarytool submit --apple-id "jay0lee@gmail.com" --password "$ASP_NOTARIZE" --team-id GZ85H2DRLM "$zipfilename"
|
||||
rm -v "$zipfilename"
|
||||
|
||||
- name: Basic Tests all jobs
|
||||
id: basictests
|
||||
@@ -635,7 +628,45 @@ jobs:
|
||||
echo "GAM Version ${GAMVERSION}"
|
||||
echo "GAMVERSION=${GAMVERSION}" >> $GITHUB_ENV
|
||||
|
||||
- name: Attest Binary Provenance
|
||||
- name: Configure service account auth
|
||||
id: configserviceaccount
|
||||
env:
|
||||
PASSCODE: ${{ secrets.PASSCODE }}
|
||||
run: |
|
||||
source ../.github/actions/decrypt.sh ../.github/actions/creds.tar.xz.gpg creds.tar.xz "${GAMCFGDIR}"
|
||||
mv -v "${GAMCFGDIR}/oauth2.txt-gam-gha-${JID}" "${GAMCFGDIR}/oauth2.txt"
|
||||
rm -v $GAMCFGDIR/oauth2.txt-gam*
|
||||
$gam create signjwtserviceaccount
|
||||
|
||||
- name: Upload gam.exe Windows for signing
|
||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||
run: |
|
||||
export folder_number=$(date +%s)
|
||||
export folder_id=$($gam user gam-win-signer@pdl.jaylee.us add drivefile drivefilename "UPLOADING_FOR_SIGN ${folder_number}" parentid "1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp" mimetype gfolder returnidonly)
|
||||
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$gam" parentid "$folder_id"
|
||||
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
|
||||
export signed_folder="SIGNED ${folder_number}"
|
||||
zero_results="gam-win-signer@pdl.jaylee.us,0"
|
||||
while true; do
|
||||
result_counts=$($gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
|
||||
echo "$result_counts"
|
||||
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
|
||||
echo "looks like we have results"
|
||||
break
|
||||
fi
|
||||
echo "no results, sleeping 10..."
|
||||
sleep 10
|
||||
done
|
||||
# download signed gam.exe
|
||||
$gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name = 'gam.exe'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$gampath" targetname "signed-gam.exe" overwrite true acknowledgeabuse true
|
||||
# delete signed folder on drive
|
||||
$gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
|
||||
# remove unsigned gam.exe and rename signed-gam.exe
|
||||
rm -v -f "${gampath}/gam.exe"
|
||||
mv -v -f "${gampath}/signed-gam.exe" "${gampath}/gam.exe"
|
||||
#"/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe" verify /v /pa "$gam"
|
||||
|
||||
- name: Attest gam executable was generated from this Action
|
||||
uses: actions/attest-build-provenance@v1
|
||||
if: matrix.goal == 'build'
|
||||
with:
|
||||
@@ -645,28 +676,80 @@ jobs:
|
||||
if: runner.os != 'Windows' && matrix.goal == 'build'
|
||||
run: |
|
||||
if [[ "${RUNNER_OS}" == "macOS" ]]; then
|
||||
GAM_ARCHIVE="gam-${GAMVERSION}-macos-${arch}.tar.xz"
|
||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-macos-${arch}.tar.xz"
|
||||
elif [[ "${RUNNER_OS}" == "Linux" ]]; then
|
||||
if [[ "${staticx}" == "yes" ]]; then
|
||||
libver="legacy"
|
||||
else
|
||||
libver="glibc$(ldd --version | awk '/ldd/{print $NF}')"
|
||||
fi
|
||||
GAM_ARCHIVE="gam-${GAMVERSION}-linux-$(arch)-${libver}.tar.xz"
|
||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-linux-$(arch)-${libver}.tar.xz"
|
||||
fi
|
||||
echo "GAM Archive ${GAM_ARCHIVE}"
|
||||
tar -C dist/ --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam
|
||||
tar -C "${gampath}/.." --create --verbose --exclude-from "${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" --file $GAM_ARCHIVE --xz gam7
|
||||
|
||||
- name: Windows package
|
||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||
run: |
|
||||
cd dist/
|
||||
GAM_ARCHIVE="../gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.zip"
|
||||
/c/Program\ Files/7-Zip/7z.exe a -tzip $GAM_ARCHIVE gam "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
||||
cd "${gampath}/.."
|
||||
GAM_ARCHIVE="${GITHUB_WORKSPACE}/gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.zip"
|
||||
/c/Program\ Files/7-Zip/7z.exe a -tzip "$GAM_ARCHIVE" gam7 "-xr@${GITHUB_WORKSPACE}/.github/actions/package_exclusions.txt" -bb3
|
||||
cd ..
|
||||
export MSI_FILENAME="gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.msi"
|
||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/candle.exe -arch "${WIX_ARCH}" gam.wxs
|
||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/light.exe -ext /c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/WixUIExtension.dll gam.wixobj -o "gam-${GAMVERSION}-windows-${GAM_ARCHIVE_ARCH}.msi" || true;
|
||||
/c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/light.exe -ext /c/Program\ Files\ \(x86\)/WiX\ Toolset\ v3.14/bin/WixUIExtension.dll gam.wixobj -o "$MSI_FILENAME" || true;
|
||||
rm -v -f *.wixpdb
|
||||
export folder_number=$(date +%s)
|
||||
export folder_id=$($gam user gam-win-signer@pdl.jaylee.us add drivefile drivefilename "UPLOADING_FOR_SIGN ${folder_number}" parentid "1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp" mimetype gfolder returnidonly)
|
||||
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$MSI_FILENAME" parentid "$folder_id"
|
||||
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
|
||||
echo "MSI_FILENAME=${MSI_FILENAME}" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload gam MSI Windows for signing
|
||||
if: runner.os == 'Windows' && matrix.goal != 'test'
|
||||
run: |
|
||||
export folder_number=$(date +%s)
|
||||
export folder_id=$($gam user gam-win-signer@pdl.jaylee.us add drivefile drivefilename "UPLOADING_FOR_SIGN ${folder_number}" parentid "1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp" mimetype gfolder returnidonly)
|
||||
$gam user gam-win-signer@pdl.jaylee.us add drivefile localfile "$MSI_FILENAME" parentid "$folder_id"
|
||||
rm -f -v "$MSI_FILENAME"
|
||||
$gam user gam-win-signer@pdl.jaylee.us update drivefile "$folder_id" newfilename "READYTOSIGN ${folder_number}"
|
||||
export signed_folder="SIGNED ${folder_number}"
|
||||
zero_results="gam-win-signer@pdl.jaylee.us,0"
|
||||
while true; do
|
||||
result_counts=$($gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" countsonly)
|
||||
echo "$result_counts"
|
||||
if [[ ! "$result_counts" =~ "$zero_results" ]]; then
|
||||
echo "looks like we have results"
|
||||
break
|
||||
fi
|
||||
echo "no results, sleeping 10..."
|
||||
sleep 10
|
||||
done
|
||||
# download signed package
|
||||
$gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us print filelist query "'~~id~~' in parents and name = '$MSI_FILENAME'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us get drivefile ~id targetfolder "$GITHUB_WORKSPACE" targetname "$MSI_FILENAME" overwrite true acknowledgeabuse true
|
||||
# delete signed folder from drive
|
||||
# delete signed folder on drive
|
||||
$gam user gam-win-signer print filelist query "name = '${signed_folder}' and '1Xz3hYq4Mfa_r6D8EcBZHLDtHDFurYSvp' in parents and mimeType = 'application/vnd.google-apps.folder'" id | $gam csv - gam user gam-win-signer@pdl.jaylee.us trash drivefile "~id"
|
||||
#"/c/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x64/signtool.exe" verify /v /pa "$MSI_FILENAME"
|
||||
|
||||
- name: Attest that gam package files were generated from this Action
|
||||
uses: actions/attest-build-provenance@v1
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && matrix.goal == 'build'
|
||||
with:
|
||||
subject-path: |
|
||||
gam*.tar.xz
|
||||
gam*.zip
|
||||
gam*.msi
|
||||
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && matrix.goal != 'test'
|
||||
with:
|
||||
name: gam-binaries-${{ env.GAMOS }}-${{ env.arch }}-${{ matrix.jid }}
|
||||
path: |
|
||||
gam*.tar.xz
|
||||
gam*.zip
|
||||
gam*.msi
|
||||
|
||||
- name: Basic Tests build jobs only
|
||||
if: matrix.goal != 'test' && steps.cache-python-ssl.outputs.cache-hit != 'true'
|
||||
@@ -690,12 +773,7 @@ jobs:
|
||||
|
||||
- name: Live API tests push only
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule')
|
||||
env:
|
||||
PASSCODE: ${{ secrets.PASSCODE }}
|
||||
run: |
|
||||
source ../.github/actions/decrypt.sh ../.github/actions/creds.tar.xz.gpg creds.tar.xz "${GAMCFGDIR}"
|
||||
mv -v "${GAMCFGDIR}/oauth2.txt-gam-gha-${JID}" "${GAMCFGDIR}/oauth2.txt"
|
||||
rm -v $GAMCFGDIR/oauth2.txt-gam*
|
||||
export gam_user="gam-gha-${JID}@pdl.jaylee.us"
|
||||
echo "gam_user=${gam_user}" >> $GITHUB_ENV
|
||||
$gam config customer_id "C03uzfv2s" save
|
||||
@@ -705,7 +783,6 @@ jobs:
|
||||
$gam oauth info
|
||||
$gam oauth refresh
|
||||
$gam config enable_dasa true save
|
||||
$gam create signjwtserviceaccount
|
||||
$gam checkconn
|
||||
$gam user "$gam_user" check serviceaccount
|
||||
$gam info domain
|
||||
@@ -886,7 +963,7 @@ jobs:
|
||||
echo "printer model count:"
|
||||
$gam print printermodels | wc -l
|
||||
$gam print printers
|
||||
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by $(gam_user)" ou "${newou}" nodetails | awk '{print substr($2, 1, length($2)-1)}')
|
||||
printerid=$($gam create printer displayname "${newbase}" uri ipp://localhost:631 driverless description "made by ${gam_user}" ou "${newou}" nodetails | awk '{print substr($2, 1, length($2)-1)}')
|
||||
$gam info printer "$printerid"
|
||||
$gam delete printer "$printerid"
|
||||
$gam delete ou "${newou}"
|
||||
@@ -902,25 +979,6 @@ jobs:
|
||||
fi
|
||||
tar cJvvf cache.tar.xz $tar_folders
|
||||
|
||||
- name: Attest Build Archive Provenance
|
||||
uses: actions/attest-build-provenance@v1
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && matrix.goal == 'build'
|
||||
with:
|
||||
subject-path: |
|
||||
src/gam*.tar.xz
|
||||
src/gam*.zip
|
||||
src/gam*.msi
|
||||
|
||||
- name: Archive production artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule') && matrix.goal != 'test'
|
||||
with:
|
||||
name: gam-binaries-${{ env.GAMOS }}-${{ env.arch }}-${{ matrix.jid }}
|
||||
path: |
|
||||
src/gam*.tar.xz
|
||||
src/gam*.zip
|
||||
src/gam*.msi
|
||||
|
||||
merge:
|
||||
if: (github.event_name == 'push' || github.event_name == 'schedule')
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
GAM is a command line tool for Google Workspace admins to manage domain and user settings quickly and easily.
|
||||
|
||||

|
||||
[](https://github.com/GAM-team/GAM/actions/workflows/build.yml)
|
||||
|
||||
# Quick Start
|
||||
|
||||
@@ -32,7 +32,7 @@ There is a public chat room hosted in Google Chat. [Instructions to join](https:
|
||||
|
||||
# Author
|
||||
|
||||
GAM is maintained by [Jay Lee](mailto:jay0lee@gmail.com). Please direct "how do I?" questions to [Google Groups].
|
||||
GAM is maintained by [Jay (James) Lee](mailto:jay0lee@gmail.com) and [Ross Scroggs](mailto:ross.scroggs@gmail.com). Please direct "how do I?" questions to [Google Groups].
|
||||
|
||||
[GAM release]: https://github.com/GAM-team/GAM/releases
|
||||
[GitHub Releases]: https://github.com/GAM-team/GAM/releases
|
||||
|
||||
@@ -176,6 +176,7 @@ Client access works when accessing Resource calendars.
|
||||
<AttendeeStatus> ::= accepted|declined|needsaction|tentative
|
||||
|
||||
<EventType> ::=
|
||||
birthday|
|
||||
default|
|
||||
focustime|
|
||||
fromgmail|
|
||||
@@ -241,6 +242,7 @@ Client access works when accessing Resource calendars.
|
||||
(attendee <EmailAddress>)|
|
||||
(attendeestatus [<AttendeeAttendance>] [<AttendeeStatus>] <EmailAddress>)|
|
||||
available|
|
||||
(birthday <Date>)|
|
||||
(color <EventColorName>)|
|
||||
(colorindex|colorid <EventColorIndex>)|
|
||||
(description <String>)|
|
||||
@@ -261,7 +263,7 @@ Client access works when accessing Resource calendars.
|
||||
(privateproperty <PropertyKey> <PropertyValue>)|
|
||||
(range <Date> <Date>)|
|
||||
(recurrence <RRULE, EXRULE, RDATE and EXDATE line>)|
|
||||
(reminder <Number> email|popup))|
|
||||
(reminder <Number> email|popup)|
|
||||
(selectattendees [<AttendeeAttendance>] [<AttendeeStatus>] <UserTypeEntity>)|
|
||||
(sequence <Integer>)|
|
||||
(sharedproperty <PropertyKey> <PropertyValue>)|
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
- [Definitions](#definitions)
|
||||
- [Display a specific Chrome policy schema](#display-a-specific-chrome-policy-schema)
|
||||
- [Display all or filtered Chrome policy schemas](#display-all-or-filtered-chrome-policy-schemas)
|
||||
- [Display Chrome policy schemas in same format as Standard GAM](#display-chrome-policy-schemas-in-same-format-as-standard-gam)
|
||||
- [Display Chrome policy schemas in same format as Legacy GAM](#display-chrome-policy-schemas-in-same-format-as-legacy-gam)
|
||||
- [Create a Chrome policy image](#create-a-chrome-policy-image)
|
||||
- [Update Chrome policy](#update-chrome-policy)
|
||||
- [Delete Chrome policy](#delete-chrome-policy)
|
||||
@@ -118,7 +118,7 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||
|
||||
## Display Chrome policy schemas in same format as Standard GAM
|
||||
## Display Chrome policy schemas in same format as Legacy GAM
|
||||
```
|
||||
gam show chromeschemas std
|
||||
[filter <String>]
|
||||
|
||||
@@ -71,7 +71,7 @@ gam <Command> cros <CrOSEntity> ...
|
||||
```
|
||||
The first form allows more powerful selection of devices with `<CrOSTypeEntity>`.
|
||||
|
||||
The second form is backwards compatible with Standard GAM and selection with `<CrOSEntity>` is limited.
|
||||
The second form is backwards compatible with Legacy GAM and selection with `<CrOSEntity>` is limited.
|
||||
|
||||
## Definitions
|
||||
* [`<CrOSTypeEntity>`](Collections-of-ChromeOS-Devices)
|
||||
@@ -465,7 +465,7 @@ gam getcommand cros <CrOSEntity> commandid <CommandID> [times_to_check_status <I
|
||||
### Action Examples
|
||||
Remove user profile data from the device; the device will remain enrolled and connected.
|
||||
User data not synced to the Cloud including Downloads, Android app data and Crostini Linux VMs will be permanently lost.
|
||||
Commands with issuecommand directly after gam will work with standard GAM & GAMADV-XTD3, whereas commands where the issuecommand is after the cros <CrOSTypeEntity> will work only with GAMADV-XTD3.
|
||||
Commands with issuecommand directly after gam will work with Legacy GAM & GAMADV-XTD3, whereas commands where the issuecommand is after the cros <CrOSTypeEntity> will work only with GAMADV-XTD3.
|
||||
```
|
||||
gam issuecommand cros dd1d659a-0ea4-4e94-905e-4726c7a5f1e9 command wipe_users doit
|
||||
```
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
|
||||
<UserGoogleDoc> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
|
||||
|
||||
<SheetEntity> ::= <String>|id:<Number>
|
||||
<UserGoogleSheet> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>) <SheetEntity>
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
|
||||
<UserGoogleDoc> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
|
||||
|
||||
<SheetEntity> ::= <String>|id:<Number>
|
||||
<UserGoogleSheet> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>) <SheetEntity>
|
||||
```
|
||||
@@ -88,8 +90,6 @@
|
||||
<SharedDriveIDEntity> |
|
||||
<SharedDriveNameEntity>
|
||||
|
||||
<SheetEntity> ::= <String>|id:<Number>
|
||||
|
||||
<UserTypeEntity> ::=
|
||||
(all users|users_ns|users_susp|users_ns_susp)|
|
||||
(user <UserItem>)|
|
||||
|
||||
56
docs/Downloads-Installs-GAM7.md
Normal file
56
docs/Downloads-Installs-GAM7.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Downloads-Installs-GAM7
|
||||
You can download and install the current GAM7 release from the [GitHub Releases](https://github.com/GAM-team/GAM/releases/latest) page.
|
||||
Choose one of the following:
|
||||
|
||||
* Executable Archive, Automatic, Linux/Mac OS/Google Cloud Shell/Raspberry Pi/ChromeOS
|
||||
- Start a terminal session and execute one of the following commands:
|
||||
- New install, default path `$HOME/bin`
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install)`
|
||||
- New install, specify a path
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install) -d <Path>`
|
||||
- Update to latest version, do not create project or authorizations, default path `$HOME/bin`
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install) -l`
|
||||
- Update to latest version, do not create project or authorizations, specify a path
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install) -l -d <Path>`
|
||||
|
||||
By default, a folder, `gam7`, is created in the default or specified path and the files are downloaded into that folder.
|
||||
Add the `-s` option to the end of the above commands to suppress creating the `gam7` folder; the files are downloaded directly into the default or specified path.
|
||||
|
||||
* Executable Archive, Manual, Linux/Google Cloud Shell
|
||||
- `gam-7.wx.yz-linux-x86_64-glibc2.35.tar.xz`
|
||||
- `gam-7.wx.yz-linux-x86_64-glibc2.31.tar.xz`
|
||||
- `gam-7.wx.yz-linux-x86_64-legacy.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Raspberry Pi/ChromeOS ARM devices
|
||||
- `gam-7.wx.yz-linux-aarch-glibc2.31.tar.xz`
|
||||
- `gam-7.wx.yz-linux-aarch-legacy.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Mac OS versions Big Sur, Monterey, Ventura - M1/M2
|
||||
- `gam-7.wx.yz-macos-aarch.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Mac OS, versions Big Sur, Monterey, Ventura - Intel
|
||||
- `gam-7.wx.yz-macos-x86_64.tar.xz`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal session.
|
||||
|
||||
* Executable Archive, Manual, Windows 64 bit
|
||||
- `gam-7.wx.yz-windows-x86_64.zip`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Executable Installer, Manual, Windows 64 bit
|
||||
- `gam-7.wx.yz-windows-x86_64.msi`
|
||||
- Download the installer and run it.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Source, all platforms
|
||||
- `Source code(zip)`
|
||||
- `Source code(tar.gz)`
|
||||
- Download the archive, extract the contents into some directory.
|
||||
- Start a terminal/Command Prompt/PowerShell session.
|
||||
@@ -4,7 +4,7 @@ Many of the changes are internal to Gam and have no visible effect. Google has m
|
||||
A variable, `drive_v3_native_names` (default value is True), has been added to `gam.cfg` to control the field names on output: when True, the v3 native field names are used; when False, the v3 native field names are mapped to the v2 field names.
|
||||
|
||||
If you have scripts that process the output from these print commands, you may have to make modifications to your scripts.
|
||||
Run your print/show commands with a version of Standard Gam and save the output.
|
||||
Run your print/show commands with a version of Legacy Gam and save the output.
|
||||
With drive_v3_native_names = False, run your print/show commands with this version of Gam and compare the output to that saved in the previous run;
|
||||
modify your scripts that process the output as appropriate.
|
||||
|
||||
|
||||
@@ -10,6 +10,47 @@ Add the `-s` option to the end of the above commands to suppress creating the `g
|
||||
|
||||
See [Downloads-Installs](https://github.com/taers232c/GAMADV-XTD3/wiki/Downloads-Installs) for Windows or other options, including manual installation
|
||||
|
||||
### 7.00.08
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> delete groups` that caused the command to fail when `enable_dasa = true` in `gam.cfg`.
|
||||
|
||||
### 7.00.07
|
||||
|
||||
Updated `<PeopleContactAttribute>` fields `address,email,phone,url` to allow an empty type field.
|
||||
```
|
||||
address "" formatted "My Address" primary
|
||||
email "" user@gmail.com primary
|
||||
phone "" "510-555-1212" primary
|
||||
url "" "https://www.domain.com" primary
|
||||
```
|
||||
|
||||
### 7.00.06
|
||||
|
||||
Updated `gam <UserTypeEntity> create|update chatspace` to support the new permissions settings
|
||||
for Chat spaces that are in Developer Preview.
|
||||
|
||||
* See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces#Space.FIELDS.predefined_permission_settings
|
||||
|
||||
### 7.00.05
|
||||
|
||||
Fixed bug that caused an error when creating a calendar birthday event.
|
||||
|
||||
### 7.00.04
|
||||
|
||||
Improved performance of `gam report users orgunit <OrgUnitPath>` when `showorgunit` is not specified.
|
||||
|
||||
Added option `birthday <Date>` to `gam <UserTypeEntity> create event <UserCalendarEntity>` that adds
|
||||
an annual recurring event to the calendar.
|
||||
|
||||
Added `birthday` to `<EventType>` for use in various calendar event commands.
|
||||
|
||||
### 7.00.03
|
||||
|
||||
Updated `gam delete ou` and `gam print admins` to handle the following error:
|
||||
```
|
||||
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
|
||||
```
|
||||
|
||||
### 7.00.02
|
||||
|
||||
Added option `showlastmodification` to `gam <UserTypeEntity> print|show filecounts` that adds
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
|
||||
## Definitions
|
||||
See [Collections of Items](Collections-of-Items)
|
||||
|
||||
* [Command data from Google Docs/Sheets/Storage](Command-Data-From-Google-Docs-Sheets-Storage)
|
||||
```
|
||||
<StorageBucketName> ::= <String>
|
||||
<StorageObjectName> ::= <String>
|
||||
<StorageBucketObjectName> ::=
|
||||
https://storage.cloud.google.com/<StorageBucketName>/<StorageObjectName>|
|
||||
https://storage.googleapis.com/<StorageBucketName>/<StorageObjectName>|
|
||||
gs://<StorageBucketName>/<StorageObjectName>|
|
||||
<StorageBucketName>/<StorageObjectName>
|
||||
|
||||
<UserGoogleDoc> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
|
||||
|
||||
<SheetEntity> ::= <String>|id:<Number>
|
||||
<UserGoogleSheet> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>) <SheetEntity>
|
||||
```
|
||||
```
|
||||
<DeliverySetting> ::=
|
||||
allmail|
|
||||
|
||||
14
docs/Home.md
14
docs/Home.md
@@ -1,8 +1,7 @@
|
||||
- [Introduction](#introduction)
|
||||
- [Requirements](#requirements)
|
||||
- [Installation - First time GAM installation](#installation---first-time-gam-installation)
|
||||
- [Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-gam-version-other-than-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
|
||||
- [Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3](#installation---upgrading-from-a-prior-version-of-gamadv-x-or-gamadv-xtd-or-gamadv-xtd3)
|
||||
- [Installation - Upgrading from Legacy GAM](#installation---upgrading-from-legacy-gam)
|
||||
|
||||
# Introduction
|
||||
GAMADV-XTD3 is a free, open source command line tool for Google Workspace Administrators to manage domain and user settings quickly and easily.
|
||||
@@ -43,20 +42,13 @@ and all necessary authentications.
|
||||
* Configuration: [GAM Configuration](gam.cfg)
|
||||
* Install: [How to Install Advanced GAM](How-to-Install-Advanced-GAM)
|
||||
|
||||
# Installation - Upgrading from a GAM version other than a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
|
||||
# Installation - Upgrading from Legacy GAM
|
||||
Use these steps if you have used any version of GAM in your domain. They will update your GAM project
|
||||
and all necessary authentications.
|
||||
|
||||
* Download: [Downloads-Installs](Downloads-Installs)
|
||||
* Configuration: [GAM Configuration](gam.cfg)
|
||||
* Upgrade: [How to Upgrade from Standard GAM](How-to-Upgrade-from-Standard-GAM)
|
||||
|
||||
# Installation - Upgrading from a prior version of GAMADV-X or GAMADV-XTD or GAMADV-XTD3
|
||||
Use these steps if you already use GAMADV-X or GAMADV-XTD or GAMADV-XTD3. The updates may tell you to update your GAM project
|
||||
or authentications because new features have been included.
|
||||
|
||||
* Updates: [GAM Updates]
|
||||
* Download: [Downloads-Installs](Downloads-Installs)
|
||||
* Upgrade: [How to Upgrade from Legacy GAM](How-to-Upgrade-from-Legacy-GAM)
|
||||
|
||||
You can install multiple versions of GAM and GAMADV-XTD3 in different parallel directories.
|
||||
|
||||
|
||||
120
docs/How-to-Update-Advanced-GAM-to-GAM7.md
Normal file
120
docs/How-to-Update-Advanced-GAM-to-GAM7.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# Installation - Update Advanced GAM to GAM7
|
||||
|
||||
- [Downloads-Installs-GAM7](Downloads-Installs-GAM7)
|
||||
- [Linux and MacOS and Google Cloud Shell](#linux-and-mac-os-and-google-cloud-shell)
|
||||
- [Windows](#windows)
|
||||
|
||||
## Linux and MacOS and Google Cloud Shell
|
||||
|
||||
This example assumes that GAMADV-XTD3 was installed in /Users/admin/bin/gamadv-xtd3.
|
||||
If GAMADV-XTD3 was installed in another directory, substitute that value in the directions.
|
||||
|
||||
Rename install directory.
|
||||
```
|
||||
mv /Users/admin/bin/gamadv-xtd3 /Users/admin/bin/gam7
|
||||
```
|
||||
|
||||
See: [Downloads-Installs-GAM7](Downloads-Installs-GAM7)
|
||||
|
||||
You can download and install the current GAM7 release from the [GitHub Releases](https://github.com/GAM-team/GAM/releases/latest) page. Choose one of the following:
|
||||
|
||||
* Executable Archive, Automatic, Linux/Mac OS/Google Cloud Shell/Raspberry Pi/ChromeOS
|
||||
- Start a terminal session and execute one of the following commands:
|
||||
- Update to latest version, do not create project or authorizations, default path `$HOME/bin`
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install) -l`
|
||||
- Update to latest version, do not create project or authorizations, specify a path
|
||||
- `bash <(curl -s -S -L https://git.io/gam-install) -l -d <Path>`
|
||||
|
||||
In these examples, the user home folder is shown as /Users/admin; adjust according to your
|
||||
specific situation; e.g., /home/administrator.
|
||||
|
||||
### Update gam alias
|
||||
You should set an alias to point to /Users/admin/bin/gam/gam so you can operate from the /Users/admin/GAMWork directory.
|
||||
Aliases aren't available in scripts, so you may want to set a symlink instead, see below.
|
||||
|
||||
Change the following line:
|
||||
```
|
||||
alias gam="/Users/admin/bin/gamadv-xtd3/gam"
|
||||
```
|
||||
to
|
||||
```
|
||||
alias gam="/Users/admin/bin/gam7/gam"
|
||||
```
|
||||
in one of these files based on your shell:
|
||||
```
|
||||
~/.bash_aliases
|
||||
~/.bash_profile
|
||||
~/.bashrc
|
||||
~/.zshrc
|
||||
~/.profile
|
||||
```
|
||||
|
||||
Issue the following command replacing `<Filename>` with the name of the file you edited:
|
||||
```
|
||||
source <Filename>
|
||||
```
|
||||
|
||||
### Set a symlink if desired
|
||||
Set a symlink in `/usr/local/bin` (or some other location on $PATH) to point to GAM.
|
||||
```
|
||||
ln -s "/Users/admin/bin/gam7/gam" /usr/local/bin/gam
|
||||
```
|
||||
|
||||
### Test
|
||||
```
|
||||
gam version
|
||||
```
|
||||
|
||||
## Windows
|
||||
|
||||
You can download and install the current GAM7 release from the [GitHub Releases](https://github.com/GAM-team/GAM/releases/latest) page.
|
||||
|
||||
This example assumes that GAMADV-XTD3 was installed in C:\GAMADV-XTD3.
|
||||
If GAMADV-XTD3 was installed in another directory, substitute that value in the directions.
|
||||
|
||||
These steps assume Command Prompt, adjust if you're using PowerShell.
|
||||
|
||||
Rename install directory.
|
||||
```
|
||||
ren C:\GAMADV-STD3 C:\GAM7
|
||||
```
|
||||
|
||||
See: [Downloads-Installs-GAM7](Downloads-Installs-GAM7)
|
||||
|
||||
* Executable Archive, Manual, Windows 64 bit
|
||||
- `gam-7.wx.yz-windows-x86_64.zip`
|
||||
- Download the archive, extract the contents into C:\GAM7.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
* Executable Installer, Manual, Windows 64 bit
|
||||
- `gam-7.wx.yz-windows-x86_64.msi`
|
||||
- Download the installer and run it.
|
||||
- Start a Command Prompt/PowerShell session.
|
||||
|
||||
### Update system path
|
||||
You should set the system path to point to C:\GAM7 so you can operate from the C:\GAMWork directory.
|
||||
```
|
||||
Start Control Panel
|
||||
Click System
|
||||
Click Advanced system settings
|
||||
Click Environment Variables...
|
||||
Click Path under System variables
|
||||
Click Edit...
|
||||
If you have an existing entry referencing GAMADV-XTD3:
|
||||
Click that entry
|
||||
Click Delete
|
||||
If C:\GAM7 is already on the Path, skip the next three steps
|
||||
Click New
|
||||
Enter C:\GAM7
|
||||
Click OK
|
||||
Click OK
|
||||
Click OK
|
||||
Exit Control Panel
|
||||
```
|
||||
|
||||
At this point, you should restart Command Prompt so that it has the updated path and environment variables.
|
||||
|
||||
### Test
|
||||
```
|
||||
gam version
|
||||
```
|
||||
1262
docs/How-to-Upgrade-from-Legacy-GAM.md
Normal file
1262
docs/How-to-Upgrade-from-Legacy-GAM.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
- [Display organizational unit counts](#display-organizational-unit-counts)
|
||||
- [Display indented organizational unit tree](#display-indented-organizational-unit-tree)
|
||||
- [Check organizational unit for contained items](#check-organizational-unit-for-contained-items)
|
||||
- [Delete Empty OUs](#delete-empty-ous)
|
||||
- [Special case handling for large number of organizational units](#special-case-handling-for-large-number-of-organizational-units)
|
||||
|
||||
## API documentation
|
||||
@@ -321,6 +322,17 @@ You can inspect the file and execute it if desired; substitute actual filenames
|
||||
gam redirect stdout CleanOuLog.txt multiproces redirect stderr stdout batch CleanOuBatch.txt
|
||||
```
|
||||
|
||||
### Delete Empty OUs
|
||||
```
|
||||
# Get list of OUs
|
||||
gam redirect csv ./OUs.csv print ous
|
||||
# Check status of each OU
|
||||
gam redirect csv ./CheckOUs.csv multiprocess redirect stderr - multiprocess csv OUs.csv gam check ou "~orgUnitId"
|
||||
# Delete empty OUs
|
||||
gam config csv_input_row_filter "empty:boolean:true" redirect stdout ./DeleteEmptyOUs.txt multiprocess redirect stderr stdout csv CheckOUs.csv gam delete ou "~orgUnitId"
|
||||
```
|
||||
Repeat the steps until no empty OUs remain.
|
||||
|
||||
## Special case handling for large number of organizational units
|
||||
|
||||
By default, the `print orgs` and `show orgtree` commands issue a single API call to get the
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Scripts
|
||||
|
||||
These scripts can be used to enhance GAM's capabilities; all are supported with Advanced GAM,
|
||||
many are supported with Standard GAM. They require that Python 3 be installed on you computer.
|
||||
many are supported with Legacy GAM. They require that Python 3 be installed on you computer.
|
||||
|
||||
* https://github.com/taers232c/GAM-Scripts3
|
||||
* https://www.python.org/
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
* https://developers.google.com/calendar/v3/reference/events
|
||||
* https://developers.google.com/calendar/v3/reference/events/import
|
||||
* https://developers.google.com/calendar/api/guides/working-hours-and-location
|
||||
* https://developers.google.com/calendar/api/guides/event-types#birthday
|
||||
|
||||
## Definitions
|
||||
* [`<UserTypeEntity>`](Collections-of-Users)
|
||||
@@ -241,6 +242,7 @@
|
||||
```
|
||||
```
|
||||
<EventType> ::=
|
||||
birthday|
|
||||
default|
|
||||
focustime|
|
||||
fromgmail|
|
||||
@@ -306,6 +308,7 @@
|
||||
(attendee <EmailAddress>)|
|
||||
(attendeestatus [<AttendeeAttendance>] [<AttendeeStatus>] <EmailAddress>)|
|
||||
available|
|
||||
(birthday <Date>)|
|
||||
(color <EventColorName>)|
|
||||
(colorindex|colorid <EventColorIndex>)|
|
||||
(description <String>)|
|
||||
@@ -326,7 +329,7 @@
|
||||
(privateproperty <PropertyKey> <PropertyValue>)|
|
||||
(range <Date> <Date>)|
|
||||
(recurrence <RRULE, EXRULE, RDATE and EXDATE line>)|
|
||||
(reminder <Number> email|popup))|
|
||||
(reminder <Number> email|popup)|
|
||||
(selectattendees [<AttendeeAttendance>] [<AttendeeStatus>] <UserTypeEntity>)|
|
||||
(sequence <Integer>)|
|
||||
(sharedproperty <PropertyKey> <PropertyValue>)|
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Users - Chat
|
||||
- [API documentation](#api-documentation)
|
||||
- [Introduction](#introduction)
|
||||
- [Developer Preview Admin Access](#developer-preview-admin-access)
|
||||
- [Set up a Chat Bot](#set-up-a-chat-bot)
|
||||
- [Definitions](#definitions)
|
||||
- [Chat Space Permissions](#chat-space-permissions)
|
||||
- [Manage Chat Spaces](#manage-chat-spaces)
|
||||
- [Display Chat Spaces](#display-chat-spaces)
|
||||
- [Manage Chat Members](#manage-chat-members)
|
||||
@@ -20,7 +20,9 @@
|
||||
* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.messages/list
|
||||
* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces.spaceEvents/list
|
||||
* https://support.google.com/chat/answer/7655820
|
||||
* https://support.google.com/a/answer/13369245
|
||||
* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces/search
|
||||
* https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces#Space.FIELDS.predefined_permission_settings
|
||||
|
||||
## Introduction
|
||||
These features were added in version 6.60.00.
|
||||
@@ -30,36 +32,11 @@ To use these commands you must update your service account authorization.
|
||||
gam user user@domain.com update serviceaccount
|
||||
|
||||
[*] 4) Chat API - Memberships (supports readonly)
|
||||
[*] 5) Chat API - Memberships Admin (supports readonly)
|
||||
[*] 6) Chat API - Messages (supports readonly)
|
||||
[*] 7) Chat API - Spaces (supports readonly)
|
||||
[*] 9) Chat API - Spaces Delete
|
||||
|
||||
```
|
||||
|
||||
## Developer Preview Admin Access
|
||||
The Chat API Developer Preview allows an admin to perform certain actions
|
||||
on all Chat Spaces. These commands were added in version 6.77.00.
|
||||
|
||||
You must be enrolled in the Developer Preview program for the CHAT API to use these commands.
|
||||
|
||||
```
|
||||
gam <UserItem> delete chatspace asadmin
|
||||
gam <UserItem> update chatspace asadmin
|
||||
gam <UserItem> info chatspace asadmin
|
||||
gam <UserItem> print|show chatspaces asadmin
|
||||
gam <UserItem> create chatmember asadmin
|
||||
gam <UserItem> delete|remove chatmember asadmin
|
||||
gam <UserItem> update|modify chatmember asadmin
|
||||
gam <UserItem> sync chatmembers asadmin
|
||||
gam <UserItem> info chatmember asadmin
|
||||
gam <UserItem> print|show chatmembers|asadmin
|
||||
```
|
||||
To use these commands you must update your service account authorization.
|
||||
```
|
||||
gam user user@domain.com update serviceaccount
|
||||
|
||||
[*] 5) Chat API - Memberships Admin (supports readonly)
|
||||
[*] 8) Chat API - Spaces Admin (supports readonly)
|
||||
[*] 9) Chat API - Spaces Delete
|
||||
[*] 10) Chat API - Spaces Delete Admin
|
||||
```
|
||||
|
||||
@@ -71,15 +48,6 @@ Added `use_chat_admin_access` Boolean variable to `gam.cfg`.
|
||||
* Default: False
|
||||
```
|
||||
|
||||
If your account is not enrolled in the Chat API Developer Preview, you will see errors like this:
|
||||
```
|
||||
$ gam user admin@domain.com show chatspaces asadmin
|
||||
Getting all Chat Spaces that match query (customer = "customers/my_customer" AND spaceType = "SPACE") for admin@domain.com(asadmin)
|
||||
Chat Admin: admin@domain.com(asadmin), Show Failed: Method not found.
|
||||
```
|
||||
|
||||
To enroll in the Developer Preview program, see: https://developers.google.com/workspace/preview
|
||||
|
||||
Google requires that you have a Chat Bot configured in order to use the Chat API; set up a Chat Bot as described in the next section.
|
||||
|
||||
## Set up a Chat Bot
|
||||
@@ -139,6 +107,7 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
|
||||
lastactivetime|
|
||||
membershipcount|
|
||||
name|
|
||||
permissionsettings|
|
||||
singleuserbotdm|
|
||||
spacedetails|
|
||||
spacehistorystate|
|
||||
@@ -188,11 +157,36 @@ Google requires that you have a Chat Bot configured in order to use the Chat API
|
||||
|
||||
```
|
||||
|
||||
## Chat Space Permissions
|
||||
### Announcement
|
||||
| Keyword | Description | Allowed | Default |
|
||||
|---------|-------------|---------|---------|
|
||||
| manageapps | Manage apps | managers-immutable | managers |
|
||||
| managemembersandgroups | Manage members and groups | managers/members | managers |
|
||||
| managewebhooks | Manage web hooks | managers-immutable | managers |
|
||||
| modifyspacedetails | Modify space details | managers/members | managers |
|
||||
| postmessages | Post messages | managers-immutable | managers |
|
||||
| replymessages | Reply messages | members/managers | members |
|
||||
| togglehistory | Turn history on and off | managers/members | managers |
|
||||
| useatmentionall | Use @all | managers-immutable | managers |
|
||||
|
||||
### Collaboration
|
||||
| Keyword | Description | Allowed | Default |
|
||||
|---------|-------------|---------|---------|
|
||||
| manageapps | Manage apps | members-immutable | members |
|
||||
| managemembersandgroups | Manage members and groups | managers/members | members |
|
||||
| managewebhooks | Manage web hooks | managers/members | members |
|
||||
| modifyspacedetails | Modify space details | managers/members | members |
|
||||
| postmessages | Post messages | members-immutable | members |
|
||||
| replymessages | Reply messages | members-immutable | members |
|
||||
| togglehistory | Turn history on and off | managers/members | members |
|
||||
| useatmentionall | Use @all | managers/members | members |
|
||||
|
||||
## Manage Chat Spaces
|
||||
### Create a chat space
|
||||
```
|
||||
gam <UserTypeEntity> create chatspace
|
||||
[type <ChatSpaceType>]
|
||||
[type <ChatSpaceType>] [announcement|collaboration]
|
||||
[restricted|(audience <String>)]
|
||||
[externalusersallowed <Boolean>]
|
||||
[members <UserTypeEntity>]
|
||||
@@ -208,6 +202,7 @@ For `type space`, the following apply:
|
||||
* `description <String>` - Optional
|
||||
* `guidelines <String>` - Optional
|
||||
* `history <Boolean>` - Optional
|
||||
* `announcement|collaboration` - Initial permission settings; default is `collaboration`; this is in Developer Preview
|
||||
|
||||
For `type groupchat`, the following apply:
|
||||
* `members <UserTypeEntity>` - Required, must specify between 2 and 20 users
|
||||
@@ -229,8 +224,6 @@ By default, Gam displays the information about the created chatspace as an inden
|
||||
|
||||
Use the `<ChatContent>` option to send an initial message to the created chatspace.
|
||||
|
||||
The `restricted|audience` options are in Developer Preview and will not be generally available.
|
||||
|
||||
By default, details about the chatmessage are displayed.
|
||||
* `returnidonly` - Display the chatmessage name only
|
||||
|
||||
@@ -242,12 +235,29 @@ gam <UserTypeEntity> update chatspace <ChatSpace>
|
||||
[type space]
|
||||
[description <String>] [guidelines|rules <String>]
|
||||
[history <Boolean>])
|
||||
[managemembersandgroups managers|members]
|
||||
[modifyspacedetails managers|members]
|
||||
[togglehistory managers|members]
|
||||
[useatmentionall managers|members]
|
||||
[manageapps managers|members]
|
||||
[managewebhooks managers|members]
|
||||
[replymessages managers|members]
|
||||
[formatjson]
|
||||
```
|
||||
A groupchat space can be upgraded to a space by specifying `type space` and `displayname <String>`.
|
||||
|
||||
The `restricted|audience` options can not be combined with options `displayname,type,description,guidelines,history`.
|
||||
They are in Developer Preview and will not be generally available.
|
||||
|
||||
You can manage permissions for chat spaces with the following options that are available with Developer Preview.
|
||||
[managemembersandgroups managers|members]
|
||||
[modifyspacedetails managers|members]
|
||||
[togglehistory managers|members]
|
||||
[useatmentionall managers|members]
|
||||
[manageapps managers|members]
|
||||
[managewebhooks managers|members]
|
||||
[postmessages managers|members]
|
||||
[replymessages managers|members]
|
||||
|
||||
|
||||
By default, Gam displays the information about the created chatspace as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
@@ -265,7 +275,6 @@ gam <UserItem> update chatspace asadmin <ChatSpace>
|
||||
A groupchat space can be upgraded to a space by specifying `type space` and `displayname <String>`.
|
||||
|
||||
The `restricted|audience` options can not be combined with options `displayname,type,description,guidelines,history`.
|
||||
They are in Developer Preview and will not be generally available.
|
||||
|
||||
By default, Gam displays the information about the created chatspace as an indented list of keys and values.
|
||||
* `formatjson` - Display the fields in JSON format.
|
||||
@@ -398,7 +407,6 @@ When using the `formatjson` option, double quotes are used extensively in the da
|
||||
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
|
||||
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
|
||||
|
||||
|
||||
## Manage Chat Members
|
||||
### Add members to a user's chat space
|
||||
```
|
||||
|
||||
@@ -722,7 +722,7 @@ as it does now. Of course, if the query really is invalid, you will get the mess
|
||||
|
||||
The `showsize` option displays the total size (in bytes) of the files counted.
|
||||
|
||||
The showmimetypesize' displays the total size (in bytes) of each MIME type counted.
|
||||
The `showmimetypesize` option displays the total size (in bytes) of each MIME type counted.
|
||||
|
||||
The option `showlastmodification` displays the following fields:
|
||||
`lastModifiedFileId,lastModifiedFileName,lastModifyingUser,lastModifiedTime`;
|
||||
|
||||
@@ -208,7 +208,7 @@ If `noduplicate` is specfied, GAM will issue a warning and not perform the creat
|
||||
exists in the parent folder.
|
||||
|
||||
By default, when files are uploaded from local content, they are created with `binary` format, i.e., the data is uploaded
|
||||
without any conversion. Standard GAM had an option `convert` that was passed to the Drive API v2 that it used.
|
||||
without any conversion. Legacy GAM had an option `convert` that was passed to the Drive API v2 that it used.
|
||||
* convert - Whether to convert this file to the corresponding Docs Editors format
|
||||
|
||||
Advanced GAM uses Drive API v3 that doesn't support the `convert` option; it uses the `mimetype` argument to cause conversions.
|
||||
|
||||
@@ -125,8 +125,15 @@ gam user user@domain.com check serviceaccount
|
||||
(subject <String>)|
|
||||
(suffix <String>)|
|
||||
(userdefinedfield clear|(<String> <String>))|
|
||||
(website clear|(app_install_page|blog|ftp|home|home_page|other|profile|reservations|work|<String> <URL> notprimary|primary))
|
||||
(url|website clear|(app_install_page|blog|ftp|home|home_page|other|profile|reservations|work|<String> <URL> notprimary|primary))
|
||||
|
||||
For address, email, phone and url, the type <String> can be empty.
|
||||
address "" formatted "My Address" primary
|
||||
email "" user@gmail.com primary
|
||||
phone "" "510-555-1212" primary
|
||||
url "" "https://www.domain.com" primary
|
||||
```
|
||||
```
|
||||
<PeopleFieldName> ::=
|
||||
addresses|
|
||||
ageranges|
|
||||
|
||||
@@ -80,6 +80,22 @@ queries "`"orgUnitPath=\'/Students/Lower\ School/2027\'`",`"orgUnitPath=\'/Stude
|
||||
* [`<UserTypeEntity>`](Collections-of-Users)
|
||||
* [Command data from Google Docs/Sheets/Storage](Command-Data-From-Google-Docs-Sheets-Storage)
|
||||
```
|
||||
<StorageBucketName> ::= <String>
|
||||
<StorageObjectName> ::= <String>
|
||||
<StorageBucketObjectName> ::=
|
||||
https://storage.cloud.google.com/<StorageBucketName>/<StorageObjectName>|
|
||||
https://storage.googleapis.com/<StorageBucketName>/<StorageObjectName>|
|
||||
gs://<StorageBucketName>/<StorageObjectName>|
|
||||
<StorageBucketName>/<StorageObjectName>
|
||||
|
||||
<UserGoogleDoc> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>)
|
||||
|
||||
<SheetEntity> ::= <String>|id:<Number>
|
||||
<UserGoogleSheet> ::=
|
||||
<EmailAddress> <DriveFileIDEntity>|<DriveFileNameEntity>|(<SharedDriveEntity> <SharedDriveFileNameEntity>) <SheetEntity>
|
||||
```
|
||||
```
|
||||
<DeliverySetting> ::=
|
||||
allmail|
|
||||
abridged|daily|
|
||||
@@ -736,7 +752,7 @@ When updating a user's password, you can send a message with the new password to
|
||||
|
||||
In versions of GAMADV-XTD3 prior to 5.07.00, if you do `gam update users <UserTypeEntity>` or `gam <UserTypeEntity> update users` and
|
||||
specify `password random`, all of the users in `<UserTypeEntity>` are assigned the same random password;
|
||||
this is the same behavior as in Standard GAM. If you would like each of the users in `<UserTypeEntity>` to be
|
||||
this is the same behavior as in Legacy GAM. If you would like each of the users in `<UserTypeEntity>` to be
|
||||
assigned a unique random password, specify `password uniquerandom`.
|
||||
|
||||
If you update a user with `password random|uniquerandom`, the `lograndompassword <FileName>` option causes GAM
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Print the current version of Gam with details
|
||||
```
|
||||
gam version
|
||||
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 7.00.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.5 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -15,7 +15,7 @@ Time: 2023-06-02T21:10:00-07:00
|
||||
Print the current version of Gam with details and time offset information
|
||||
```
|
||||
gam version timeoffset
|
||||
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 7.00.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.5 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -27,7 +27,7 @@ Your system time differs from www.googleapis.com by less than 1 second
|
||||
Print the current version of Gam with extended details and SSL information
|
||||
```
|
||||
gam version extended
|
||||
GAMADV-XTD3 7.00.02 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
GAMADV-XTD3 7.00.08 - https://github.com/taers232c/GAMADV-XTD3 - pythonsource
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.5 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
@@ -64,7 +64,7 @@ MacOS High Sierra 10.13.6 x86_64
|
||||
Path: /Users/Admin/bin/gamadv-xtd3
|
||||
Version Check:
|
||||
Current: 5.35.08
|
||||
Latest: 7.00.02
|
||||
Latest: 7.00.08
|
||||
echo $?
|
||||
1
|
||||
```
|
||||
@@ -72,7 +72,7 @@ echo $?
|
||||
Print the current version number without details
|
||||
```
|
||||
gam version simple
|
||||
7.00.02
|
||||
7.00.08
|
||||
```
|
||||
In Linux/MacOS you can do:
|
||||
```
|
||||
@@ -82,7 +82,7 @@ echo $VER
|
||||
Print the current version of Gam and address of this Wiki
|
||||
```
|
||||
gam help
|
||||
GAM 7.00.02 - https://github.com/taers232c/GAMADV-XTD3
|
||||
GAM 7.00.08 - https://github.com/taers232c/GAMADV-XTD3
|
||||
Ross Scroggs <ross.scroggs@gmail.com>
|
||||
Python 3.12.5 64-bit final
|
||||
MacOS Sonoma 14.5 x86_64
|
||||
|
||||
@@ -3,9 +3,9 @@ Update History
|
||||
|
||||
Installation
|
||||
* [How to Install Advanced GAM](How-to-Install-Advanced-GAM)
|
||||
* [How to Update Advanced GAM to GAM7](How-to-Update-Advanced-GAM-to-GAM7)
|
||||
* [How to Update Advanced GAM](How-to-Update-Advanced-GAM)
|
||||
* [How to Upgrade from Standard GAM](How-to-Upgrade-from-Standard-GAM)
|
||||
* [How to Upgrade from GAMADV-X or GAMADV-XTD](How-to-Upgrade-from-GAMADV-X-or-GAMADV-XTD)
|
||||
* [How to Upgrade from Legacy GAM](How-to-Upgrade-from-Legacy-GAM)
|
||||
* [Install GAM as Python Library](Install-GAM-as-Python-Library)
|
||||
* [GAMADV-XTD3 on Chrome OS Devices](GAMADV-XTD3-on-Chrome-OS-Devices)
|
||||
* [GAMADV-XTD3 on Android Devices](GAMADV-XTD3-on-Android-Devices)
|
||||
|
||||
@@ -944,11 +944,11 @@ domain = goo.com
|
||||
customer_id = my_customer
|
||||
config_dir = goo
|
||||
```
|
||||
### Existing clients that have been accessed with Standard GAM.
|
||||
### Existing clients that have been accessed with Legacy GAM.
|
||||
You have two clients: foo and goo.
|
||||
Make sub-directories foo and goo in the same folder/directory as gam.cfg.
|
||||
For each client, copy the client_secrets.json and oauth2service.json files from their Standard GAM location
|
||||
to the appropriate sub-directory. If the Standard Gam files do not have these names,
|
||||
For each client, copy the client_secrets.json and oauth2service.json files from their Legacy GAM location
|
||||
to the appropriate sub-directory. If the Legacy Gam files do not have these names,
|
||||
rename them after copying them to the sub-directory.
|
||||
|
||||
Perform the following commands for each client (replace xxx with foo and goo).
|
||||
|
||||
@@ -1594,6 +1594,7 @@ gam calendar <CalendarEntity> printacl [todrive <ToDriveAttribute>*]
|
||||
<AttendeeStatus> ::= accepted|declined|needsaction|tentative
|
||||
|
||||
<EventType> ::=
|
||||
birthday|
|
||||
default|
|
||||
focustime|
|
||||
fromgmail|
|
||||
@@ -2047,6 +2048,7 @@ gam setup chat
|
||||
lastactivetime|
|
||||
membershipcount|
|
||||
name|
|
||||
permissionsettings|
|
||||
singleuserbotdm|
|
||||
spacedetails|
|
||||
spacehistorystate|
|
||||
@@ -5847,6 +5849,7 @@ gam <UserTypeEntity> transfer calendars|seccals <UserItem> [<UserCalendarEntity>
|
||||
<AttendeeStatus> ::= accepted|declined|needsaction|tentative
|
||||
|
||||
<EventType> ::=
|
||||
birthday|
|
||||
default|
|
||||
focustime|
|
||||
outofoffice|
|
||||
@@ -5896,13 +5899,15 @@ gam <UserTypeEntity> transfer calendars|seccals <UserItem> [<UserCalendarEntity>
|
||||
<AttendeeStatus> ::= accepted|declined|needsaction|tentative
|
||||
|
||||
<EventAttribute> ::=
|
||||
(allday <Date>)|
|
||||
(anyonecanaddself [<Boolean>])|
|
||||
(attachment <String> <URL>)|
|
||||
(attendee <EmailAddress>)|
|
||||
(attendeestatus [<AttendeeAttendance>] [<AttendeeStatus>] <EmailAddress>)|
|
||||
available|
|
||||
(birthday <Date>)|
|
||||
(color <EventColorName>)|
|
||||
(colorindex|colorid <EventColorIndex>))|
|
||||
(colorindex|colorid <EventColorIndex>)|
|
||||
(description <String>)|
|
||||
(end|endtime (allday <Date>)|<Time>)|
|
||||
(guestscaninviteothers <Boolean>)|
|
||||
@@ -5912,14 +5917,16 @@ gam <UserTypeEntity> transfer calendars|seccals <UserItem> [<UserCalendarEntity>
|
||||
guestscantseeotherguests|
|
||||
hangoutsmeet|
|
||||
<JSONData>|
|
||||
(jsonattendees [charset <Charset>] <String>)|(jsonattendees file <FileName> [charset <Charset>])|
|
||||
(jsonattendees [charset <Charset>] <String>)|
|
||||
(jsonattendees file <FileName> [charset <Charset>])|
|
||||
(location <String>)|
|
||||
(noreminders|(reminder email|popup <Number>))|
|
||||
(optionalattendee <EmailAddress>)|
|
||||
(originalstart|originalstarttime (allday <Date>)|<Time>)|
|
||||
(privateproperty <PropertyKey> <PropertyValue>)|
|
||||
(range <Date> <Date>)|
|
||||
(recurrence <RRULE, EXRULE, RDATE and EXDATE line>)|
|
||||
(reminder <Number> email|popup))|
|
||||
(reminder <Number> email|popup)|
|
||||
(selectattendees [<AttendeeAttendance>] [<AttendeeStatus>] <UserTypeEntity>)|
|
||||
(sequence <Integer>)|
|
||||
(sharedproperty <PropertyKey> <PropertyValue>)|
|
||||
@@ -5928,6 +5935,7 @@ gam <UserTypeEntity> transfer calendars|seccals <UserItem> [<UserCalendarEntity>
|
||||
(status confirmed|tentative|cancelled)|
|
||||
(summary <String>)|
|
||||
tentative|
|
||||
(timerange <Time> <Time>)|
|
||||
(timezone <TimeZone>)|
|
||||
(transparency opaque|transparent)|
|
||||
(visibility default|public|private)
|
||||
@@ -6086,7 +6094,7 @@ gam <UserTypeEntity> print focustime|outofoffice|workinglocation
|
||||
<String> must contain only lowercase letters, numbers, and hyphens up to 56 characters in length.
|
||||
|
||||
gam <UserTypeEntity> create chatspace
|
||||
[type <ChatSpaceType>]
|
||||
[type <ChatSpaceType>] [announcement|collaboration]
|
||||
[restricted|(audience <String>)]
|
||||
[externalusersrallowed <Boolean>]
|
||||
[members <UserTypeEntity>]
|
||||
@@ -6101,6 +6109,13 @@ gam <UserTypeEntity> update chatspace <ChatSpace>
|
||||
[type space]
|
||||
[description <String>] [guidelines|rules <String>]
|
||||
[history <Boolean>])
|
||||
[managemembersandgroups managers|members]
|
||||
[modifyspacedetails managers|members]
|
||||
[togglehistory managers|members]
|
||||
[useatmentionall managers|members]
|
||||
[manageapps managers|members]
|
||||
[managewebhooks managers|members]
|
||||
[replymessages managers|members]
|
||||
[formatjson]
|
||||
gam <UserTypeEntity> delete chatspace <ChatSpace>
|
||||
|
||||
@@ -7887,7 +7902,7 @@ gam <UserItem> print meettranscripts <MeetConferenceName> [todrive <ToDriveAttri
|
||||
(subject <String>)|
|
||||
(suffix <String>)|
|
||||
(userdefinedfield clear|(<String> <String>))|
|
||||
(website clear|(app_install_page|blog|ftp|home|home_page|other|profile|reservations|work|<String> <URL> notprimary|primary))
|
||||
(url|website clear|(app_install_page|blog|ftp|home|home_page|other|profile|reservations|work|<String> <URL> notprimary|primary))
|
||||
|
||||
<PeopleUserContactSelection> ::=
|
||||
[(selectcontactgroup <PeopleContactGroupItem>)|
|
||||
|
||||
@@ -1,3 +1,44 @@
|
||||
7.00.08
|
||||
|
||||
Fixed bug in `gam <UserTypeEntity> delete groups` that caused the command to fail when `enable_dasa = true` in `gam.cfg`.
|
||||
|
||||
7.00.07
|
||||
|
||||
Updated `<PeopleContactAttribute>` fields `address,email,phone,url` to allow an empty type field.
|
||||
```
|
||||
address "" formatted "My Address" primary
|
||||
email "" user@gmail.com primary
|
||||
phone "" "510-555-1212" primary
|
||||
url "" "https://www.domain.com" primary
|
||||
```
|
||||
|
||||
7.00.06
|
||||
|
||||
Updated `gam <UserTypeEntity> create|update chatspace` to support the new permissions settings
|
||||
for Chat spaces that are in Developer Preview.
|
||||
|
||||
* See: https://developers.google.com/workspace/chat/api/reference/rest/v1/spaces#Space.FIELDS.predefined_permission_settings
|
||||
|
||||
7.00.05
|
||||
|
||||
Fixed bug that caused an error when creating a calendar birthday event.
|
||||
|
||||
7.00.04
|
||||
|
||||
Improved performance of `gam report users orgunit <OrgUnitPath>` when `showorgunit` is not specified.
|
||||
|
||||
Added option `birthday <Date>` to `gam <UserTypeEntity> create event <UserCalendarEntity>` that adds
|
||||
an annual recurring event to the calendar.
|
||||
|
||||
Added `birthday` to `<EventType>` for use in various calendar event commands.
|
||||
|
||||
7.00.03
|
||||
|
||||
Updated `gam delete ou` and `gam print admins` to handle the following error:
|
||||
```
|
||||
ERROR: 503: serviceNotAvailable - The service is currently unavailable.
|
||||
```
|
||||
|
||||
7.00.02
|
||||
|
||||
Added option `showlastmodification` to `gam <UserTypeEntity> print|show filecounts` that adds
|
||||
|
||||
4880
src/chat-v1.json
4880
src/chat-v1.json
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@ EOF
|
||||
}
|
||||
|
||||
target_dir="$HOME/bin"
|
||||
target_gam="gam/gam"
|
||||
target_gam="gam7/gam"
|
||||
gamarch=$(uname -m)
|
||||
gamos=$(uname -s)
|
||||
osversion=""
|
||||
@@ -141,25 +141,28 @@ case $gamos in
|
||||
;;
|
||||
[Mm]ac[Oo][sS]|[Dd]arwin)
|
||||
gamos="macos"
|
||||
fullversion=$(sw_vers -productVersion)
|
||||
osversion=${fullversion:0:2}
|
||||
case $gamarch in
|
||||
x86_64)
|
||||
fullversion=$(sw_vers -productVersion)
|
||||
osversion=${fullversion:0:2}
|
||||
case ${osversion:0:2} in
|
||||
11|12|13|14)
|
||||
gamfile="macos-x86_64.tar.xz";;
|
||||
*)
|
||||
echo_red "Sorry, this version ($fullversion) of MacOS is not supported. Exiting."
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
gamfile="macos-x86_64.tar.xz"
|
||||
minimum_version=13
|
||||
;;
|
||||
arm|arm64|aarch64)
|
||||
gamfile="macos-aarch64.tar.xz";;
|
||||
gamfile="macos-aarch64.tar.xz"
|
||||
minimum_version=14
|
||||
;;
|
||||
*)
|
||||
echo_red "ERROR: this installer currently only supports x86_64 and arm64 MacOS. Looks like you're running on $gamarch. Exiting."
|
||||
exit
|
||||
;;
|
||||
esac
|
||||
if [[ "$osversion" -ge "$minimum_version" ]]; then
|
||||
echo_green "You are running MacOS ${fullversion}, good. Using GAM with ${gamfile}."
|
||||
else
|
||||
echo_red "Sorry, you are running MacOS ${fullversion} but GAM on ${gamarch} requires MacOS ${minimum_version}. Exiting."
|
||||
exit
|
||||
fi
|
||||
;;
|
||||
MINGW64_NT*)
|
||||
gamos="windows"
|
||||
|
||||
83
src/gam.spec
83
src/gam.spec
@@ -12,7 +12,6 @@ for pkg in GAM_VER_LIBS:
|
||||
datas += copy_metadata(pkg, recursive=True)
|
||||
datas += [('admin-directory_v1.1beta1.json', '.')]
|
||||
datas += [('cbcm-v1.1beta1.json', '.')]
|
||||
datas += [('chat-v1.json', '.')]
|
||||
datas += [('contactdelegation-v1.json', '.')]
|
||||
datas += [('datastudio-v1.json', '.')]
|
||||
datas += [('serviceaccountlookup-v1.json', '.')]
|
||||
@@ -21,7 +20,7 @@ hiddenimports = [
|
||||
'gam.gamlib.yubikey',
|
||||
]
|
||||
|
||||
print(f"datas before analysis:\n{datas}")
|
||||
runtime_hooks = []
|
||||
a = Analysis(
|
||||
['gam/__main__.py'],
|
||||
pathex=[],
|
||||
@@ -30,30 +29,35 @@ a = Analysis(
|
||||
hiddenimports=hiddenimports,
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
runtime_hooks=runtime_hooks,
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=None,
|
||||
noarchive=False,
|
||||
)
|
||||
print(f"datas from analysis:\n{a.datas}")
|
||||
#print(f"datas from analysis:\n{a.datas}")
|
||||
for d in a.datas:
|
||||
if 'pyconfig' in d[0]:
|
||||
a.datas.remove(d)
|
||||
break
|
||||
print(f"datas after pyconfig cleanup:\n{a.datas}")
|
||||
#print(f"datas after pyconfig cleanup:\n{a.datas}")
|
||||
pyz = PYZ(a.pure,
|
||||
a.zipped_data,
|
||||
cipher=None)
|
||||
# requires Python 3.10+ but no one should be compiling
|
||||
# GAM with older versions anyway
|
||||
target_arch = None
|
||||
codesign_identity = None
|
||||
entitlements_file = None
|
||||
match platform:
|
||||
case "darwin":
|
||||
if getenv('arch') == 'universal2':
|
||||
target_arch = "universal2"
|
||||
else:
|
||||
target_arch = None
|
||||
|
||||
codesign_identity = getenv('codesign_identity')
|
||||
if codesign_identity:
|
||||
entitlements_file = '../.github/actions/entitlements.plist'
|
||||
strip = True
|
||||
case "win32":
|
||||
target_arch = None
|
||||
@@ -68,9 +72,38 @@ upx = False
|
||||
console = True
|
||||
disable_windowed_traceback = False
|
||||
argv_emulation = False
|
||||
codesign_identity = None
|
||||
entitlements_file = None
|
||||
if not getenv('PYINSTALLER_BUILD_ONEDIR') == 'yes':
|
||||
if getenv('PYINSTALLER_BUILD_ONEDIR') == 'yes':
|
||||
# Build one directory
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name=name,
|
||||
debug=debug,
|
||||
bootloader_ignore_signals=bootloader_ignore_signals,
|
||||
strip=strip,
|
||||
upx=upx,
|
||||
console=console,
|
||||
# put most everyting under a lib/ subfolder
|
||||
contents_directory='lib',
|
||||
disable_windowed_traceback=disable_windowed_traceback,
|
||||
argv_emulation=argv_emulation,
|
||||
target_arch=target_arch,
|
||||
codesign_identity=codesign_identity,
|
||||
entitlements_file=entitlements_file,
|
||||
)
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=strip,
|
||||
upx=upx,
|
||||
upx_exclude=[],
|
||||
name=name,
|
||||
)
|
||||
else:
|
||||
# Build one file
|
||||
exe = EXE(
|
||||
pyz,
|
||||
@@ -91,32 +124,4 @@ if not getenv('PYINSTALLER_BUILD_ONEDIR') == 'yes':
|
||||
codesign_identity=codesign_identity,
|
||||
entitlements_file=entitlements_file,
|
||||
)
|
||||
else:
|
||||
# Build one folder
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name=name,
|
||||
debug=debug,
|
||||
bootloader_ignore_signals=bootloader_ignore_signals,
|
||||
strip=strip,
|
||||
upx=upx,
|
||||
console=console,
|
||||
disable_windowed_traceback=disable_windowed_traceback,
|
||||
argv_emulation=argv_emulation,
|
||||
target_arch=target_arch,
|
||||
codesign_identity=codesign_identity,
|
||||
entitlements_file=entitlements_file,
|
||||
)
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=strip,
|
||||
upx=upx,
|
||||
upx_exclude=[],
|
||||
name=name,
|
||||
)
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<ComponentGroup
|
||||
Id="ProductComponents"
|
||||
Directory="INSTALLFOLDER"
|
||||
Source="dist/gam">
|
||||
Source="dist/gam7">
|
||||
<Component Id="gam_exe" Guid="d046ea24-c9f8-40ca-84db-70b0119933ff">
|
||||
<File Name="gam.exe" KeyPath="yes" />
|
||||
<Environment Id="PATH" Name="PATH" Value="[INSTALLFOLDER]" Permanent="yes" Part="last" Action="set" System="yes" />
|
||||
|
||||
56
src/gam.wxs.template
Normal file
56
src/gam.wxs.template
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" >
|
||||
<Product
|
||||
Id="*"
|
||||
Name="GAM7"
|
||||
Language="1033"
|
||||
Version="$(env.GAMVERSION)"
|
||||
Manufacturer="GAM Team - google-apps-manager@googlegroups.com"
|
||||
UpgradeCode="D86B52B2-EFE9-4F9D-8BA3-9D84B9B2D319">
|
||||
<Package
|
||||
InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
|
||||
|
||||
<MajorUpgrade
|
||||
DowngradeErrorMessage=
|
||||
"A newer version of [ProductName] is already installed."
|
||||
Schedule="afterInstallExecute" />
|
||||
<MediaTemplate EmbedCab="yes" />
|
||||
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
<WixVariable Id="WixUILicenseRtf" Value="LICENSE.rtf" />
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
|
||||
<Feature
|
||||
Id="gam"
|
||||
Title="GAM7"
|
||||
Level="1">
|
||||
<ComponentGroupRef Id="ProductComponents" />
|
||||
</Feature>
|
||||
</Product>
|
||||
|
||||
<Fragment>
|
||||
<SetDirectory Id="WINDOWSVOLUME" Value="[WindowsVolume]"/>
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="WINDOWSVOLUME">
|
||||
<Directory Id="INSTALLFOLDER" Name="GAM7" />
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<!-- Group of components that are our main application items -->
|
||||
<ComponentGroup
|
||||
Id="ProductComponents"
|
||||
Directory="INSTALLFOLDER"
|
||||
Source="dist/gam7">
|
||||
REPLACE_ME_WITH_FILE_COMPONENTS
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<InstallUISequence>
|
||||
<ExecuteAction />
|
||||
<Show Dialog="WelcomeDlg" Before="ProgressDlg" />
|
||||
</InstallUISequence>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# GAM
|
||||
# GAM7
|
||||
#
|
||||
# Copyright 2024, All Rights Reserved.
|
||||
#
|
||||
@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
|
||||
"""
|
||||
|
||||
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
|
||||
__version__ = '7.00.02'
|
||||
__version__ = '7.00.08'
|
||||
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
|
||||
|
||||
#pylint: disable=wrong-import-position
|
||||
@@ -9190,6 +9190,7 @@ MACOS_CODENAMES = {
|
||||
12: 'Monterey',
|
||||
13: 'Ventura',
|
||||
14: 'Sonoma',
|
||||
15: 'Sequoia',
|
||||
}
|
||||
|
||||
def getOSPlatform():
|
||||
@@ -9231,7 +9232,7 @@ def doCheckConnection():
|
||||
api_hosts.append(host)
|
||||
hosts.extend(sorted(api_hosts))
|
||||
host_count = len(hosts)
|
||||
httpObj = getHttpObj(timeout=10)
|
||||
httpObj = getHttpObj(timeout=30)
|
||||
httpObj.follow_redirects = False
|
||||
headers = {'user-agent': GAM_USER_AGENT}
|
||||
okay = createGreenText('OK')
|
||||
@@ -13803,7 +13804,8 @@ def doReport():
|
||||
Ent.SetGetting(Ent.REPORT)
|
||||
elif userKey == 'all':
|
||||
if orgUnitId:
|
||||
userOrgUnits = getUserOrgUnits(cd, orgUnit, orgUnitId)
|
||||
if showOrgUnit:
|
||||
userOrgUnits = getUserOrgUnits(cd, orgUnit, orgUnitId)
|
||||
forWhom = f'users in orgUnit {orgUnit}'
|
||||
else:
|
||||
forWhom = 'all users'
|
||||
@@ -13989,7 +13991,8 @@ def doReport():
|
||||
orgUnitId = None
|
||||
elif userKey == 'all':
|
||||
if orgUnitId:
|
||||
userOrgUnits = getUserOrgUnits(cd, orgUnit, orgUnitId)
|
||||
if showOrgUnit:
|
||||
userOrgUnits = getUserOrgUnits(cd, orgUnit, orgUnitId)
|
||||
printGettingEntityItemForWhom(Ent.REPORT, f'users in orgUnit {orgUnit}')
|
||||
else:
|
||||
printGettingEntityItemForWhom(Ent.REPORT, 'all users')
|
||||
@@ -16623,13 +16626,15 @@ def doPrintShowAdmins():
|
||||
try:
|
||||
admins = callGAPIpages(cd.roleAssignments(), 'list', 'items',
|
||||
pageMessage=getPageMessage(),
|
||||
throwReasons=[GAPI.INVALID, GAPI.USER_NOT_FOUND, GAPI.BAD_REQUEST,
|
||||
GAPI.CUSTOMER_NOT_FOUND, GAPI.FORBIDDEN],
|
||||
throwReasons=[GAPI.INVALID, GAPI.USER_NOT_FOUND,
|
||||
GAPI.FORBIDDEN, GAPI.SERVICE_NOT_AVAILABLE,
|
||||
GAPI.BAD_REQUEST, GAPI.CUSTOMER_NOT_FOUND],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
customer=GC.Values[GC.CUSTOMER_ID], fields=fields, **kwargs)
|
||||
except (GAPI.invalid, GAPI.userNotFound):
|
||||
entityUnknownWarning(Ent.ADMINISTRATOR, userKey)
|
||||
return
|
||||
except GAPI.forbidden as e:
|
||||
except (GAPI.forbidden, GAPI.serviceNotAvailable) as e:
|
||||
entityActionFailedExit([Ent.ADMINISTRATOR, userKey, Ent.ADMIN_ROLE, roleId], str(e))
|
||||
except (GAPI.badRequest, GAPI.customerNotFound):
|
||||
accessErrorExit(cd)
|
||||
@@ -17334,14 +17339,17 @@ def _doDeleteOrgs(entityList):
|
||||
try:
|
||||
orgUnitPath = makeOrgUnitPathAbsolute(orgUnitPath)
|
||||
callGAPI(cd.orgunits(), 'delete',
|
||||
throwReasons=[GAPI.CONDITION_NOT_MET, GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND, GAPI.BACKEND_ERROR, GAPI.BAD_REQUEST, GAPI.INVALID_CUSTOMER_ID, GAPI.LOGIN_REQUIRED],
|
||||
throwReasons=[GAPI.CONDITION_NOT_MET, GAPI.INVALID_ORGUNIT, GAPI.ORGUNIT_NOT_FOUND, GAPI.BACKEND_ERROR,
|
||||
GAPI.INVALID_CUSTOMER_ID, GAPI.SERVICE_NOT_AVAILABLE,
|
||||
GAPI.BAD_REQUEST, GAPI.LOGIN_REQUIRED],
|
||||
retryReasons=GAPI.SERVICE_NOT_AVAILABLE_RETRY_REASONS,
|
||||
customerId=GC.Values[GC.CUSTOMER_ID], orgUnitPath=encodeOrgUnitPath(makeOrgUnitPathRelative(orgUnitPath)))
|
||||
entityActionPerformed([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], i, count)
|
||||
except GAPI.conditionNotMet:
|
||||
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], Msg.HAS_CHILD_ORGS.format(Ent.Plural(Ent.ORGANIZATIONAL_UNIT)), i, count)
|
||||
except (GAPI.invalidOrgunit, GAPI.orgunitNotFound, GAPI.backendError):
|
||||
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath], Msg.DOES_NOT_EXIST, i, count)
|
||||
except GAPI.invalidCustomerId as e:
|
||||
except (GAPI.invalidCustomerId, GAPI.serviceNotAvailable) as e:
|
||||
### Check for my_customer
|
||||
entityActionFailedWarning([Ent.ORGANIZATIONAL_UNIT, orgUnitPath, Ent.CUSTOMER_ID, GC.Values[GC.CUSTOMER_ID]], str(e), i, count)
|
||||
except (GAPI.badRequest, GAPI.loginRequired):
|
||||
@@ -20702,6 +20710,9 @@ class PeopleManager():
|
||||
}
|
||||
}
|
||||
|
||||
# Fields that allow an empty type
|
||||
EMPTY_TYPE_ALLOWED_FIELDS = {PEOPLE_ADDRESSES, PEOPLE_EMAIL_ADDRESSES, PEOPLE_PHONE_NUMBERS, PEOPLE_URLS}
|
||||
|
||||
# Fields with just a URL
|
||||
# URL_FIELDS = {
|
||||
# PEOPLE_COVER_PHOTOS,
|
||||
@@ -20745,14 +20756,14 @@ class PeopleManager():
|
||||
person[fieldName].append({})
|
||||
return person[fieldName][0]
|
||||
|
||||
def InitArrayFieldEntry(choices):
|
||||
def InitArrayFieldEntry(choices, typeMinLen=1):
|
||||
entry = {'metadata': {'primary': False}}
|
||||
if choices is not None:
|
||||
ftype = getChoice(choices, mapChoice=True, defaultChoice=None)
|
||||
if ftype:
|
||||
entry['type'] = ftype
|
||||
else:
|
||||
entry['type'] = getString(Cmd.OB_STRING)
|
||||
entry['type'] = getString(Cmd.OB_STRING, minLen=typeMinLen)
|
||||
return entry
|
||||
|
||||
def GetMultiFieldEntry(fieldName):
|
||||
@@ -20803,7 +20814,7 @@ class PeopleManager():
|
||||
if fieldName == PEOPLE_ADDRESSES:
|
||||
if CheckClearPersonField(fieldName):
|
||||
continue
|
||||
entry = InitArrayFieldEntry(PeopleManager.TYPE_VALUE_PNP_FIELDS[fieldName])
|
||||
entry = InitArrayFieldEntry(PeopleManager.TYPE_VALUE_PNP_FIELDS[fieldName], typeMinLen=0)
|
||||
while Cmd.ArgumentsRemaining():
|
||||
argument = getArgument()
|
||||
if argument in PeopleManager.ADDRESS_ARGUMENT_TO_FIELD_MAP:
|
||||
@@ -20884,7 +20895,8 @@ class PeopleManager():
|
||||
elif fieldName in PeopleManager.TYPE_VALUE_PNP_FIELDS:
|
||||
if CheckClearPersonField(fieldName):
|
||||
continue
|
||||
entry = InitArrayFieldEntry(PeopleManager.TYPE_VALUE_PNP_FIELDS[fieldName])
|
||||
entry = InitArrayFieldEntry(PeopleManager.TYPE_VALUE_PNP_FIELDS[fieldName],
|
||||
typeMinLen=0 if fieldName in PeopleManager.EMPTY_TYPE_ALLOWED_FIELDS else 1)
|
||||
if fieldName == PEOPLE_IM_CLIENTS:
|
||||
checkBlankField = None
|
||||
entry['protocol'] = getChoice(PeopleManager.IM_PROTOCOLS, mapChoice=True)
|
||||
@@ -25622,13 +25634,18 @@ CHAT_SPACE_TYPE_MAP = {
|
||||
'directmessage': 'DIRECT_MESSAGE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_PREDEFINED_PERMS_MAP = {
|
||||
'announcement': 'ANNOUNCEMENT_SPACE',
|
||||
'collaboration': 'COLLABORATION_SPACE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS = {
|
||||
'SPACE': {'min': 0, 'max': 20},
|
||||
'GROUP_CHAT': {'min': 2, 'max': 20},
|
||||
'DIRECT_MESSAGE': {'min': 1, 'max': 1},
|
||||
}
|
||||
# gam <UserTypeEntity> create chatspace
|
||||
# [type <ChatSpaceType>]
|
||||
# [type <ChatSpaceType>] [announcement|collaboration]
|
||||
# [restricted|(audience <String>)]
|
||||
# [externalusersallowed <Boolean>]
|
||||
# [members <UserTypeEntity>]
|
||||
@@ -25639,9 +25656,7 @@ CHAT_SPACE_MIN_MAX_MEMBERS = {
|
||||
# [formatjson|returnidonly]
|
||||
def createChatSpace(users):
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
body = {'space': {'spaceType': CHAT_SPACE_TYPE_MAP['space'], 'displayName': ''},
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'memberships': []}
|
||||
body = {'space': {'spaceType': CHAT_SPACE_TYPE_MAP['space'], 'displayName': ''}, 'requestId': str(uuid.uuid4())}
|
||||
members = []
|
||||
tbody = {}
|
||||
returnIdOnly = False
|
||||
@@ -25650,6 +25665,8 @@ def createChatSpace(users):
|
||||
myarg = getArgument()
|
||||
if getChatSpaceParameters(myarg, body['space'], CHAT_SPACE_TYPE_MAP, updateMask):
|
||||
pass
|
||||
elif myarg in CHAT_SPACE_PREDEFINED_PERMS_MAP:
|
||||
body['space']['predefinedPermissionSettings'] = CHAT_SPACE_PREDEFINED_PERMS_MAP[myarg]
|
||||
elif myarg == 'externalusersallowed':
|
||||
body['space']['externalUserAllowed'] = getBoolean()
|
||||
elif myarg == 'members':
|
||||
@@ -25670,17 +25687,21 @@ def createChatSpace(users):
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['min'],
|
||||
CHAT_SPACE_MIN_MAX_MEMBERS[spaceType]['max']))
|
||||
mtype = CHAT_MEMBER_TYPE_MAP['human']
|
||||
for member in members:
|
||||
name = normalizeEmailAddressOrUID(member)
|
||||
body['memberships'].append({'member': {'name': f'users/{name}', 'type': mtype}})
|
||||
if members:
|
||||
body['memberships'] = []
|
||||
for member in members:
|
||||
name = normalizeEmailAddressOrUID(member)
|
||||
body['memberships'].append({'member': {'name': f'users/{name}', 'type': mtype}})
|
||||
if spaceType == 'SPACE':
|
||||
if not body['space']['displayName']:
|
||||
missingArgumentExit('displayname')
|
||||
elif spaceType == 'GROUP_CHAT':
|
||||
body['space'].pop('displayName', None)
|
||||
body['space'].pop('predefinedPermissionSettings', None)
|
||||
else: # DIRECT_MESSAGE
|
||||
body['space'].pop('displayName', None)
|
||||
body['space'].pop('spaceDetails', None)
|
||||
body['space'].pop('predefinedPermissionSettings', None)
|
||||
body['space']['singleUserBotDm'] = False
|
||||
if tbody:
|
||||
trimChatMessageIfRequired(tbody)
|
||||
@@ -25729,12 +25750,34 @@ CHAT_UPDATE_SPACE_TYPE_MAP = {
|
||||
'space': 'SPACE',
|
||||
}
|
||||
|
||||
CHAT_SPACE_ROLE_PERMISSIONS_MAP = {
|
||||
'managers': 'managersAllowed',
|
||||
'members': 'membersAllowed',
|
||||
}
|
||||
|
||||
CHAT_UPDATE_SPACE_PERMISSIONS_MAP = {
|
||||
'managemembersandgroups': 'manageMembersAndGroups',
|
||||
'modifyspacedetails': 'modifySpaceDetails',
|
||||
'togglehistory': 'toggleHistory',
|
||||
'useatmentionall': 'useAtMentionAll',
|
||||
'manageapps': 'manageApps',
|
||||
'managewebhooks': 'manageWebhooks',
|
||||
'replymessages': 'replyMessages',
|
||||
}
|
||||
|
||||
# gam <UserTypeEntity> update chatspace <ChatSpace>
|
||||
# [restricted|(audience <String>)]|
|
||||
# ([displayname <String>]
|
||||
# [type space]
|
||||
# [description <String>] [guidelines|rules <String>]
|
||||
# [history <Boolean>])
|
||||
# managemembersandgroups managers|members
|
||||
# modifyspacedetails managers|members
|
||||
# togglehistory managers|members
|
||||
# useatmentionall managers|members
|
||||
# manageapps managers|members
|
||||
# managewebhooks managers|members
|
||||
# replymessages managers|members
|
||||
# [formatjson]
|
||||
def updateChatSpace(users):
|
||||
FJQC = FormatJSONQuoteChar()
|
||||
@@ -25748,6 +25791,14 @@ def updateChatSpace(users):
|
||||
name = getSpaceName(myarg)
|
||||
elif getChatSpaceParameters(myarg, body, CHAT_UPDATE_SPACE_TYPE_MAP, updateMask):
|
||||
pass
|
||||
elif myarg in CHAT_UPDATE_SPACE_PERMISSIONS_MAP:
|
||||
body.setdefault('permissionSettings', {})
|
||||
permissionSetting = CHAT_UPDATE_SPACE_PERMISSIONS_MAP[myarg]
|
||||
role = getChoice(CHAT_SPACE_ROLE_PERMISSIONS_MAP, mapChoice=True)
|
||||
body['permissionSettings'][permissionSetting] = {'managersAllowed': True}
|
||||
if role == 'membersAllowed':
|
||||
body['permissionSettings'][permissionSetting].update({'membersAllowed': True})
|
||||
updateMask.add(f'permissionSettings.{permissionSetting}')
|
||||
else:
|
||||
FJQC.GetFormatJSON(myarg)
|
||||
if not name:
|
||||
@@ -25815,6 +25866,7 @@ CHAT_SPACES_FIELDS_CHOICE_MAP = {
|
||||
"lastactivetime": "lastActiveTime",
|
||||
"membershipcount": "membershipCount",
|
||||
"name": "name",
|
||||
"permissionsettings": "permissionSettings",
|
||||
"singleuserbotdm": "singleUserBotDm",
|
||||
"spacedetails": "spaceDetails",
|
||||
"spacehistorystate": "spaceHistoryState",
|
||||
@@ -37335,6 +37387,7 @@ def doCalendarsPrintShowACLs(calIds):
|
||||
if csvPF:
|
||||
csvPF.writeCSVfile('Calendar ACLs')
|
||||
|
||||
EVENT_TYPE_BIRTHDAY = 'birthday'
|
||||
EVENT_TYPE_DEFAULT = 'default'
|
||||
EVENT_TYPE_FOCUSTIME = 'focusTime'
|
||||
EVENT_TYPE_FROMGMAIL = 'fromGmail'
|
||||
@@ -37342,6 +37395,7 @@ EVENT_TYPE_OUTOFOFFICE = 'outOfOffice'
|
||||
EVENT_TYPE_WORKINGLOCATION = 'workingLocation'
|
||||
|
||||
EVENT_TYPES_CHOICE_MAP = {
|
||||
'birthday': EVENT_TYPE_BIRTHDAY,
|
||||
'default': EVENT_TYPE_DEFAULT,
|
||||
'focustime': EVENT_TYPE_FOCUSTIME,
|
||||
'fromgmail': EVENT_TYPE_FROMGMAIL,
|
||||
@@ -37349,20 +37403,6 @@ EVENT_TYPES_CHOICE_MAP = {
|
||||
'workinglocation': EVENT_TYPE_WORKINGLOCATION,
|
||||
}
|
||||
|
||||
#EVENT_TYPE_DEFAULT_PROPERTIES_MAP = {
|
||||
# EVENT_TYPE_DEFAULT: {'eventType': EVENT_TYPE_DEFAULT},
|
||||
# EVENT_TYPE_FOCUSTIME: {'eventType': EVENT_TYPE_FOCUSTIME,
|
||||
# 'focusTimeProperties': {'autoDeclineMode': 'declineNone', 'declineMessage': 'Declined', 'chatStatus': 'doNotDisturb'},
|
||||
# 'transparency':'opaque'},
|
||||
# EVENT_TYPE_FROMGMAIL: {'eventType': EVENT_TYPE_FROMGMAIL},
|
||||
# EVENT_TYPE_OUTOFOFFICE: {'eventType': EVENT_TYPE_OUTOFOFFICE,
|
||||
# 'outOfOfficeProperties': {'autoDeclineMode': 'declineOnlyNewConflictingInvitations', 'declineMessage': 'Declined'},
|
||||
# 'transparency':'opaque'},
|
||||
# EVENT_TYPE_WORKINGLOCATION: {'eventType': EVENT_TYPE_WORKINGLOCATION,
|
||||
# 'workingLocationProperties': {},
|
||||
# 'visibility': 'public', 'transparency':'transparent'},
|
||||
# }
|
||||
|
||||
EVENT_TYPE_PROPERTIES_NAME_MAP = {
|
||||
EVENT_TYPE_DEFAULT: None,
|
||||
EVENT_TYPE_FOCUSTIME: f'{EVENT_TYPE_FOCUSTIME}Properties',
|
||||
@@ -37372,6 +37412,7 @@ EVENT_TYPE_PROPERTIES_NAME_MAP = {
|
||||
}
|
||||
|
||||
EVENT_TYPE_ENTITY_MAP = {
|
||||
EVENT_TYPE_BIRTHDAY: Ent.EVENT_BIRTHDAY,
|
||||
EVENT_TYPE_DEFAULT: None,
|
||||
EVENT_TYPE_FOCUSTIME: Ent.EVENT_FOCUSTIME,
|
||||
EVENT_TYPE_FROMGMAIL: None,
|
||||
@@ -37605,6 +37646,16 @@ def _getCalendarEventAttribute(myarg, body, parameters, function):
|
||||
elif myarg == 'timerange':
|
||||
body['start'] = {'dateTime': getTimeOrDeltaFromNow()}
|
||||
body['end'] = {'dateTime': getTimeOrDeltaFromNow()}
|
||||
elif myarg == 'birthday':
|
||||
body['eventType'] = EVENT_TYPE_BIRTHDAY
|
||||
body['visibility'] = 'private'
|
||||
body['transparency'] = 'transparent'
|
||||
bday = getYYYYMMDD(returnDateTime=True)
|
||||
body['start'] = body['end'] = {'date': bday.strftime(YYYYMMDD_FORMAT)}
|
||||
if bday.month != 2 or bday.day != 29:
|
||||
body['recurrence'] = ['RRULE:FREQ=YEARLY']
|
||||
else:
|
||||
body['recurrence'] = ['RRULE:FREQ=YEARLY;BYMONTH=2;BYMONTHDAY=-1']
|
||||
elif myarg == 'attachment':
|
||||
body.setdefault('attachments', [])
|
||||
body['attachments'].append({'title': getString(Cmd.OB_STRING), 'fileUrl': getString(Cmd.OB_URL)})
|
||||
@@ -38015,12 +38066,14 @@ def _createCalendarEvents(user, origCal, function, calIds, count, body, paramete
|
||||
if function == 'insert':
|
||||
event = callGAPI(cal.events(), 'insert',
|
||||
throwReasons=GAPI.CALENDAR_THROW_REASONS+[GAPI.INVALID, GAPI.REQUIRED, GAPI.TIME_RANGE_EMPTY, GAPI.EVENT_DURATION_EXCEEDS_LIMIT,
|
||||
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.DUPLICATE, GAPI.FORBIDDEN, GAPI.MALFORMED_WORKING_LOCATION_EVENT],
|
||||
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.DUPLICATE, GAPI.FORBIDDEN,
|
||||
GAPI.MALFORMED_WORKING_LOCATION_EVENT, GAPI.BAD_REQUEST],
|
||||
calendarId=calId, conferenceDataVersion=1, sendUpdates=parameters['sendUpdates'], supportsAttachments=True, body=body, fields=fields)
|
||||
else:
|
||||
event = callGAPI(cal.events(), 'import_',
|
||||
throwReasons=GAPI.CALENDAR_THROW_REASONS+[GAPI.INVALID, GAPI.REQUIRED, GAPI.TIME_RANGE_EMPTY, GAPI.EVENT_DURATION_EXCEEDS_LIMIT,
|
||||
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.DUPLICATE, GAPI.FORBIDDEN, GAPI.MALFORMED_WORKING_LOCATION_EVENT,
|
||||
GAPI.REQUIRED_ACCESS_LEVEL, GAPI.DUPLICATE, GAPI.FORBIDDEN,
|
||||
GAPI.MALFORMED_WORKING_LOCATION_EVENT, GAPI.BAD_REQUEST,
|
||||
GAPI.PARTICIPANT_IS_NEITHER_ORGANIZER_NOR_ATTENDEE],
|
||||
calendarId=calId, conferenceDataVersion=1, supportsAttachments=True, body=body, fields=fields)
|
||||
if parameters['csvPF'] is None:
|
||||
@@ -38030,7 +38083,8 @@ def _createCalendarEvents(user, origCal, function, calIds, count, body, paramete
|
||||
_getEventDaysOfWeek(event)
|
||||
_printCalendarEvent(user, calId, event, parameters['csvPF'], parameters['FJQC'])
|
||||
except (GAPI.invalid, GAPI.required, GAPI.timeRangeEmpty, GAPI.eventDurationExceedsLimit,
|
||||
GAPI.requiredAccessLevel, GAPI.participantIsNeitherOrganizerNorAttendee, GAPI.malformedWorkingLocationEvent) as e:
|
||||
GAPI.requiredAccessLevel, GAPI.participantIsNeitherOrganizerNorAttendee,
|
||||
GAPI.malformedWorkingLocationEvent, GAPI.badRequest) as e:
|
||||
entityActionFailedWarning([Ent.CALENDAR, calId, Ent.EVENT, event['id']], str(e), i, count)
|
||||
except GAPI.duplicate as e:
|
||||
entityActionFailedWarning([Ent.CALENDAR, calId, Ent.EVENT, event['id']], str(e), i, count)
|
||||
@@ -51080,7 +51134,7 @@ def createStatusEvent(users, eventType):
|
||||
missingArgumentExit('|'.join(WORKING_LOCATION_CHOICE_MAP))
|
||||
elif eventType == EVENT_TYPE_OUTOFOFFICE:
|
||||
getOutOfOfficeProperties(body, parameters, dateList)
|
||||
else: # eventType == EVENT_TYPE_FOCUSTIME
|
||||
else: # elif eventType == EVENT_TYPE_FOCUSTIME:
|
||||
getFocusTimeProperties(body, parameters, dateList)
|
||||
if not dateList:
|
||||
missingChoiceExit(STATUS_EVENTS_DATETIME_CHOICES)
|
||||
@@ -65686,6 +65740,7 @@ def deleteUserFromGroups(users):
|
||||
matchPattern = {}
|
||||
kwargs = _getUserGroupOptionalDomainCustomerId()
|
||||
if not kwargs:
|
||||
kwargs = {'customer': GC.Values[GC.CUSTOMER_ID]}
|
||||
deleteGroups = {}
|
||||
if Cmd.ArgumentsRemaining():
|
||||
if not checkArgumentPresent('emailmatchpattern'):
|
||||
@@ -65760,6 +65815,7 @@ def updateUserGroups(users):
|
||||
baseRole = getChoice(GROUP_ROLES_MAP, defaultChoice=Ent.ROLE_MEMBER, mapChoice=True)
|
||||
baseDeliverySettings = getDeliverySettings()
|
||||
if not kwargs:
|
||||
kwargs = {'customer': GC.Values[GC.CUSTOMER_ID]}
|
||||
if Cmd.ArgumentsRemaining():
|
||||
groupKeys = getEntityList(Cmd.OB_GROUP_ENTITY)
|
||||
subkeyRoleField = GM.Globals[GM.CSV_SUBKEY_FIELD]
|
||||
@@ -65820,6 +65876,8 @@ def updateUserGroups(users):
|
||||
def syncUserWithGroups(users):
|
||||
cd = buildGAPIObject(API.DIRECTORY)
|
||||
kwargs = _getUserGroupOptionalDomainCustomerId()
|
||||
if not kwargs:
|
||||
kwargs = {'customer': GC.Values[GC.CUSTOMER_ID]}
|
||||
baseRole = getChoice(GROUP_ROLES_MAP, defaultChoice=Ent.ROLE_MEMBER, mapChoice=True)
|
||||
baseDeliverySettings = getDeliverySettings()
|
||||
groupKeys = getEntityList(Cmd.OB_GROUP_ENTITY)
|
||||
@@ -71912,14 +71970,16 @@ def _processSendAs(user, i, count, entityType, emailAddress, j, jcount, gmail, f
|
||||
result = callGAPI(gmail.users().settings().sendAs(), function,
|
||||
throwReasons=GAPI.GMAIL_THROW_REASONS+[GAPI.NOT_FOUND, GAPI.ALREADY_EXISTS, GAPI.DUPLICATE,
|
||||
GAPI.CANNOT_DELETE_PRIMARY_SENDAS, GAPI.INVALID_ARGUMENT,
|
||||
GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED],
|
||||
GAPI.FAILED_PRECONDITION, GAPI.PERMISSION_DENIED,
|
||||
GAPI.INSUFFICIENT_PERMISSIONS],
|
||||
userId='me', **kwargs)
|
||||
if function == 'get':
|
||||
_showSendAs(result, j, jcount, sigReplyFormat, verifyOnly)
|
||||
else:
|
||||
entityActionPerformed([Ent.USER, user, entityType, emailAddress], j, jcount)
|
||||
except (GAPI.notFound, GAPI.alreadyExists, GAPI.duplicate,
|
||||
GAPI.cannotDeletePrimarySendAs, GAPI.invalidArgument, GAPI.failedPrecondition, GAPI.permissionDenied) as e:
|
||||
GAPI.cannotDeletePrimarySendAs, GAPI.invalidArgument,
|
||||
GAPI.failedPrecondition, GAPI.permissionDenied, GAPI.insufficientPermissions) as e:
|
||||
entityActionFailedWarning([Ent.USER, user, entityType, emailAddress], str(e), j, jcount)
|
||||
except (GAPI.serviceNotAvailable, GAPI.badRequest):
|
||||
entityServiceNotApplicableWarning(Ent.USER, user, i, count)
|
||||
|
||||
4880
src/gam/chat-v1.json
4880
src/gam/chat-v1.json
File diff suppressed because it is too large
Load Diff
@@ -206,15 +206,15 @@ _INFO = {
|
||||
ANALYTICS_ADMIN: {'name': 'Analytics Admin API', 'version': 'v1beta', 'v2discovery': True},
|
||||
CALENDAR: {'name': 'Calendar API', 'version': 'v3', 'v2discovery': True, 'mappedAPI': 'calendar-json'},
|
||||
CBCM: {'name': 'Chrome Browser Cloud Management API', 'version': 'v1.1beta1', 'v2discovery': True, 'localjson': True},
|
||||
CHAT: {'name': 'Chat API', 'version': 'v1', 'v2discovery': True, 'localjson': True},
|
||||
CHAT_EVENTS: {'name': 'Chat API - Events', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_MEMBERSHIPS: {'name': 'Chat API - Memberships', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_MEMBERSHIPS_ADMIN: {'name': 'Chat API - Memberships Admin', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_MESSAGES: {'name': 'Chat API - Messages', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES: {'name': 'Chat API - Spaces', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_ADMIN: {'name': 'Chat API - Spaces Admin', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_DELETE: {'name': 'Chat API - Spaces Delete', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_DELETE_ADMIN: {'name': 'Chat API - Spaces Delete Admin', 'version': 'v1', 'v2discovery': True, 'localjson': True, 'mappedAPI': CHAT},
|
||||
CHAT: {'name': 'Chat API', 'version': 'v1', 'v2discovery': True},
|
||||
CHAT_EVENTS: {'name': 'Chat API - Events', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_MEMBERSHIPS: {'name': 'Chat API - Memberships', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_MEMBERSHIPS_ADMIN: {'name': 'Chat API - Memberships Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_MESSAGES: {'name': 'Chat API - Messages', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES: {'name': 'Chat API - Spaces', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_ADMIN: {'name': 'Chat API - Spaces Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_DELETE: {'name': 'Chat API - Spaces Delete', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CHAT_SPACES_DELETE_ADMIN: {'name': 'Chat API - Spaces Delete Admin', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHAT},
|
||||
CLASSROOM: {'name': 'Classroom API', 'version': 'v1', 'v2discovery': True},
|
||||
CHROMEMANAGEMENT: {'name': 'Chrome Management API', 'version': 'v1', 'v2discovery': True},
|
||||
CHROMEMANAGEMENT_APPDETAILS: {'name': 'Chrome Management API - AppDetails', 'version': 'v1', 'v2discovery': True, 'mappedAPI': CHROMEMANAGEMENT},
|
||||
|
||||
@@ -215,6 +215,7 @@ class GamEntity():
|
||||
END_TIME = 'endt'
|
||||
ENTITY = 'enti'
|
||||
EVENT = 'evnt'
|
||||
EVENT_BIRTHDAY = 'evbd'
|
||||
EVENT_FOCUSTIME = 'evft'
|
||||
EVENT_OUTOFOFFICE = 'evoo'
|
||||
EVENT_WORKINGLOCATION = 'evwl'
|
||||
@@ -565,6 +566,7 @@ class GamEntity():
|
||||
END_TIME: ['End Times', 'End Time'],
|
||||
ENTITY: ['Entities', 'Entity'],
|
||||
EVENT: ['Events', 'Event'],
|
||||
EVENT_BIRTHDAY: ['Borthday Events', 'Birthday Event'],
|
||||
EVENT_FOCUSTIME: ['Focus Time Events', 'Focus Time Event'],
|
||||
EVENT_OUTOFOFFICE: ['Out of Office Events', 'Out of Office Event'],
|
||||
EVENT_WORKINGLOCATION: ['Working Location Events', 'Working Location Event'],
|
||||
|
||||
@@ -1170,9 +1170,11 @@ def createMethod(methodName, methodDesc, rootDesc, schema):
|
||||
elif "response" not in methodDesc:
|
||||
model = RawModel()
|
||||
|
||||
api_version = methodDesc.get("apiVersion", None)
|
||||
|
||||
headers = {}
|
||||
headers, params, query, body = model.request(
|
||||
headers, actual_path_params, actual_query_params, body_value
|
||||
headers, actual_path_params, actual_query_params, body_value, api_version
|
||||
)
|
||||
|
||||
expanded_url = uritemplate.expand(pathUrl, params)
|
||||
|
||||
@@ -27,10 +27,18 @@ import json
|
||||
import logging
|
||||
import platform
|
||||
import urllib
|
||||
import warnings
|
||||
|
||||
from googleapiclient import version as googleapiclient_version
|
||||
from googleapiclient.errors import HttpError
|
||||
|
||||
try:
|
||||
from google.api_core.version_header import API_VERSION_METADATA_KEY
|
||||
|
||||
HAS_API_VERSION = True
|
||||
except ImportError:
|
||||
HAS_API_VERSION = False
|
||||
|
||||
_LIBRARY_VERSION = googleapiclient_version.__version__
|
||||
_PY_VERSION = platform.python_version()
|
||||
|
||||
@@ -121,7 +129,7 @@ class BaseModel(Model):
|
||||
LOGGER.info("query: %s", query)
|
||||
LOGGER.info("--request-end--")
|
||||
|
||||
def request(self, headers, path_params, query_params, body_value):
|
||||
def request(self, headers, path_params, query_params, body_value, api_version=None):
|
||||
"""Updates outgoing requests with a serialized body.
|
||||
|
||||
Args:
|
||||
@@ -129,7 +137,10 @@ class BaseModel(Model):
|
||||
path_params: dict, parameters that appear in the request path
|
||||
query_params: dict, parameters that appear in the query
|
||||
body_value: object, the request body as a Python object, which must be
|
||||
serializable by json.
|
||||
serializable by json.
|
||||
api_version: str, The precise API version represented by this request,
|
||||
which will result in an API Version header being sent along with the
|
||||
HTTP request.
|
||||
Returns:
|
||||
A tuple of (headers, path_params, query, body)
|
||||
|
||||
@@ -155,6 +166,15 @@ class BaseModel(Model):
|
||||
_PY_VERSION,
|
||||
)
|
||||
|
||||
if api_version and HAS_API_VERSION:
|
||||
headers[API_VERSION_METADATA_KEY] = api_version
|
||||
elif api_version:
|
||||
warnings.warn(
|
||||
"The `api_version` argument is ignored as a newer version of "
|
||||
"`google-api-core` is required to use this feature."
|
||||
"Please upgrade `google-api-core` to 2.19.0 or newer."
|
||||
)
|
||||
|
||||
if body_value is not None:
|
||||
headers["content-type"] = self.content_type
|
||||
body_value = self.serialize(body_value)
|
||||
|
||||
@@ -12,4 +12,4 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
__version__ = "2.124.0"
|
||||
__version__ = "2.146.0"
|
||||
|
||||
@@ -13,10 +13,10 @@ keywords = google, oauth2, gsuite, google-apps, google-admin-sdk, google-drive,
|
||||
classifiers =
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: 3.12
|
||||
License :: OSI Approved :: Apache License
|
||||
|
||||
[options]
|
||||
|
||||
58
src/tools/gen-wix-xml-filelist.py
Normal file
58
src/tools/gen-wix-xml-filelist.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import os
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
source_dir = sys.argv[1]
|
||||
template_file = sys.argv[2]
|
||||
target_file = sys.argv[3]
|
||||
|
||||
existing_components = {
|
||||
'gam.exe': ''' <Component Id="gam_exe" Guid="d046ea24-c9f8-40ca-84db-70b0119933ff">
|
||||
<File Name="gam.exe" KeyPath="yes" />
|
||||
<Environment Id="PATH" Name="PATH" Value="[INSTALLFOLDER]" Permanent="yes" Part="last" Action="set" System="yes" />
|
||||
</Component>
|
||||
''',
|
||||
'LICENSE': ''' <Component Id="license" Guid="c76864c5-d005-44d5-bb7c-a27e5923792d">
|
||||
<File Name="LICENSE" KeyPath="yes" />
|
||||
</Component>
|
||||
''',
|
||||
'gam-setup.bat': ''' <Component Id="gam_setup_bat" Guid="5e6bbacb-d86f-4d80-a10b-89b81ee63fcb">
|
||||
<File Name="gam-setup.bat" KeyPath="yes" />
|
||||
</Component>
|
||||
''',
|
||||
'GamCommands.txt': ''' <Component Id="GamCommands_txt" Guid="a2dca862-b222-469e-a637-95ea2a1c53e7">
|
||||
<File Name="GamCommands.txt" KeyPath="yes" />
|
||||
</Component>
|
||||
''',
|
||||
'GamUpdate.txt': ''' <Component Id="GamUpdate_txt" Guid="1b7cdd48-0fff-4943-a219-102fcd14c755">
|
||||
<File Name="GamUpdate.txt" KeyPath="yes" />
|
||||
</Component>
|
||||
''',
|
||||
'cacerts.pem': ''' <Component Id="cacerts_pem" Guid="61fe2b2d-1646-4bed-b844-193965e97727">
|
||||
<File Name="cacerts.pem" KeyPath="yes" />
|
||||
</Component>
|
||||
''',
|
||||
}
|
||||
|
||||
component_xml = ''
|
||||
all_files = []
|
||||
for root, dirs, files in os.walk(source_dir):
|
||||
for filename in files:
|
||||
relpath = os.path.relpath(root, source_dir)
|
||||
if relpath == '.':
|
||||
all_files.append(filename)
|
||||
else:
|
||||
all_files.append(os.path.join(relpath, filename))
|
||||
all_files.sort()
|
||||
for filename in all_files:
|
||||
component_xml += existing_components.get(filename,
|
||||
f' <Component>\n <File Name="{filename}" KeyPath="yes"/>\n </Component>\n')
|
||||
|
||||
with open(template_file, 'r') as f:
|
||||
template = f.read()
|
||||
|
||||
full_xml = template.replace('REPLACE_ME_WITH_FILE_COMPONENTS', component_xml)
|
||||
|
||||
with open(target_file, 'w') as f:
|
||||
f.write(full_xml)
|
||||
|
||||
Reference in New Issue
Block a user