Skip to content

Instantly share code, notes, and snippets.

@ctrlcctrlv
Last active October 18, 2023 09:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctrlcctrlv/fae00f11a20951e06db7ed502fd29f4c to your computer and use it in GitHub Desktop.
Save ctrlcctrlv/fae00f11a20951e06db7ed502fd29f4c to your computer and use it in GitHub Desktop.
gcloud_translate.bash
#
# gcloud_translate() Fred util
# ★ gcloud_translate [source_language] [target_language]
#
# @mainfunc cloud_translate
BANNER=$(cat<<'BANNER'
_ _ _ _ _ _ _
__ _ ___| | ___ _ _ __| | | |_ _ __ __ _ _ __ ___| | __ _| |_ ___ | |__ __ _ ___| |__
/ _` |/ __| |/ _ \| | | |/ _` | | __| '__/ _` | '_ \/ __| |/ _` | __/ _ \ | '_ \ / _` / __| '_ \
| (_| | (__| | (_) | |_| | (_| | | |_| | | (_| | | | \__ \ | (_| | || __/_| |_) | (_| \__ \ | | |
\__, |\___|_|\___/ \__,_|\__,_|___\__|_| \__,_|_| |_|___/_|\__,_|\__\___(_)_.__/ \__,_|___/_| |_|
|___/ |_____|
BANNER
)
#
# Interactively translate text using Google Cloud Translate API.
# Requires gcloud, yq, jq, and perl. Optionally requires sqlite3, xsel, and wl-copy.
# A bit of a mess, but it works.
#
TRUECOLOR_DARK_RED=`tput setaf 52`
TRUECOLOR_DARK_GREEN=`tput setaf 22`
TRUECOLOR_DARK_YELLOW=`tput setaf 94`
TRUECOLOR_DARK_BLUE=`tput setaf 19`
TRUECOLOR_DARK_MAGENTA=`tput setaf 127`
TRUECOLOR_DARK_CYAN=`tput setaf 23`
TRUECOLOR_DARK_GRAY=`tput setaf 238`
BOLD=`tput bold`
ITALIC=`tput sitm`
UNDERLINE=`tput smul`
RESET=`tput sgr0`
_F_CONFIG_ROOT="$HOME/.config/futiles"
_F_GCLOUD_TRANSLATE_CONFIG_ROOT="$_F_CONFIG_ROOT/gcloud_translate"
_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES="$_F_GCLOUD_TRANSLATE_CONFIG_ROOT/languages.json"
_F_SHARE_ROOT="$HOME/.local/share/futiles"
_F_HISTORY_ROOT="$_F_SHARE_ROOT/gcloud_translate/history/"
FUTIL_DEBUG="${FUTIL_DEBUG:-}"
_F_GCLOUD_TRANSLATE_DEBUG="$FUTIL_DEBUG"
SQLITE3_HISTORY="$_F_HISTORY_ROOT/history.sqlite"
# This is a 12 hour timeout used for the read bash builtin which has this envvar hardcoded
TMOUT=$((60 * 60 * 60 * 12))
declare -g -x TMOUT
export TMOUT
# Check if sourced
# @returns 0 if sourced
_f_gcloud_translate_sourced() {
[[ "${BASH_SOURCE[0]}" != "${0}" ]]
return $?
}
# @param $* = string to echo
# @returns 0
# $* means all arguments in one string, $@ means all arguments as separate strings
_fgtecho() {
>&2 echo -e "${TRUECOLOR_DARK_GREEN}$*${RESET}"
}
# @param $1 = prompt
# @param $@ = read arg, SHIFTED
_fgtread() {
local prompt="$1"
shift
>&2 read "$@" -p "${TRUECOLOR_DARK_GREEN}$prompt${RESET}"
}
# Create history database
SQL_SCHEMA1=$(cat<<-'SQL'
CREATE TABLE IF NOT EXISTS history (id INTEGER PRIMARY KEY, source TEXT, target TEXT, text TEXT, translation TEXT, request_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, translation_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, service_name TEXT NOT NULL, CONSTRAINT service_name CHECK (service_name IN ('gcloud', 'deepl', 'openai')));
SQL
)
SQL_SCHEMA2=$(cat<<-'SQL'
CREATE TABLE IF NOT EXISTS history_meta (id INTEGER PRIMARY KEY, key TEXT, value TEXT, UNIQUE(key, value));
CREATE TABLE IF NOT EXISTS history_hostnames (id INTEGER PRIMARY KEY, hostname TEXT, fk_history INTEGER, FOREIGN KEY(fk_history) REFERENCES history(id));
CREATE TABLE IF NOT EXISTS history_usernames (id INTEGER PRIMARY KEY, username TEXT, fk_history INTEGER, FOREIGN KEY(fk_history) REFERENCES history(id));
CREATE INDEX IF NOT EXISTS history_source_idx ON history (source);
CREATE INDEX IF NOT EXISTS history_target_idx ON history (target);
CREATE INDEX IF NOT EXISTS history_text_idx ON history (text);
CREATE INDEX IF NOT EXISTS history_translation_idx ON history (translation);
CREATE INDEX IF NOT EXISTS history_request_time_idx ON history (request_time);
CREATE INDEX IF NOT EXISTS history_translation_time_idx ON history (translation_time);
CREATE INDEX IF NOT EXISTS history_meta_key_idx ON history_meta (key);
CREATE INDEX IF NOT EXISTS history_meta_value_idx ON history_meta (value);
CREATE INDEX IF NOT EXISTS history_hostnames_hostname_idx ON history_hostnames (hostname);
CREATE INDEX IF NOT EXISTS history_usernames_username_idx ON history_usernames (username);
INSERT INTO history_meta (key, value) VALUES ('schema_version', '1');
SQL
)
_f_gcloud_sql_initialize() {
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: Initializing SQL database"
SQL_SCHEMA=()
while read -r line; do
SQL_SCHEMA+=("$line")
done < <(echo "$SQL_SCHEMA1 $SQL_SCHEMA2")
[[ -f "$SQLITE3_HISTORY" ]] || (
mkdir -p "$_F_HISTORY_ROOT"
for sql in "${SQL_SCHEMA[@]}"; do
sqlite3 "$SQLITE3_HISTORY" <<< "$sql"
_fgtecho "Executed SQL: $sql"
done
)
}
# @param $1 = query
# @param $@ = query args
# @returns return code of sqlite3
# @returns OUTSQL = output of sqlite3
# @returns PID = PID of sqlite3
# @requires sqlite3
# @requires perl
# @requires sqlite3.pl script
#
# Example:
# _f_gcloud_do_query "SELECT * FROM history WHERE id = ?;" 1
_f_gcloud_do_query() {
# Quiet bash's job control messages
set +b 2>/dev/null
set +m 2>/dev/null
hash sqlite3 2>/dev/null || { _fgtecho "sqlite3 not found, please install sqlite3"; return 1; }
local query="$1"
shift
local _query_args=()
for arg in "$@"; do
_query_args+=("${arg}")
done
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: Query: $query"
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: Query args: ${_query_args[@]}"
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && \
_fgtecho "Debug: Executing query:\n\t\t$query ${_query_args[@]}"
# We do this through a coproc so that we can read the output of sqlite3 in a non-blocking manner
# Use perl to replace ? with $1, $2, etc. because sqlite3 doesn't support ? in a heredoc
sqlpipe="$(mktemp -u)"
mkfifo "$sqlpipe"
coproc sqlite3.pl "$SQLITE3_HISTORY" "$query" "${_query_args[@]}" > "$sqlpipe"
PID=$COPROC_PID
OUTSQL="$(cat "$sqlpipe")"
wait $PID
rm -f "$sqlpipe"
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: Query output:\n\t\t$OUTSQL"
echo "$OUTSQL"
# Restore job control messages
set -b 2>/dev/null
set -m 2>/dev/null
}
# @returns 0
# @requires sqlite3
_f_gcloud_init_history() {
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: Initializing history database. $_F_HISTORY_ROOT $_F_GCLOUD_TRANSLATE_CONFIG_ROOT $SQLITE3_HISTORY $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES"
if [ ! -f "$SQLITE3_HISTORY" -o ! -d "$_F_HISTORY_ROOT" ]; then
_fgtecho "Creating history database..."
mkdir -p "$_F_HISTORY_ROOT"
_f_gcloud_sql_initialize
else
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] && _fgtecho "Debug: History database already exists"
fi
}
# @param $1 = id
#
# Delete history entry and all associated data
_f_gcloud_sql_cleanup_id() {
local id="$1"
[[ -z "$id" ]] && return 1
local i=0
_f_gcloud_do_query "DELETE FROM history WHERE id = ?;" "$id"
i=$((i+$?))
_f_gcloud_do_query "DELETE FROM history_hostnames WHERE fk_history = ?;" "$id"
i=$((i+$?))
_f_gcloud_do_query "DELETE FROM history_usernames WHERE fk_history = ?;" "$id"
i=$((i+$?))
# Warn about possible data corruption
[[ $i -ne 3 ]] && _fgtecho "Warning: Possible data corruption"
}
# @param $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES = path to languages list
# @returns return code of `gcloud beta ml translate get-supported-languages`
_f_gcloud_translate_download_languages() {
hash yq 2>/dev/null || { _fgtecho "yq not found, please install yq"; return 1; }
[[ ! -d $_F_GCLOUD_TRANSLATE_CONFIG_ROOT ]] && mkdir -p $_F_GCLOUD_TRANSLATE_CONFIG_ROOT
(gcloud beta ml translate get-supported-languages --model general/nmt --zone=us-central1 | yq) > "$_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES"
return $?
}
# Check if languages list is more than one month old…
# Download new list if it is.
# @param $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES = path to languages list
_f_gcloud_translate_check_languages() {
if [[ -f $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES ]]; then
local _F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES_LAST_MODIFIED=$(stat -c %Y $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES)
local _F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES_LAST_MODIFIED_DIFF=$(( $(date +%s) - $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES_LAST_MODIFIED ))
[[ $_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES_LAST_MODIFIED_DIFF -gt 2592000 ]] && (
_fgtecho "Languages list is more than one month old, downloading new list..."
_f_gcloud_translate_download_languages
)
else
_fgtecho "Languages list not found, downloading new list..."
_f_gcloud_translate_download_languages
fi
}
# @param $1 = language json string
# @returns 0 if language is valid
# @returns 1 if language is invalid
_f_check_language_validity() {
local langjsonstr="$1"
[[ -z "$langjsonstr" ]] && return 1
jq --arg langjson "$langjsonstr" 'select(.language == $langjson)' < "$_F_GCLOUD_TRANSLATE_CONFIG_LANGUAGES"
return $?
}
# @param $langiso639 = language’s ISO 639 code, e.g. en-US
# @returns to stdout = language name
# Private function
__f_language_name_to_iso639() {
local langname="$(cat /usr/share/i18n/locales/"$langiso639" | perl -ne 'print $1 if /language\s+"(.+)"/')"
[[ -z "$langname" ]] && return 1
echo "$langname"
}
# @param $1 = language name
# @returns to stdout = language’s ISO 639 code, e.g. en-US
_f_language_iso639_to_name() {
local langiso639="$1"
__f_language_name_to_iso639 "$langiso639"
[[ -z "$langiso639" ]] && return 1
# Try name before _
[[ -z "$langname" ]] && (
langiso639_before_underscore="$(echo "$langiso639" | cut -d_ -f1)"
__f_language_name_to_iso639 "$langiso639_before_underscore"
)
}
# @param $OUTTEXT = output transated text, global
# @returns 0
# @bypasses _fgtecho!
_f_gcloud_translate_print_translation() {
echo "${BOLD}""${OUTTEXT}""${RESET}"
}
# Uses `test -t 0` to determine if session is interactive,
# which works by using the fact that a non-interactive session
# will have stdin redirected from a file or pipe. :)
#
# May only work in GNU bash, wmmv (works on my machine™)
_f_gcloud_interactive() {
# Is session interactive?
declare -g -x FUTIL_INTERACTIVE
FUTIL_INTERACTIVE=$(test -t 0 ; echo $?)
return $FUTIL_INTERACTIVE
}
# @returns 0 if output is written to file
# @returns 1 if output is not written to file
# @returns 1 if no output text
# @requires wl-copy
# @requires xsel
#
# Output text to wl-copy, xsel, or file
_f_gcloud_output() {
# Prompt user for writing output to wl-copy
_fgtread "Write output where? [w(l-copy)/x(sel -b)/n(one)/f(ile)] " -n 1 -r
_fgtecho
case "$REPLY" in
w)
wl-copy <<< "$OUTTEXT"
;;
x)
xsel -b <<< "$OUTTEXT"
;;
f)
_fgtread "Write output to [t(emporary file)/s(pecified file)/n(one)]? " -n 1 -r
_fgtecho
case "$REPLY" in
t)
local OUTTXT="$(mktemp --suffix=.gcldtrns)"
_fgtecho "Output text will be stored in $OUTTXT"
echo "$OUTTEXT" > "$OUTTXT"
if ! _f_gcloud_interactive; then
echo "$OUTTXT"
fi
;;
s)
read -p "Write output to which file? " OUTTXT
echo "$OUTTEXT" > "$OUTTXT"
;;
*)
if _f_gcloud_interactive; then
_fgtecho "Invalid option, returning to main menu"
_f_gcloud_output
else
return 1
fi
esac
;;
n)
;;
*)
if _f_gcloud_interactive; then
_fgtecho "Invalid option"
_f_gcloud_output
else
_f_gcloud_output <<< "f""t" # Write to file, temporary
fi
;;
esac
}
# @returns temp file name
# @returns 1 if no input text
# @returns 0 if input text
_f_gcloud_read_stdin() {
local INTXT="$(mktemp --suffix=.gcldtrns)"
_fgtecho "Input text will be stored in $INTXT …"
trap "rm -f $INTXT; return 1" SIGINT
[ -f /dev/fd/4 ] && exec 4>&-
exec 4<>"$INTXT";
# Redirect stdin to temp file
_fgtecho "Enter text to translate, press Ctrl+D when done:"
read -d '' -r -e -u 0 CONTENT
wait $!
>&4 echo -e "$CONTENT";
perl -e 'print "\n"' >&4;
perl -pe 's/[\r]/\n/g' <&4 >&2;
exec 4<&-;
stat -c '%s' "$INTXT" | grep -q '^0$' && { _fgtecho "No input text"; return 1; }
echo "$INTXT" # Return temp file name to caller
return 0
}
# @param $1 = source language
# @param $2 = target language
#
# Interactively translate text using either Google Cloud Translate API, DeepL API, or OpenAI API.
# A bit of a mess, but it works.
# A history database is created in ~/.local/share/futiles/gcloud_translate/history.sqlite and is used to store all translations.
cloud_translate(){
# Check if any arg == -h or --help
for arg in "$@"; do
[[ "$arg" == "-h" || "$arg" == "--help" ]] && { _fgt_help; return 0; }
done
# Quiet bash's job control messages
set +b 2>/dev/null
set +m 2>/dev/null
# Check if sourced
_f_gcloud_translate_sourced || return 1
_f_gcloud_translate_check_languages
local langfrom="$1"
local langto="$2"
if [[ -z "$_FGT_CLOUD_SERVICE" ]]; then
{ _fgtecho "Usage: cloud_translate [source_language] [target_language]"; echo "$BANNER"; }
_fgtread "Cloud service not specified. Which cloud service? [(g)cloud/(dD)eepL/(cC)hatGPT by (oO)penAI]" -n 1 -r
_fgtecho
case "$REPLY" in
g|G)
_FGT_CLOUD_SERVICE="gcloud"
;;
d|D)
_FGT_CLOUD_SERVICE="deepl"
;;
o|O|c|C)
_FGT_CLOUD_SERVICE="openai"
;;
*)
_fgtecho "Invalid cloud service"
_f_gcloud_interactive && cloud_translate "$@"
;;
esac
fi
# Read text from stdin, put in temp file
local INTXT="$(_f_gcloud_read_stdin)"
trap "rm -f $INTXT" EXIT
[[ $? -ne 0 ]] && return 1
# Check if language is valid
while ! (_f_check_language_validity "$langfrom"); do
_fgtecho "Invalid source language"
read -p "Source language…? " langfrom
done
while ! (_f_check_language_validity "$langto"); do
_fgtecho "Invalid target language"
read -p "Target language…? " langto
done
# Translate
if [[ "$_FGT_CLOUD_SERVICE" == "gcloud" ]]; then
_f_gcloud_translate_gcloud "$langfrom" "$langto"
elif [[ "$_FGT_CLOUD_SERVICE" == "deepl" ]]; then
_f_gcloud_translate_deepl "$langfrom" "$langto"
elif [[ "$_FGT_CLOUD_SERVICE" == "openai" ]]; then
_f_gcloud_translate_openai "$langfrom" "$langto"
else
_fgtecho "Invalid cloud service"
return 1
fi <<< "$INTXT"
# Check if output is empty
[[ -z "$OUTTEXT" ]] && { _fgtecho "No output text"; return 1; }
# Print
_f_gcloud_translate_print_translation
# Output
_f_gcloud_output
_f_gcloud_init_history
# Correctly escape all texts to SQLite3 by using ? syntax and get last inserted row ID
sqli="INSERT INTO history (source, target, text, translation, service_name) VALUES (?, ?, ?, ?, ?);"
_f_gcloud_do_query "$sqli" "$langfrom" "$langto" "$(cat "$INTXT")" "$OUTTEXT" "$_FGT_CLOUD_SERVICE"
sqli="SELECT MAX(id) FROM history;"
local last_insert_rowid=()
while read -r line; do
last_insert_rowid+=("$line")
done < <(_f_gcloud_do_query "$sqli")
# Get hostname and username
local hostname="$(hostname)"
local username="$(whoami)"
# Insert hostname and username into history_hostnames and history_usernames
sqli="INSERT INTO history_hostnames (hostname, fk_history) VALUES (?, ?);"
_f_gcloud_do_query "$sqli" "$hostname" "${last_insert_rowid[0]}"
sqlu="INSERT INTO history_usernames (username, fk_history) VALUES (?, ?);"
_f_gcloud_do_query "$sqlu" "$username" "${last_insert_rowid[0]}"
# Cleanup
[[ -n "$_F_GCLOUD_TRANSLATE_DEBUG" ]] || rm -v -f "$INTXT"
}
_F_OPENAI_DEFAULT_TIMEOUT=5
# @param $1 = source language
# @param $2 = target language
# @requires jq
# @requires curl
#
# Translate text using OpenAI API
_f_gcloud_translate_openai() {
# Check if OpenAI API key is set
[[ -z "$OPENAI_API_KEY" ]] && \
{ _fgtecho "OPENAI_API_KEY is not set"; return 1; }
# Construct the prompt
local prompt="Translate the following text from $langfrom to $langto:\n\n$(cat "$INTXT")"
cat > "$INTXT" <<< "$prompt"
# Send the request to OpenAI API
OUTTREQ="$(curl -L -s -H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-X POST \
--data @<(
jq '{"model":"gpt-4", "messages": [{"role":"user","content":$prompt}]}' -s --rawfile prompt "$INTXT" <(echo) \
) \
https://api.openai.com/v1/chat/completions)"
OUTTEXT=$(jq -s -r '.[0].choices[0].message.content' <<< "$OUTTREQ")
}
# @param $1 = source language
# @param $2 = target language
# @requires yq
# @requires gcloud
# @requires perl
#
# Translate text using Google Cloud Translate API
_f_gcloud_translate_gcloud() {
read -r npipe < <(mktemp -u)
mkfifo "$npipe"
coproc \
(gcloud alpha ml translate translate-text --source-language="$langfrom" --target-language="$langto" \
--model general/nmt --zone=us-central1 --format=json --content-file="$INTXT" --mime-type=text/plain | \
yq -r '.translations[].translatedText' | sed -e 's/[\r]/\n/g') >>"$npipe" &
PID=$COPROC_PID
OUTTEXT="$(cat "$npipe")"
wait $PID
rm -f "$npipe"
}
# @param $1 = source language
# @param $2 = target language
# @requires jq
# @requires curl
# @requires perl
#
# Translate text using DeepL API
_f_gcloud_translate_deepl() {
[[ -z "$DEEPL_AUTH_KEY" ]] && \
[[ ! -f "$_F_GCLOUD_TRANSLATE_CONFIG_ROOT/deepl_auth_key" ]] && \
{ _fgtecho "DEEPL_AUTH_KEY not set and $_F_GCLOUD_TRANSLATE_CONFIG_ROOT/deepl_auth_key not found"; return 1; }
DEEPL_AUTH_KEY="$(cat "$_F_GCLOUD_TRANSLATE_CONFIG_ROOT/deepl_auth_key")"
# Use DeepL Pro ?
[[ -f $_F_GCLOUD_TRANSLATE_CONFIG_ROOT/deepl_pro ]] && \
DEEPL_PRO=1 || \
DEEPL_PRO=0
# DeepL API domains
if [[ $DEEPL_PRO -eq 1 ]]; then
DEEPL_API_DOMAIN="api.deepl.com"
else
DEEPL_API_DOMAIN="api-free.deepl.com"
fi
read -r npipe < <(mktemp -u)
mkfifo "$npipe"
# Text may be long so we must use curl's file-read feature
coproc \
(curl -s -X POST --data-urlencode "auth_key=$DEEPL_AUTH_KEY" --data-urlencode "text@$INTXT" \
--data-urlencode "source_lang=$langfrom" --data-urlencode "target_lang=$langto" \
"https://$DEEPL_API_DOMAIN/v2/translate" | \
jq -r '.translations[].text' | sed -e 's/[\r]/\n/g') >>"$npipe" &
PID=$COPROC_PID
OUTTEXT="$(cat "$npipe")"
wait $PID
rm -f "$npipe"
}
################################
## Aliases to cloud_translate ##
################################
_f_gcloud_translate() {
export _FGT_CLOUD_SERVICE="gcloud"
cloud_translate "$@"
_FGT_CLOUD_SERVICE=""
}
_f_deepl_translate() {
export _FGT_CLOUD_SERVICE="deepl"
cloud_translate "$@"
_FGT_CLOUD_SERVICE=""
}
_f_openai_translate() {
export _FGT_CLOUD_SERVICE="openai"
cloud_translate "$@"
_FGT_CLOUD_SERVICE=""
}
##############################
## Aliases, for convenience ##
##############################
gcloud_translate() {
_f_gcloud_translate "$@"
}
deepl_translate() {
_f_deepl_translate "$@"
}
openai_translate() {
_f_openai_translate "$@"
}
###############################
## More aliases, for funsies ##
###############################
GoogleTranslate() {
_f_gcloud_translate "$@"
}
DeepL() {
_f_deepl_translate "$@"
}
GPT4() {
_f_openai_translate "$@"
}
###################################
## Aliases, for backwards compat ##
###################################
gpt() { GPT4 "$@"; }
gpt3() { GPT4 "$@"; }
gpt4() { GPT4 "$@"; }
GPT3() { GPT4 "$@"; }
GPT() { GPT4 "$@"; }
ChatGPT() { GPT4 "$@"; }
Google() { GoogleTranslate "$@"; }
deepl() { DeepL "$@"; }
google() { GoogleTranslate "$@"; }
GT() { GoogleTranslate "$@"; }
###################################
## HELP ##
###################################
_fgt_help() {
>&2 echo "$BANNER"
>&2 cat<<HELP
cloud_translate() Fred util
★ cloud_translate [source_language] [target_language]
Interactively translate text using Google Cloud Translate API, DeepL API, or OpenAI API.
`tput smul`ENVIRONMENT VARIABLES`tput sgr0`
`tput bold`OPENAI_API_KEY`tput sgr0`
OpenAI API key. Required for OpenAI API.
`tput bold`DEEPL_AUTH_KEY`tput sgr0`
DeepL API key. Required for DeepL API.
`tput bold`FUTIL_DEBUG`tput sgr0`
Set to any value to enable debug mode.
`tput setaf 1 smul`Note: `tput sgr0`
Google Cloud Translate API does not require an API key, but will not
work if gcloud is not installed and configured and the user has not
enabled the Cloud Translation API.
`tput smul`OPTIONS`tput sgr0`
`tput bold`-h, --help`tput sgr0`
`tput smul`ARGUMENTS`tput sgr0`
`tput bold`source_language`tput sgr0`
Source language. If not specified, will be prompted for.
For OpenAI API, this is freeform text and should be the complete language name, e.g. English, French, etc.
For Google Cloud Translate API and DeepL API, this is the ISO 639-1 language code, e.g. en, fr, etc.
`tput bold`target_language`tput sgr0`
Target language. If not specified, will be prompted for.
`tput smul`ALIASES`tput sgr0`
`tput bold`gcloud_translate`tput sgr0`
`tput bold`GoogleTranslate`tput sgr0`
`tput bold`Google`tput sgr0`
Alias for cloud_translate using Google Cloud Translate API.
`tput bold`deepl_translate`tput sgr0`
`tput bold`DeepL`tput sgr0`
`tput bold`deepl`tput sgr0`
Alias for cloud_translate using DeepL API.
`tput bold`openai_translate`tput sgr0`
`tput bold`GPT4`tput sgr0`
`tput bold`GPT3`tput sgr0` `tput sitm`$TRUECOLOR_DARK_GRAY(deprecated; doesn't actually use GPT-3)`tput sgr0`
`tput bold`GPT`tput sgr0`
`tput bold`ChatGPT`tput sgr0`
Alias for cloud_translate using OpenAI API.
HELP
return 0
}
@ctrlcctrlv
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment