Skip to content

Instantly share code, notes, and snippets.

@denoww
Last active March 30, 2025 08:12
Show Gist options
  • Save denoww/983566e9653cbef4b5e40ffce029582b to your computer and use it in GitHub Desktop.
Save denoww/983566e9653cbef4b5e40ffce029582b to your computer and use it in GitHub Desktop.
# Instalação
# curl -s https://gist.githubusercontent.com/denoww/983566e9653cbef4b5e40ffce029582b/raw | bash -s install_lib
# ou
# wget -O - https://gist.githubusercontent.com/denoww/983566e9653cbef4b5e40ffce029582b/raw | bash -s install_lib
# $ scflutter
# IOS Manuais api
# https://developer.apple.com/documentation/appstoreconnectapi
# ANDROID Manuais api
# Google Cloud Console
# https://console.cloud.google.com/welcome?hl=pt-br&project=api-8415245765938766450-242028
# https://console.cloud.google.com/apis/credentials/oauthclient/444910204686-1qn6tatuk83hrnbpca0nftvg4vidrao2.apps.googleusercontent.com?hl=pt-br&project=api-8415245765938766450-242028
# https://console.cloud.google.com/apis/credentials/consent?hl=pt-br&project=api-8415245765938766450-242028
# API rest
# https://developers.google.com/android-publisher/api-ref/rest?hl=pt-br
# Auth documentação
# https://developers.google.com/android-publisher/authorization?hl=pt-br
# Atualizar essa lib em
# https://gist.github.com/denoww/983566e9653cbef4b5e40ffce029582b/edit
# versionCode='3088'
# access_token=ya29.a0AfB_byDbv52TE4z6Ulhe8nkC4NpjxdBXt6j_HE7UBO90lyJoeVuKT4i7BBdM7Mwdm2dz1DxQnoyIy1xGX0gyQt8tnFyq2MB9dzg42VID-eJ2CZYqVucBbnaVc9iZobeF_2kR-jmfdS9HidM9YFqOP-zb1fjBR_LftgmDaCgYKARASARESFQHGX2Mikuj75lHT9oNvMlk5fW8uLg0171
# veja os comandos com
# $ scflutter
flutterFolder="$HOME/workspace/erp_flutter"
iosApiHost="https://api.appstoreconnect.apple.com/v1"
jsonHeader='Content-Type: application/json'
if [[ "$OSTYPE" == "darwin"* ]]; then
# estou no macos
deploy_folder=$flutterFolder/sc_deploy/ios
else
# estou no linux
deploy_folder=$flutterFolder/sc_deploy/android
fi
function androidDeploy() {
flavor=$1
androidConfigDeploy $flavor
build android $flavor
androidUploadBundle
androidUpdateTracks
androidCommitEditId
}
#####################################################################
#####################################################################
# IOS - ini
#####################################################################
function iosDeploy(){
flavor=$1
ios_configurar_flavor
iosAvisosDeploy
#############################################
# ios_testar_token_jwt
################################
# iosBuild
build "ios" $flavor
iosUpload
ios_apple_store_arrumar_versao
# ios_apple_store_enviar_para_revisao
#############################################
}
function ios_apple_store_enviar_para_revisao(){
JSON_DATA='{
“type”: "reviewSubmissions",
"attributes": {
"platform": "IOS",
},
"relationships": {
"app": {
"data": {
"type": "apps",
"id": "'"$ios_app_id"'"
}
}
}
}'
url="/reviewSubmissions"
echo "---------------------------------------------------------"
echo "$flavor: ios_apple_store_enviar_para_revisao "
echo "Post" "$url"
echo $JSON_DATA
echo "---------------------------------------------------------"
createSubmission=$(ios_request "POST" "$url" "$JSON_DATA")
echo $createSubmission
}
function iosBuild(){
flavor=$1
echo "$flavor: criando build..."
cd $flutterFolder;
flutter build ipa --release --flavor $flavor --dart-define=flavorApp=$flavor
}
function iosUpload(){
echo "-------------------------------------------------------"
echo "$flavor: Enviando $IOS_IPA_PATH para apple connect..."
echo "-------------------------------------------------------"
xcrun altool --upload-app --type ios -f $IOS_IPA_PATH --apiKey $IOS_KEY_ID --apiIssuer $IOS_ISSUER_ID
}
function iosAvisosDeploy(){
echo "-------------------------------------------------------------------------"
echo "Caso não tenha feito os passos abaixo, então faça:"
echo "Garante que tenha criado a chave aqui https://appstoreconnect.apple.com/access/api"
echo "Procure nesse script aqui por IOS_KEY_ID e coloque o valor da chave criada"
echo "Baixe o arquivo p8"
echo "AuthKey_$IOS_KEY_ID.p8 precisa estar na pasta $HOME/private_keys"
echo "-------------------------------------------------------------------------"
}
function ios_arrumar_encriptacao_do_build(){
JSON_DATA='{
“type”: “builds”,
“id”: "'"$iosBuildId"'",
“attributes”: {
“usesNonExemptEncryption” : true
},
“relationships”: {
“appEncryptionDeclaration”: {
“data”: {
“type”: “appEncryptionDeclarations”,
“id”: “51f19f70-ccd2-4ab9-986b-d7c38ee3e60c”
}
}
}
}'
url="/builds/$iosBuildId"
echo "---------------------------------------------------------"
echo "$flavor: ios_arrumar_encriptacao_do_build "
echo "PATCH" "$url"
echo $JSON_DATA
echo "---------------------------------------------------------"
resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
echo $resp
}
function ios_get_ultimo_build_id(){
echo "---------------------------------------------------------"
echo "$flavor: ios_get_ultimo_build_id "
echo "---------------------------------------------------------"
url="/builds?filter\[app\]=$ios_app_id&filter\[version\]=$versaoNumero&sort=-uploadedDate&limit=1"
echo GET $url
resp=$(ios_request "GET" "$url")
iosBuildId=$(echo "$resp" | jq -r '.data[0].id')
}
function ios_arrumar_ultimo_build(){
ios_get_ultimo_build_id
# ios_arrumar_encriptacao_do_build
}
function ios_configurar_flavor(){
ios_jwt_token=$(ios_gerar_jwt_token)
iosHeaderToken="Authorization: Bearer $ios_jwt_token"
ios_app_id=$(ios_get_app_id_from_bundle_id $flavor)
ios_bundle_id=$(ios_get_bundle_id $flavor)
ios_app_info_id=$(ios_get_app_info $ios_app_id)
ios_app_store_version_id=$(ios_get_app_store_version_id $ios_app_id)
IOS_IPA_PATH=$flutterFolder/build/ios/ipa/erp_flutter.ipa
IOS_KEY_ID=RVGAWC6A47
IOS_ISSUER_ID="69a6de90-5841-47e3-e053-5b8c7c11a4d1"
if [ -z "$ios_app_id" ]; then
echo "-------------------------------------------------------------------"
echo "-------------------------------------------------------------------"
echo "$flavor: não encontradado ios_app_id - esse flavor existe???"
echo "-------------------------------------------------------------------"
exit 1
fi
encontrarVersaoErpFlutter
}
function ios_get_app_store_version_id(){
$ios_app_id=$1
# echo "---------------------------------------------------------"
# echo "$flavor: Buscando versão pendente"
# echo "---------------------------------------------------------"
appStoreState="DEVELOPER_REJECTED,IN_REVIEW,INVALID_BINARY,METADATA_REJECTED,PENDING_APPLE_RELEASE,PENDING_DEVELOPER_RELEASE,PREPARE_FOR_SUBMISSION,PREORDER_READY_FOR_SALE,PROCESSING_FOR_APP_STORE,READY_FOR_REVIEW,REJECTED,REMOVED_FROM_SALE,WAITING_FOR_EXPORT_COMPLIANCE,WAITING_FOR_REVIEW"
url="/apps/$ios_app_id/appStoreVersions?filter%5BappStoreState%5D=$appStoreState&limit=1"
versoes=$(ios_request "GET" "$url")
ios_app_store_version_id=$(echo "$versoes" | jq -r '.data[0].id')
echo $ios_app_store_version_id
}
# function ios_listar_versoes(){
# API_URL="$iosApiHost/$ios_app_id/appStoreVersions"
# response=$(ios_request "GET" "$API_URL")
# echo $response
# }
function ios_app_store_update_versao(){
echo "---------------------------------------------------------"
echo "$flavor: atualizando versão existente para $versaoString no loja do app "
echo "---------------------------------------------------------"
versaoId=$1
versaoString=$2
JSON_DATA='{
"data": {
"id": "'"$versaoId"'",
"type": "appStoreVersions",
"attributes": {
"versionString": "'"$versaoString"'"
}
}
}'
updateVersao=$(ios_request "PATCH" "/appStoreVersions/${versaoId}" "$JSON_DATA")
echo $updateVersao
}
function encontrarVersaoErpFlutter(){
pubspec_content=$(cat "$flutterFolder/pubspec.yaml")
# Use awk para extrair a versão e o número da versão
versaoString=$(echo "$pubspec_content" | awk -F ': ' '/^version:/ { print $2 }' | awk -F '+' '{ print $1 }')
versaoNumero=$(echo "$pubspec_content" | awk -F ': ' '/^version:/ { print $2 }' | awk -F '+' '{ print $2 }')
echo "versaoString: $versaoString"
echo "versaoNumero: $versaoNumero"
}
function ios_apple_store_arrumar_versao(){
ios_arrumar_ultimo_build
appStoreState="DEVELOPER_REJECTED,IN_REVIEW,INVALID_BINARY,METADATA_REJECTED,PENDING_APPLE_RELEASE,PENDING_DEVELOPER_RELEASE,PREPARE_FOR_SUBMISSION,PREORDER_READY_FOR_SALE,PROCESSING_FOR_APP_STORE,READY_FOR_REVIEW,REJECTED,REMOVED_FROM_SALE,WAITING_FOR_EXPORT_COMPLIANCE,WAITING_FOR_REVIEW"
appStoreVersions="versionString,appStoreState"
url="/apps/$ios_app_id/appStoreVersions?filter\[appStoreState\]=$appStoreState&fields\[appStoreVersions\]=$appStoreVersions"
versoes_pendentes=$(ios_request "GET" "$url")
length=$(echo "$versoes_pendentes" | jq '.data | length')
# textoNovidade="Nova versão $versaoString"
if [ "$length" -ge 1 ]; then
for ((i = 0; i < length; i++)); do
versaoId=$(echo "$versoes_pendentes" | jq -r ".data[$i].id")
ios_app_store_update_versao $versaoId $versaoString
# ios_app_store_ligar_compilacao_na_versao $versaoId
done
else
# "Não há versões pendentes."
resp=$(ios_apple_store_criar_versao $versaoStringm)
versaoId=$(echo "$resp" | jq -r '.data.id')
# ios_app_store_ligar_compilacao_na_versao $versaoId
# Coloque o código que deseja executar se não houver versões pendentes aqui
fi
}
# function ios_app_store_ligar_compilacao_na_versao(){
# versaoId=$1
# JSON_DATA='{
# "data": {
# "type": "builds",
# "id": "'"$iosBuildId"'"
# }
# }'
# url="/appStoreVersions/${versaoId}/relationships/build"
# echo "---------------------------------------------------------"
# echo "$flavor: ios_app_store_ligar_compilacao_na_versao"
# echo "PATCH" "$url"
# echo $JSON_DATA
# echo "---------------------------------------------------------"
# resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
# echo $resp
# # response=$(curl -X PATCH "/appStoreVersions/$APP_STORE_VERSION_ID/relationships/build" \
# # -d '{
# # "data": {
# # "type": "builds",
# # "id": "'"$versaoNumero"'"
# # }
# # }')
# }
function ios_apple_store_criar_versao(){
versaoString=$1
echo "---------------------------------------------------------"
echo "$flavor: criando versão $versaoString no loja do app "
echo "---------------------------------------------------------"
# URL da API
# JSON de dados da solicitação
JSON_DATA="{\"data\": {
\"type\": \"appStoreVersions\",
\"attributes\": {
\"platform\": \"IOS\",
\"versionString\": \"$versaoString\",
\"copyright\": \"© Erp.\",
\"releaseType\": \"AFTER_APPROVAL\",
\"usesIdfa\": false
},
\"relationships\": {
\"app\": {
\"data\": {
\"type\": \"apps\",
\"id\": \"$ios_app_id\"
}
}
}
}}"
response=$(ios_request "POST" "/appStoreVersions" "$JSON_DATA")
echo $response
}
function ios_request(){
ios_method=$1
ios_API_URL=$2
ios_JSON_DATA=$3
# echo "$method $API_URL $JSON_DATA"
response=$(curl -X $ios_method -H "$iosHeaderToken" -H "$jsonHeader" -d "$ios_JSON_DATA" "${iosApiHost}${ios_API_URL}")
echo $response
}
function ios_get_bundle_id(){
PLIST_FILE="$flutterFolder/ios/flavors/$flavor/GoogleService-Info.plist"
BUNDLE_ID=$(grep -A1 '<key>BUNDLE_ID</key>' "$PLIST_FILE" | grep '<string>' | awk -F'<string>' '{print $2}' | awk -F'</string>' '{print $1}' | tr -d '[:space:]')
echo $BUNDLE_ID
}
# function ios_get_app_id_from_bundle_id(){
# bundle_id=$(ios_get_bundle_id $flavor)
# APP_INFO=$(curl -s "https://itunes.apple.com/lookup?bundleId=$bundle_id")
# APP_ID_LINE=$(echo "$APP_INFO" | grep -o '"trackId":[0-9]*')
# APP_ID=$(echo "$APP_ID_LINE" | grep -o '[0-9]*')
# echo $APP_ID
# }
function ios_get_app_id_from_bundle_id(){
bundle_id=$(ios_get_bundle_id $flavor)
url="/apps?filter%5BbundleId%5D=$bundle_id"
resp=$(ios_request "GET" "$url")
app_id=$(echo "$resp" | jq -r '.data[0].id')
echo $app_id
}
function ios_testar_token_jwt(){
ios_jwt_token=$(ios_gerar_jwt_token)
# url="$iosApiHost/apps"
url=$iosApiHost/bundleIds
curl -s -X GET -H "$iosHeaderToken" "$url"
}
function ios_gerar_jwt_token(){
# echo "Gerando ios_jwt_token JWT da apple connect..."
ios_jwt_token=$(ruby "$deploy_folder/JWT_GENERATOR.rb")
echo $ios_jwt_token
}
#####################################################################
# IOS - fim
#####################################################################
#####################################################################
# varAndroidFlavors=$(awk '/scFlutteLibFlavorIni/,/scFlutteLibFlavorFim/' $gradleFile | grep "flavorName" | awk -F '["]' '{print $6}')
# IFS=$'\n' read -d '' -a listaFlavors <<< "$varAndroidFlavors"
# pastaFlavors="$flutterFolder/assets/flavors"
# listaFlavors=$(find "$pastaFlavors" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort)
envDart="$flutterFolder/lib/libs/env.dart"
listaFlavors=()
while IFS= read -r line; do
# Procura por linhas que contêm "case '".
if [[ "$line" == *"case '"* ]]; then
# Extrai o valor entre aspas após "case ".
flavorEncontrado=$(echo "$line" | awk -F"'" '{print $2}')
# echo "$flavorEncontrado"
# Adiciona o sabor encontrado ao array.
listaFlavors+=("$flavorEncontrado")
fi
done < "$envDart"
IFS=$'\n' emOrdemAlfabetica=($(sort <<<"${listaFlavors[*]}")) # ordem alfabetica
unset IFS
listaFlavors="${emOrdemAlfabetica[@]}"
# androidGetPackage() {
# # O nome do sabor do aplicativo é passado como primeiro argumento para a função
# flavorName="$1"
# # Caminho para o arquivo build.gradle
# gradleFile="$flutterFolder/android/app/build.gradle"
# # Usando grep para encontrar a linha que contém o nome do sabor e awk para extrair o identificador do pacote
# packageName=$(grep -oP "${flavorName} \{ setFlavor\(it, \"\K[^\"]+" "$gradleFile")
# # Imprime o identificador do pacote
# echo "$packageName"
# }
androidGetPackage() {
flavor=$1
gradleFile="$flutterFolder/android/app/build.gradle"
# Usando grep para buscar a linha que contém o nome do flavor, seguido de awk para extrair o pacote
package=$(grep "\[name: '$flavor'" $gradleFile | head -n 1 | awk -F\" '{print $2}')
echo $package
}
function androidGetFlavorPosition(){
# flavors="seucondominio famaconnect hicond"
flavor=$1
position=-1
i=-1
for item in $listaFlavors; do
((i++))
if [ "$item" == "$flavor" ]; then
position=$i
break
fi
done
number=$(expr "$position" + 0)
echo $number
}
function build(){
tipo=$1
flavor=$2
tipoBuild=${3:-appbundle} # Se $tipoBuild estiver vazia ou não definida, atribui 'appbundle' a ela
descomentar_assets_flavors
comentar_assets_flavors_exceto $flavor
if [[ "$tipo" == "android" ]]; then
# android
androidBuild $tipoBuild $flavor
else
# ios
iosBuild $flavor
fi
descomentar_assets_flavors
}
function androidBuild(){
tipoBuild=$1
flavor=$2
echo "--------------------------------------------"
echo "Flutter criando build $tipoBuild de $flavor - $package"
echo "--------------------------------------------"
cd $flutterFolder; flutter build $tipoBuild --release --flavor $flavor --dart-define=flavorApp=$flavor
# cd $flutterFolder; flutter build appbundle --release --flavor $flavor --dart-define=flavorApp=$flavor
# cd $flutterFolder; flutter build apk --release --flavor $flavor --dart-define=flavorApp=$flavor
}
install_lib() {
SERVICE_DIR="/usr/local/bin"
SERVICE_PATH="$SERVICE_DIR/scflutter"
# sudo wget -O $SERVICE_DIR/_scflutter https://gist.githubusercontent.com/denoww/983566e9653cbef4b5e40ffce029582b/raw;
sudo curl -o $SERVICE_DIR/_scflutter https://gist.githubusercontent.com/denoww/983566e9653cbef4b5e40ffce029582b/raw;
download_success=$?
echo "downloading new scflutter"
if [[ $download_success -eq 0 ]]; then
# sucesso ao baixar
sudo rm -f $SERVICE_DIR/scflutter
sudo mv $SERVICE_DIR/_scflutter $SERVICE_PATH
sudo chmod 777 $SERVICE_DIR/scflutter;
# sudo chmod +x $SERVICE_DIR/scflutter;
else
# erro ao baixar
sudo rm -f $SERVICE_DIR/_scflutter
echo "Erro ao baixar scflutter"
fi
}
function googleLogin() {
if [ -n "$access_token" ]; then
return
fi
client_id="444910204686-1qn6tatuk83hrnbpca0nftvg4vidrao2.apps.googleusercontent.com"
client_secret="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"
redirect_uri=http://localhost:8080
scope="https://www.googleapis.com/auth/androidpublisher"
response_type="code"
access_type="offline"
grant_type=authorization_code
login_url="https://accounts.google.com/o/oauth2/auth?scope=$scope&response_type=$response_type&access_type=$access_type&redirect_uri=$redirect_uri&client_id=$client_id"
google-chrome $login_url
echo "------------------------------------------------------------------"
echo "------------------------------------------------------------------"
echo "Faça login no google e cole o code que está na barra de endereços"
echo "------------------------------------------------------------------"
echo
read -p "Code: " code
if [ -z "$code" ]; then
echo "code não foi definido"
exit 1
fi
code_decoded=$(echo -e "$code" | sed 's/%2F/\//g')
# response=$(curl -X POST "https://accounts.google.com/o/oauth2/token" \
# --data "grant_type=authorization_code&client_id=$client_id&client_secret=$client_secret&code=$code_decoded&redirect_uri=$redirect_uri")
# access_token=$(echo "$response" | jq -r '.access_token')
googleRefreshAcessToken
}
function googleRefreshAcessToken(){
echo "---------------------------------------"
echo "googleRefreshAcessToken()"
echo "---------------------------------------"
TOKEN_ENDPOINT="https://oauth2.googleapis.com/token"
# Fazendo a solicitação POST para obter o token
if [ -z "$refresh_token" ]; then
echo "Criando refresh token + access token..."
# Endpoint do Google para trocar o código de autorização por tokens
TOKEN_ENDPOINT="https://oauth2.googleapis.com/token"
response=$(curl -s -d client_id=$client_id \
-d client_secret=$client_secret \
-d redirect_uri=$redirect_uri \
-d grant_type=authorization_code \
-d code=$code_decoded \
$TOKEN_ENDPOINT)
refresh_token=$(echo $response | jq -r '.refresh_token')
access_token=$(echo $response | jq -r '.access_token')
else
echo "Atualizando access token com refresh token..."
# REFRESH_TOKEN foi definido, prosseguindo com a solicitação POST para obter um novo access_token
response=$(curl -s -d client_id=$client_id \
-d client_secret=$client_secret \
-d refresh_token=$refresh_token \
-d grant_type=refresh_token \
$TOKEN_ENDPOINT)
access_token=$(echo $response | jq -r '.access_token')
fi
echo 'response'
echo $response
# new_access_token=$(echo $response | jq -r '.access_token')
echo "-------------------------------------------------------------"
echo "-------------------------------------------------------------"
echo "-------------------------------------------------------------"
echo "access_token=${access_token}"
echo "-------------------------------------------------------------"
echo "refresh_token=${refresh_token}"
echo "-------------------------------------------------------------"
echo "-------------------------------------------------------------"
echo "-------------------------------------------------------------"
if [ "$refresh_token" == 'null' ]; then
echo "refresh_token $refresh_token"
exit 1
fi
}
function androidConfigDeploy() {
#################
flavor=$1
# echo "$varAndroidFlavors"
package=$(androidGetPackage $flavor)
if [ -z "$package" ]; then
echo
echo
echo "Não foi possivel encontrar o package de $flavor - cadastre ele no build.gradle"
echo
helpDeploy
# echo
# echo "$androidPackages"
# echo 'null'
exit 1
fi
if [ -z "$access_token" ]; then
googleLogin
if [ "$access_token" = 'null' ]; then
echo "$flavor: access_token não pode ser vazio"
exit 1
fi
fi
# echo "-----------------------------"
# echo "androidConfigDeploy"
# echo "-----------------------------"
# echo "flavor $flavor"
# echo "package $package"
# echo "-----------------------------"
#################
host="https://androidpublisher.googleapis.com/androidpublisher/v3"
aplicationHost="$host/applications"
appHost="$aplicationHost/$package"
loginHeader="Authorization: Bearer ${access_token}"
#################
uploadHost=https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications
uploadappHost=$uploadHost/$package
uploadHeader="Content-Type: application/octet-stream"
#################
androidBundleFile="$flutterFolder/build/app/outputs/bundle/${flavor}Release/app-${flavor}-release.aab"
# echo "androidPackages"
# echo "$androidPackages"
# echo
# echo "varAndroidFlavors"
# echo "$varAndroidFlavors"
###################################
echo "-----------------------------"
echo "androidDeploy"
echo "-----------------------------"
echo "flavor $flavor"
echo "package $package"
echo "appHost $appHost"
echo "-----------------------------"
googleRefreshAcessToken
}
function androidCommitEditId(){
# if [ "$versionCode" = "null" ] || [ -z "$versionCode" ]; then
# echo "error: $error"
# echo "$flavor: androidCommitEditId - versionCode não pode ser nulo"
# exit 1
# fi
# validar editId
echo "$flavor: Validando editId $editId"
resp=$(curl -H "$loginHeader" -X POST $editIdUrl:validate); echo $resp
# validId=$(echo "$resp" | jq -r '.id')
error=$(echo "$resp" | jq -r '.error')
# commit no editId
echo "$flavor: Commit em editId $editId"
resp=$(curl -H "$loginHeader" -X POST $editIdUrl:commit); echo $resp
commitId=$(echo "$resp" | jq -r '.id')
error=$(echo "$resp" | jq -r '.error')
echo "----------------------------------------------------------"
echo "----------------------------------------------------------"
echo "----------------------------------------------------------"
echo "----------------------------------------------------------"
if [ "$error" != "null" ]; then
echo "$flavor Commit error: $error"
exit 1
fi
echo "$flavor: DEPLOY COM SUCESSO"
echo "----------------------------------------------------------"
echo "----------------------------------------------------------"
echo "----------------------------------------------------------"
editId=
unset editId
}
function androidUpdateTracks(){
androidGarantaEditId
if [ "$versionCode" = "null" ] || [ -z $versionCode ]; then
echo "error: $error"
echo "$flavor: androidUpdateTracks - versionCode não pode ser nulo"
exit 1
fi
androidUpdateTrack "internal"
androidUpdateTrack "production"
}
function androidUpdateTrack(){
trackName=$1
# colocar track no editId
urlTrack="$appHost/edits/$editId/tracks/$trackName"
dataTrack="{\"releases\": [{\"name\": \"versão ${versionCode}\", \"versionCodes\": [\"${versionCode}\"], \"status\": \"completed\" }]}"
echo "--------------------------------------------"
echo "$flavor: androidUpdateTrack $trackName"
echo "PUT $urlTrack"
echo "body: $dataTrack"
echo "--------------------------------------------"
resp=$(curl -H "$loginHeader" -H $jsonHeader -X PUT "$urlTrack" -d "$dataTrack"); echo "$resp"
error=$(echo "$resp" | jq -r '.error')
if [ "$error" != "null" ]; then
echo "$flavor erro em androidUpdateTrack: $error"
exit 1
fi
}
function androidUploadBundle(){
androidGarantaEditId
echo "-----------------------------"
echo "$flavor: fazendo upload de $androidBundleFile"
echo "-----------------------------"
resp=$(curl -H "$loginHeader" -H "$uploadHeader" -T "${androidBundleFile}" -X POST $uploadappHost/edits/$editId/bundles); echo $resp
error=$(echo "$resp" | jq -r '.error')
if [ "$error" != "null" ]; then
echo "$flavor error: $error"
exit 1
fi
versionCode=$(echo "$resp" | jq -r '.versionCode')
echo "-----------------------------"
echo "$flavor: versionCode $versionCode - upload completo"
echo "-----------------------------"
}
function androidGarantaEditId(){
# echo "editId $editId"
if [ -n "$editId" ] && [ "$editId" != 'null' ]; then
echo "Já existe editId"
return
fi
echo "-----------------------------"
echo "$flavor: criando editId"
echo "-----------------------------"
resp=$(curl -H "$loginHeader" -X POST $appHost/edits); echo $resp
editId=$(echo "$resp" | jq -r '.id'); echo editId; echo $editId
if [ -z "$editId" ] || [ "$editId" = 'null' ]; then
echo "Erro ao criar editId"
exit 1
fi
editIdUrl=$appHost/edits/${editId}; #echo editIdUrl; echo $editIdUrl
}
function helpDeploy(){
lista=( $listaFlavors )
lote_x_itens=10
total_de_itens=${#lista[@]}
echo "-------------------------------------------------------"
echo "Deploy todos $total_de_itens flavors"
echo "-------------------------------------------------------"
echo " scflutter deploy android all"
echo " scflutter deploy ios all (não está funcionando)"
# Tamanho do lote
tipos=("android" "ios")
for tipo in "${tipos[@]}"; do
echo "-------------------------------------------------------"
echo "$tipo deploy (10 por vez)"
echo "-------------------------------------------------------"
for (( i=0; i<$total_de_itens; i+=lote_x_itens )); do
# Obter os próximos 10 itens da lista
sub_lista=("${lista[@]:$i:$lote_x_itens}")
# Imprimir os itens da sub_lista em uma única frase
echo " scflutter deploy $tipo ${sub_lista[*]}"
done
done
echo "-------------------------------------------------------"
echo "Deploy um por um (são $total_de_itens flavors)"
echo "-------------------------------------------------------"
for item in $listaFlavors; do
echo " scflutter deploy android/ios $item"
done
echo "-------------------------------------------------------"
echo "Deploy corpflix - midia indoor Android TV"
echo "-------------------------------------------------------"
echo " google play"
echo " scflutter build android corpflix"
echo " gere o app com o comando acima e depois >> google play >> teste interno >> lá no topo direito mude o combo pra android tv >> criar nova versão"
echo " APK bit.ly/corpflix"
echo " scflutter build android corpflix apk"
echo " crie um APK com o comando acima >> google drive >> https://drive.google.com/drive/u/0/folders/1EumHxZ4xE-TqTdBYk0eFEKqSsifQNOLw >> arraste o apk pra essa pasta no google drive"
echo " APK estará linkado nesse atalho >> https://bit.ly/corpflix"
}
function criar_icones_tipo(){
tipo=$1
flavor=$2
file=$flutterFolder/flutter_launcher_icons-$flavor.yaml
cd $flutterFolder
echo "-------------------------------------"
echo "Criando icones $tipo para $flavor"
image_path="assets/flavors/$flavor/${tipo}.png"
if [ -e "$image_path" ]; then
echo "existe: $image_path"
else
echo "não existe: $image_path"
tipPadrao=ic_launcher
image_path="assets/flavors/$flavor/${tipPadrao}.png"
fi
if [ "$tipo" == "ic_notification" ]; then
execIos="false"
else
execIos="true"
fi
echo "flutter_launcher_icons:
android: $tipo
ios: $execIos
remove_alpha_ios: true
image_path: \"$image_path\"" > $file
flutter pub run flutter_launcher_icons -f $file
rm $file
}
function criar_icones(){
flavor=$1
if [ -z "$flavor" ]; then
echo "Todos os flavors"
for flavor in $listaFlavors; do
criarIconesLogosflavor $flavor
done
else
criarIconesLogosflavor $flavor
fi
}
function copiarBannerAndroidTv(){
flavor=$1
androidTvFlavor='seucondominio'
echo "-------------------------------"
echo "Criando banner android tv "
echo "provisório copiando banner ${androidTvFlavor} para não dar erro no build nos outros flavors por falta de banner (android manifest não é condicional)"
echo "-------------------------------"
folderAndroidFlavor="$flutterFolder/android/app/src"
folderOrigem="$folderAndroidFlavor/${androidTvFlavor}/res"
folderDestinoFlavor="$folderAndroidFlavor/$flavor/res"
# Loop através das pastas e fazer echo de seus nomes
for format in "$folderOrigem"/*/; do
# Extrair o nome da pasta sem o caminho
formatFolder=$(basename "$format")
# echo "$formatFolder"
fileToCopy="$folderOrigem/${formatFolder}/androidtvbanner.png"
# Verifique se o arquivo existe
if [ -f "$fileToCopy" ]; then
newFile="${folderDestinoFlavor}/${formatFolder}/androidtvbanner.png"
if [ ! -f "$newFile" ]; then
# echo "esse flavor ainda não tem androidtvbanner, poratnto vamos usar um padrão"
echo "$formatFolder: Copiando $fileToCopy para $newFile"
cp $fileToCopy $newFile
else
echo "$flavor $formatFolder já tem um androidtvbanner"
fi
else
echo "$formatFolder: arquivo $fileToCopy não existe."
fi
done
}
function criarIconesLogosflavor(){
flavor=$1
criar_icones_tipo ic_notification $flavor
criar_icones_tipo ic_launcher $flavor
copiarBannerAndroidTv $flavor
}
function help(){
echo "-------------------------------------------------------"
echo "Update lib scflutter"
echo "-------------------------------------------------------"
echo " scflutter update"
echo " ou"
echo " curl -s https://gist.githubusercontent.com/denoww/983566e9653cbef4b5e40ffce029582b/raw | bash -s install_lib"
echo
echo "-------------------------------------------------------"
echo "Modificar essa lib"
echo "-------------------------------------------------------"
echo " sudo subl /usr/local/bin/scflutter"
echo " ou"
echo " sudo code /usr/local/bin/scflutter"
echo " salve o conteúdo novo em"
echo " https://gist.github.com/denoww/983566e9653cbef4b5e40ffce029582b/edit"
echo
echo "-------------------------------------------------------"
echo "Icones"
echo "-------------------------------------------------------"
echo " scflutter criar_icones # cria de todos flavors"
echo " ou"
echo " scflutter criar_icones NOME_FLAVOR"
echo
echo
echo "-------------------------------------------------------"
echo "Desligar pc em x minutos"
echo "-------------------------------------------------------"
echo " sudo shutdown -h +60"
echo
echo "-------------------------------------------------------"
echo "build (somente build e sem deploy)"
echo "-------------------------------------------------------"
echo " scflutter build android NOME_FLAVOR"
echo " scflutter build ios NOME_FLAVOR"
echo
echo "android apk"
echo " scflutter build android NOME_FLAVOR apk"
echo "-------------------------------------------------------"
echo "Configurar loja na apple (necessário criar a loja manualmente lá antes)"
echo "-------------------------------------------------------"
echo " scflutter configurar_loja ios visao_condominial \"Visão Condominioal\" \"http://www.visaoxxx.com.br\""
echo "-------------------------------------------------------"
echo "Upload screenshots na loja android e ios"
echo "-------------------------------------------------------"
echo " scflutter config_loja_upload_screenshots ios visao_condominial"
helpDeploy
echo
# echo " scflutter googleLogin"
# echo
}
pubspecFile="$HOME/workspace/erp_flutter/pubspec.yaml"
function descomentar_assets_flavors(){
# Criando um arquivo temporário para armazenar o conteúdo modificado
tempFile=$(mktemp)
# Flag para indicar se estamos na seção de assets
inAssets=false
# Lendo o arquivo linha por linha
while IFS= read -r line || [[ -n "$line" ]]; do
# Verificando se a linha marca o início da seção de assets
if echo "$line" | grep -qE "^#\s+-\s+assets/flavors/"; then
inAssets=true
# Verificando se estamos fora da seção de assets
elif [[ $inAssets == true && "$line" =~ ^[^[:space:]] ]]; then
inAssets=false
fi
# Descomentando as linhas se estivermos na seção de assets
if [[ $inAssets == true && "$line" =~ ^#\ +-\ ]]; then
# echo "${line/#\#\ /}" >> "$tempFile"
echo "${line/#\#\ \ \ \ / }" >> "$tempFile"
else
echo "$line" >> "$tempFile"
fi
done < "$pubspecFile"
# Substituindo o arquivo original pelo arquivo temporário modificado
mv "$tempFile" "$pubspecFile"
echo "pubspec.yaml: devolvido assets de todos os flavors"
}
function comentar_assets_flavors_exceto(){
# reduz o tamanho do apk,
# pois comentano não envia assets do flavor y para build do flavor x
flavor=$1
tempFile=$(mktemp) # Criando um arquivo temporário
# Flag para indicar se estamos na seção de assets
inAssetsSection=false
# Lendo o arquivo linha por linha
while IFS= read -r line || [[ -n "$line" ]]; do
# Checando se a linha marca o início da seção de assets
if echo "$line" | grep -q "^ assets:"; then
inAssetsSection=true
# Checando se saímos da seção de assets (detectando uma linha que não começa com espaço ou '-')
elif $inAssetsSection && (echo "$line" | grep -qvE "^\s+[-]"); then
inAssetsSection=false
fi
# Se estamos na seção de assets e a linha não contém '$flavor', comentamos
if $inAssetsSection && echo "$line" | grep -q "assets/flavors/" && ! echo "$line" | grep -q "$flavor"; then
echo "#$line" >> "$tempFile"
else
# De outra forma, mantemos a linha como está
echo "$line" >> "$tempFile"
fi
done < "$pubspecFile"
# Substituindo o arquivo original pelo temporário modificado
mv "$tempFile" "$pubspecFile"
echo "pubspec.yaml: As linhas de assets foram comentadas, exceto para '$flavor'."
}
function ios_configurar_loja(){
flavor=$1
titulo_loja=$2
site=$3
# locale=${4:-"pt-BR"}
locale="pt-BR"
ios_configurar_flavor
if [ -z "$ios_app_store_version_id" ] || [ "$ios_app_store_version_id" = "null" ]; then
echo "Nenhuma versão pendente encontrada para configurar loja"
exit 1
fi
ios_config_loja_descricao $ios_app_store_version_id
ios_config_loja_copyright $ios_app_store_version_id
ios_config_loja_dados_revisao $ios_app_store_version_id
ios_config_loja_privacidade "$ios_app_info_id" "$titulo_loja"
ios_config_loja_classificacao_etaria_nenhum "$ios_app_info_id" "$ios_app_store_version_id"
# ios_config_loja_upload_screenshots $ios_app_store_version_id
# ios_remover_china_continental "$ios_app_id" "$ios_app_info_id"
# ios_config_loja_preco_gratis $ios_app_id
# ios_config_loja_categoria_financas $ios_app_info_id
}
# function ios_config_loja_upload_screenshots() {
# flavor=$1
# ios_configurar_flavor
# echo "📸 Organizando screenshots para app versão $ios_app_store_version_id"
# # 1. Buscar localizações da versão
# echo "🔍 Buscando localizações..."
# localization_id=$(ios_get_localization $ios_app_store_version_id)
# echo "🗣️ Localização: $localization_id"
# # 2. Buscar screenshot sets dessa localização
# echo "🔍 Buscando screenshot sets..."
# setsResp=$(ios_request GET "/appStoreVersionLocalizations/$localization_id/appScreenshotSets")
# set_ids=$(echo "$setsResp" | jq -r '.data[].id')
# # echo "set_ids"
# # echo "set_ids"
# # echo "$set_ids"
# for set_id in $set_ids;
# do
# # 4. Deletar screenshots existentes
# echo "🧹 Limpando screenshots do set $set_id..."
# screenshotsResp=$(ios_request GET "/appScreenshotSets/$set_id/appScreenshots")
# screenshot_ids=$(echo "$screenshotsResp" | jq -r '.data[].id')
# for screenshot_id in $screenshot_ids;
# do
# echo "❌ Deletando screenshot $screenshot_id..."
# ios_request DELETE "/appScreenshots/$screenshot_id"
# done
# # 5. Upload de novos screenshots (Exemplo com arquivos locais)
# setsResp=$(ios_request GET "/appStoreVersionLocalizations/$localization_id/appScreenshotSets")
# set_ids_and_types=$(echo "$setsResp" | jq -r '.data[] | [.id, .attributes.screenshotDisplayType] | @tsv')
# for folder in iphone_6_7 ipad_12_9; do
# if [ "$folder" = "iphone_6_7" ]; then
# display_type="APP_IPHONE_67"
# elif [ "$folder" = "ipad_12_9" ]; then
# display_type="IPAD_PRO_3GEN_129"
# else
# echo "❌ Pasta desconhecida: $folder"
# continue
# fi
# # display_type="${device_map[$folder]}"
# # Buscar o ID do set correspondente ao display_type
# set_id=$(echo "$set_ids_and_types" | grep "$display_type" | cut -f1)
# if [ -z "$set_id" ]; then
# echo "⚠️ Não foi encontrado um screenshot set para $display_type (pasta $folder)"
# continue
# fi
# echo "📁 Pasta $folder será usada para o set $set_id (tipo $display_type)"
# for filepath in /Users/seucondominio/Downloads/ios_review/captura_tela_ios/$folder/*.png; do
# filename=$(basename "$filepath")
# echo "📤 Subindo $filename para o set $set_id..."
# if stat --version >/dev/null 2>&1; then
# # GNU/Linux
# FILESIZE=$(stat -c%s "$filepath")
# else
# # maco
# FILESIZE=$(stat -f%z "$filepath")
# fi
# uploadResp=$(ios_request POST "/appScreenshots" "$(cat <<EOF
# {
# "data": {
# "type": "appScreenshots",
# "attributes": {
# "fileName": "$filename",
# "fileSize": $FILESIZE
# },
# "relationships": {
# "appScreenshotSet": {
# "data": {
# "type": "appScreenshotSets",
# "id": "$set_id"
# }
# }
# }
# }
# }
# EOF
# )")
# # echo "uploadResp"
# # echo "uploadResp"
# # echo "$uploadResp"
# upload_url=$(echo "$uploadResp" | jq -r '.data.attributes.uploadOperations[0].url')
# method=$(echo "$uploadResp" | jq -r '.data.attributes.uploadOperations[0].method')
# headers=$(echo "$uploadResp" | jq -r '.data.attributes.uploadOperations[0].headers[] | "\(.name): \(.value)"')
# echo "🔗 Upload para $upload_url via $method"
# curl -X "$method" \
# $(for h in $headers; do echo -n "-H \"$h\" "; done) \
# --data-binary "@$filepath" \
# "$upload_url"
# done
# done
# done
# echo "✅ Screenshots organizados com sucesso!"
# }
# function ios_config_loja_categoria_financas() {
# ios_app_info_id="$1"
# new_category_id="6015" # ou 6015 ou 'FINANCE'
# echo "---------------------------------------------------------"
# echo "Atualizando categoria primária para ID: $new_category_id"
# echo "---------------------------------------------------------"
# JSON_DATA='{
# "data": {
# "type": "appInfos",
# "id": "'$ios_app_info_id'",
# "attributes": {
# "primaryCategoryId": "'$new_category_id'"
# }
# }
# }'
# url="/appInfos/$ios_app_info_id"
# echo "URL: $url"
# resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
# echo "Resposta:"
# echo "$resp" | jq
# if echo "$resp" | jq -e 'has("errors")' > /dev/null; then
# echo "Erro ao atualizar a categoria primária."
# echo "$resp" | jq '.errors[]'
# else
# echo "Categoria primária atualizada com sucesso."
# fi
# # JSON_DATA='{
# # "data": {
# # "type": "categories",
# # "id": "'$new_category_id'"
# # }
# # }'
# # url="/appInfos/$ios_app_info_id/relationships/primaryCategory"
# # echo "URL: $url"
# # resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
# # echo "Resposta:"
# # echo "$resp" | jq
# # if echo "$resp" | jq -e 'has("errors")' > /dev/null; then
# # echo "Erro ao atualizar a categoria primária."
# # else
# # echo "Categoria primária atualizada com sucesso."
# # fi
# # JSON_DATA='{
# # "data": {
# # "type": "appInfos",
# # "id": "'$ios_app_info_id'",
# # "attributes": {
# # "primaryCategory": "FINANCE"
# # }
# # }
# # }'
# # url="apps/$ios_app_id/appInfos/$ios_app_info_id"
# # echo "URL: $url"
# # resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
# # echo "Resposta:"
# # echo "$resp"
# }
function ios_config_loja_privacidade() {
ios_app_info_id="$1"
titulo_loja="$2"
locale="pt-BR"
echo "---------------------------------------------------------"
echo "Buscando localization $locale"
echo "---------------------------------------------------------"
localizationsResp=$(ios_request "GET" "/appInfos/$ios_app_info_id/appInfoLocalizations")
localizationId=$(echo "$localizationsResp" | jq -r ".data[] | select(.attributes.locale == \"$locale\") | .id")
if [ -z "$localizationId" ] || [ "$localizationId" = "null" ]; then
echo "Erro: localization $locale não encontrado."
echo "$localizationsResp"
exit 1
fi
# encoded_titulo=$(LC_ALL=C printf '%s' "$titulo_loja" | sed -e 's/[^A-Za-z0-9]/_/g; s/_/%/g; s/$[%]...$/\U\1/g; s/%20/ /g; s/%2D/-/g; s/%2E/./g; s/%5F/_/g')
encoded_titulo=$(jq -rn --arg v "$titulo_loja" '$v|@uri')
# URLs e texto a preencher
privacy_policy_url="https://www.seucondominio.com.br/politica-privacidade?no_layout=true&app_name=$encoded_titulo"
# privacy_choices_url="https://www.seucondominio.com.br/preferencias-de-privacidade"
# privacy_policy_text="Veja como seus dados são tratados no aplicativo."
echo "---------------------------------------------------------"
echo "Atualizando campos de privacidade em $locale"
echo "---------------------------------------------------------"
JSON_DATA="{
\"data\": {
\"type\": \"appInfoLocalizations\",
\"id\": \"$localizationId\",
\"attributes\": {
\"privacyPolicyUrl\": \"$privacy_policy_url\"
}
}
}"
resp=$(ios_request "PATCH" "/appInfoLocalizations/$localizationId" "$JSON_DATA")
echo "Resposta:"
echo "$resp"
}
function ios_config_loja_classificacao_etaria_nenhum() {
ios_app_info_id="$1"
ios_app_store_version_id="$2"
# ageRatingDeclaration
echo "---------------------------------------------------------"
echo "Buscando localization"
echo "---------------------------------------------------------"
ageData=$(ios_request "GET" "/appInfos/$ios_app_info_id/ageRatingDeclaration")
age_rating_id=$(echo "$ageData" | jq -r '.data.id')
echo "ageData"
echo "ageData"
echo "ageData"
echo "$ageData"
if [ -z "$age_rating_id" ] || [ "$age_rating_id" = "null" ]; then
echo "Erro: age_rating_id não encontrado em"
echo "$ageData"
exit 1
fi
echo "✅ ID do ageRatingDeclaration: $age_rating_id"
echo "---------------------------------------------------------"
echo "Atualizando classificação etária"
echo "---------------------------------------------------------"
# ##################
# ##################
# campos do json aqui
# https://developer.apple.com/documentation/appstoreconnectapi/ageratingdeclarationupdaterequest/data-data.dictionary/attributes-data.dictionary
# ##################
# ##################
# ##################
JSON_DATA="{
\"data\": {
\"type\": \"ageRatingDeclarations\",
\"id\": \"$age_rating_id\",
\"attributes\": {
\"alcoholTobaccoOrDrugUseOrReferences\": \"NONE\",
\"contests\": \"NONE\",
\"gambling\": false,
\"lootBox\": false,
\"unrestrictedWebAccess\": false,
\"gamblingSimulated\": \"NONE\",
\"horrorOrFearThemes\": \"NONE\",
\"matureOrSuggestiveThemes\": \"NONE\",
\"medicalOrTreatmentInformation\": \"NONE\",
\"profanityOrCrudeHumor\": \"NONE\",
\"sexualContentGraphicAndNudity\": \"NONE\",
\"sexualContentOrNudity\": \"NONE\",
\"violenceCartoonOrFantasy\": \"NONE\",
\"violenceRealistic\": \"NONE\",
\"violenceRealisticProlongedGraphicOrSadistic\": \"NONE\"
}
}
}"
url="/ageRatingDeclarations/$age_rating_id"
resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
echo "Resposta:"
echo "$resp"
}
# function ios_remover_china_continental() {
# ios_app_id=$1
# ios_app_info_id=$2
# echo "---------------------------------------------------------"
# echo "Removendo China continental dos territórios disponíveis"
# echo "---------------------------------------------------------"
# # Buscar os territórios disponíveis diretamente do app
# territories_resp=$(ios_request "GET" "/apps/$ios_app_id/availableTerritories")
# # Extrair todos os territórios, exceto a China continental (CHN)
# territories=$(echo "$territories_resp" | jq -r '.data[] | select(.attributes.territory != "CHN") | .id' | tr '\n' ',' | sed 's/,$//')
# # Preparar o JSON para a atualização
# JSON_DATA="{
# \"data\": [
# $(echo "$territories" | sed 's/,/,\n/g' | sed 's/(.*)/{\"type\": \"territories\", \"id\": \"$1\"}/g' | tr '\n' ',' | sed 's/,$//')
# ]
# }"
# # Fazer a requisição PATCH para atualizar os territórios
# url="/apps/$ios_app_id/relationships/availableTerritories"
# echo "Atualizando territórios disponíveis. URL: $url"
# resp=$(ios_request "PATCH" "$url" "$JSON_DATA")
# echo "Resposta:"
# echo "$resp"
# # Verificar se a atualização foi bem-sucedida
# if [ -z "$resp" ] || [ "$resp" = "{}" ]; then
# echo "China continental removida com sucesso dos territórios disponíveis."
# else
# echo "Erro ao remover China continental dos territórios disponíveis."
# echo "Detalhes do erro:"
# echo "$resp" | jq '.errors[]'
# fi
# }
# function ios_config_loja_preco_gratis() {
# ios_app_id=$1
# echo "---------------------------------------------------------"
# echo "Definindo preço 0 (gratuito)"
# echo "---------------------------------------------------------"
# # URL oficial para priceTiers: 0 é grátis
# priceTier="0"
# # Pegando a data de hoje (formato ISO)
# today=$(date +%Y-%m-%d)
# JSON_DATA="{
# \"data\": {
# \"type\": \"appPrices\",
# \"attributes\": {
# \"startDate\": \"$today\"
# },
# \"relationships\": {
# \"app\": {
# \"data\": {
# \"type\": \"apps\",
# \"id\": \"$ios_app_id\"
# }
# },
# \"priceTier\": {
# \"data\": {
# \"type\": \"appPriceTiers\",
# \"id\": \"$priceTier\"
# }
# }
# }
# }
# }"
# resp=$(ios_request "POST" "/appPrices" "$JSON_DATA")
# echo "Resposta:"
# echo "$resp"
# }
function ios_get_localization(){
ios_app_store_version_id=$1
locale="pt-BR"
url="/appStoreVersions/$ios_app_store_version_id/appStoreVersionLocalizations"
localizations=$(ios_request "GET" "$url")
localizations_escaped=$(echo "$localizations" | perl -pe 's/([\x00-\x1F])/sprintf("\\u%04x", ord($1))/eg')
localization_id=$(echo "$localizations_escaped" | jq -r ".data[] | select(.attributes.locale == \"$locale\") | .id")
echo $localization_id
}
function ios_config_loja_descricao(){
ios_app_store_version_id=$1
echo "---------------------------------------------------------"
echo "Verificando se descrição da loja $locale já existe"
echo "---------------------------------------------------------"
localization_id=$(ios_get_localization $ios_app_store_version_id)
promotionalText="Gestão completa para síndicos, moradores, porteiros zeladores... Fácil, dinâmica e integrada."
descricao="$titulo_loja\n- Mais completa plataforma digital de gestão e auxílio e \ncontrole para condomínio\n- Plataforma 100% dinâmica e de fácil utilização\n\nCondomínio\nUtilize o sistema de mídia indoor para comunicados e propagandas nos elevadores\n\nSíndicos\n- Cadastro completo das unidades \n- Gestão de documentos, comunicados, ocorrências e eventos\n- Controle de acesso\n\nMoradores \n- Reserva de espaços para eventos e mudanças\n- Encomendas, visitantes\n- Ocorrências e dados da unidade\n\nAdministradora\n- Gestão de múltiplo condomínios\n- Gestão financeira completa\n- Gere gráficos e relatórios\n\nFuncionários\n- Atualização de cadastros e notificação de encomendas\n- Telefones úteis e empréstimos do condomínio\n- Estoque e leituras das unidades\n\n$titulo_loja é uma plataforma integrada de gestão e controle de acesso para condomínios.\n\nSe você, síndico ou administrador de condomínio, procura uma solução inteligente, completa, inovadora e interativa, com poucos cliques o $titulo_loja lhe dará suporte ao administrar inúmeros funções diárias, como:\n\nAutorização de entrada de visitantes;\nReserva de áreas comuns;\nControle e resumo de despesas;\nCobrança;\nReclamações e muito mais.\nO $titulo_loja vai te auxiliar a realizar suas funções com ainda mais eficiência!\n\nConecte-se com a melhor e mais completa plataforma digital de gestão e auxílio e controle para condomínios.\n\nPlataforma 100% dinâmica e de fácil utilização!\n\nSite personalizado para cada condomínio.\n\nIdeal para moradores, síndicos, administradoras e funcionários.\n\nServiços personalizados para:\n\n*Condomínio\n- Utilize e sistema de mídia Indoor para comunicados e propagandas nos elevadores\n\n*Síndicos\n- Cadastro de proprietários e moradores, inclusive veículos, pets, visitantes e funcionários;\n- Publique Comunicados;\n- Aplique Multas e advertências;\n- Acompanhe e organize o estoque;\n- Faça previsões orçamentárias;\n- Publique, gere e receba documentos;\n- Organize eventos;\n- Monitore entrada e saída de veículos e pedestres através de controles e biometria.\n\n*Moradores\n- Reserve salão de festas e espaços para eventos;\n- Notifique suas mudanças e reformas;\n- Receba notificações sobre suas encomendas;\n- Cadastre seus visitantes e funcionários particulares;\n- Abra ocorrências;\n- Acompanhe o mural do condomínio;\n- Atualize seus dados de morador e ou proprietário;\n\n*Administradora\n- Acompanhe e atualize o caixa do condomínio;\n- Gere e receba pagamentos;\n- Acompanhe e gerencie rateios;\n- Emissão de boletos;\n- Acompanhe inadimplentes;\n- Gere gráficos e relatórios;\n- Cadastre cobranças por frações ou valores;\n- Calcule correções monetárias;\n- Acompanhe e gerencie contratos e acordos;\n- Gere cartas de cobrança;\n- Publique medições de gás/água/luz.\n\n*Funcionários (porteiros e zeladores)\n- Atualize e cadastre visitantes;\n- Notifique encomendas;\n- Acompanhe ocorrências;\n- Receba e atualize ordens de serviço e tarefas;\n- Tenha acesso a telefones úteis;\n- Organize e gerencie empréstimo de objetos do condomínio;\n- Efetue leituras de gás/luz/água;\n- Acompanhe e atualize o estoque;\n\nInove a forma de se CONECTAR!"
# JSON_ATTRIBUTES="\"description\": \"$descricao\",
# \"keywords\": \"software para condomínio, administração de condomínio, app para condomínio, gestão condomínio\","
# if [ -n "$site" ]; then
# JSON_ATTRIBUTES+="\"marketingUrl\": \"$site\","
# fi
# JSON_ATTRIBUTES+="\"supportUrl\": \"https://www.seucondominio.com.br/contato?no_layout=true\",
# \"promotionalText\": \"$promotionalText\""
JSON_ATTRIBUTES="\"description\": \"$descricao\",
\"keywords\": \"software para condomínio, administração de condomínio, app para condomínio, gestão condomínio\",
\"marketingUrl\": \"$site\",
\"supportUrl\": \"https://www.seucondominio.com.br/contato?no_layout=true\",
\"promotionalText\": \"$promotionalText\""
if [ -n "$localization_id" ]; then
echo "Descrição $locale já existe para – atualizando..."
JSON_DATA="{
\"data\": {
\"type\": \"appStoreVersionLocalizations\",
\"id\": \"$localization_id\",
\"attributes\": {
$JSON_ATTRIBUTES
}
}
}"
resp=$(ios_request "PATCH" "/appStoreVersionLocalizations/$localization_id" "$JSON_DATA")
else
echo "Descrição $locale não existe – criando..."
JSON_DATA="{
\"data\": {
\"type\": \"appStoreVersionLocalizations\",
\"attributes\": {
\"locale\": \"$locale\",
$JSON_ATTRIBUTES
},
\"relationships\": {
\"appStoreVersion\": {
\"data\": {
\"type\": \"appStoreVersions\",
\"id\": \"$ios_app_store_version_id\"
}
}
}
}
}"
resp=$(ios_request "POST" "/appStoreVersionLocalizations" "$JSON_DATA")
fi
echo "resposta criação da loja"
echo $resp
}
function ios_config_loja_copyright(){
ios_app_store_version_id=$1
echo "---------------------------------------------------------"
echo "$flavor: Atualizando copyright versão etc"
echo "---------------------------------------------------------"
JSON_COPYRIGHT="{
\"data\": {
\"type\": \"appStoreVersions\",
\"id\": \"$ios_app_store_version_id\",
\"attributes\": {
\"copyright\": \"$titulo_loja\",
\"versionString\": \"$versaoString\"
}
}
}"
resp_copyright=$(ios_request "PATCH" "/appStoreVersions/$ios_app_store_version_id" "$JSON_COPYRIGHT")
echo "Resposta:"
echo "$resp"
}
function ios_config_loja_dados_revisao(){
ios_app_store_version_id=$1
echo "==============================="
echo "Preenchendo contatos do dev e login de teste para apple revisar apps..."
echo "Buscando reviewDetail existente..."
reviewResp=$(ios_request "GET" "/appStoreVersions/$ios_app_store_version_id/appStoreReviewDetail")
reviewDetailId=$(echo "$reviewResp" | jq -r '.data.id')
JSON_REVIEW_ATTR="{
\"contactFirstName\": \"Rodrigo\",
\"contactLastName\": \"Mendonça\",
\"contactPhone\": \"+5562985673142\",
\"contactEmail\": \"[email protected]\",
\"demoAccountName\": \"[email protected]\",
\"demoAccountPassword\": \"testestaging\",
\"demoAccountRequired\": true
}"
if [ "$reviewDetailId" = "null" ] || [ -z "$reviewDetailId" ]; then
echo "Criando reviewDetail novo..."
JSON_DATA="{
\"data\": {
\"type\": \"appStoreReviewDetails\",
\"attributes\": $JSON_REVIEW_ATTR,
\"relationships\": {
\"appStoreVersion\": {
\"data\": {
\"type\": \"appStoreVersions\",
\"id\": \"$ios_app_store_version_id\"
}
}
}
}
}"
resp=$(ios_request "POST" "/appStoreReviewDetails" "$JSON_DATA")
else
echo "Atualizando reviewDetail existente..."
JSON_DATA="{
\"data\": {
\"type\": \"appStoreReviewDetails\",
\"id\": \"$reviewDetailId\",
\"attributes\": $JSON_REVIEW_ATTR
}
}"
resp=$(ios_request "PATCH" "/appStoreReviewDetails/$reviewDetailId" "$JSON_DATA")
fi
echo "$resp"
}
function ios_get_app_info(){
ios_app_id=$1
# echo "---------------------------------------------------------"
# echo "Buscando ios_app_info_id para definir categoria"
# echo "---------------------------------------------------------"
# Primeiro, vamos buscar a lista de appInfos para o app
url="/apps/$ios_app_id/appInfos"
resp=$(ios_request "GET" "$url")
# Extrair o ID do appInfo mais recente
ios_app_info_id=$(echo "$resp" | jq -r '.data[0].id')
if [ -z "$ios_app_info_id" ] || [ "$ios_app_info_id" = "null" ]; then
# echo "Erro: ios_app_info_id não encontrado"
# echo "$resp"
exit 1
fi
echo $ios_app_info_id
}
function deploy(){
tipo=$2
all=$3
if [[ "$all" == "all" ]]; then
flavList=$listaFlavors
else
shift 2
flavList=("$@")
flavList="${flavList[@]}"
fi
# echo tipo $tipo
if [[ "$tipo" == "android" ]]; then
# android
cmdTipo=androidDeploy
else
# ios
cmdTipo=iosDeploy
fi
if [ $(echo "$flavList" | wc -w) -ge 2 ]; then
# mais de um flavor
clearBuilds
fi
limparCacheQtd=0
i=1
qtdItems=$(echo "$flavList" | wc -w)
for flavor in $flavList; do
echo " -----------------------------------"
echo " $i/$qtdItems $cmdTipo $flavor"
echo " -----------------------------------"
((limparCacheQtd++))
((i++))
if [ $limparCacheQtd -eq 3 ]; then
clearBuilds
limparCacheQtd=0
fi
eval "${cmdTipo} ${flavor}"
done
}
function clearBuilds(){
# echo "!!! limpando cache"
cd $flutterFolder;
flutter clean
}
###################################################
case $1 in
install_lib)
install_lib
;;
update)
install_lib
;;
build)
build $2 $3 $4
;;
deploy)
deploy $@
;;
criar_icones)
criar_icones $2
;;
# googleLogin)
# googleLogin
# ;;
configurar_loja)
if [[ "$2" == "ios" ]]; then
ios_configurar_loja "$3" "$4" "$5"
fi
;;
config_loja_upload_screenshots)
if [[ "$2" == "ios" ]]; then
ios_config_loja_upload_screenshots "$3"
fi
;;
*)
# echo "Erro: Aprenda a usar scflutter"
echo
help
exit 1 # 1 é resposta de erro
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment