diff --git a/README.md b/README.md index 54b5c519..ac0f86f4 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ The segments that are currently available are: * [`dir`](#dir) - Your current working directory. * `history` - The command number for the current line. * [`ip`](#ip) - Shows the current IP address. +* [`public_ip`](#public_ip) - Shows your public IP address. * `load` - Your machine's load averages. * `os_icon` - Display a nice little icon, depending on your operating system. * `ram` - Show free RAM. @@ -315,6 +316,29 @@ specify the correct network interface by setting: |----------|---------------|-------------| |`POWERLEVEL9K_IP_INTERFACE`|None|The NIC for which you wish to display the IP address. Example: `eth0`.| +##### public_ip + +This segment will display your public IP address. There are several methods of obtaining this +information and by default it will try all of them starting with the most efficient. You can +also specify which method you would like it to use. The methods available are dig using opendns, +curl, or wget. The host used for wget and curl is http://ident.me by default but can be set to +another host if you prefer. + +The public_ip segment will attempt to update your public IP address every 5 minutes by default(also +configurable by the user). If you lose connection your cached IP address will be displayed until +your timeout expires at which point every time your prompt is generated a new attempt will be made. +Until an IP is successfully pulled the value of $POWERLEVEL9K_PUBLIC_IP_NONE will be displayed for +this segment. If this value is empty(the default)and $POWERLEVEL9K_PUBLIC_IP_FILE is empty the +segment will not be displayed. + +| Variable | Default Value | Description | +|----------|---------------|-------------| +|`POWERLEVEL9K_PUBLIC_IP_FILE`|'/tmp/p8k_public_ip'|This is the file your public IP is cached in.| +|`POWERLEVEL9K_PUBLIC_IP_HOST`|'http://ident.me'|This is the default host to get your public IP.| +|`POWERLEVEL9K_PUBLIC_IP_TIMEOUT`|300|The amount of time in seconds between refreshing your cached IP.| +|`POWERLEVEL9K_PUBLIC_IP_METHOD`|None|You can set this to any of 'dig', 'curl', or 'wget' to only use that method to refresh your IP.| +|`POWERLEVEL9K_PUBLIC_IP_NONE`|None|The string displayed when an IP was not obtained| + ##### rbenv This segment shows the version of Ruby being used when using `rbenv` to change your current Ruby stack. diff --git a/functions/icons.zsh b/functions/icons.zsh index 06d6ab20..77015f0b 100644 --- a/functions/icons.zsh +++ b/functions/icons.zsh @@ -76,6 +76,7 @@ case $POWERLEVEL9K_MODE in RUST_ICON '' PYTHON_ICON $'\U1F40D' # 🐍 SWIFT_ICON '' + PUBLIC_IP_ICON '' ) ;; 'awesome-fontconfig') @@ -134,6 +135,7 @@ case $POWERLEVEL9K_MODE in RUST_ICON $'\uE6A8' #  PYTHON_ICON $'\U1F40D' # 🐍 SWIFT_ICON '' + PUBLIC_IP_ICON '' ) ;; *) @@ -192,6 +194,7 @@ case $POWERLEVEL9K_MODE in RUST_ICON '' PYTHON_ICON '' SWIFT_ICON 'Swift' + PUBLIC_IP_ICON '' ) ;; esac diff --git a/powerlevel9k.zsh-theme b/powerlevel9k.zsh-theme index 9e89f68d..95a2a5ea 100755 --- a/powerlevel9k.zsh-theme +++ b/powerlevel9k.zsh-theme @@ -426,6 +426,79 @@ prompt_battery() { fi } +prompt_public_ip() { + # set default values for segment + set_default POWERLEVEL9K_PUBLIC_IP_TIMEOUT "300" + set_default POWERLEVEL9K_PUBLIC_IP_NONE "" + set_default POWERLEVEL9K_PUBLIC_IP_FILE "/tmp/p9k_public_ip" + set_default POWERLEVEL9K_PUBLIC_IP_HOST "http://ident.me" + + # Do we need a fresh IP? + local refresh_ip=false + if [[ -f $POWERLEVEL9K_PUBLIC_IP_FILE ]]; then + typeset -i timediff + # if saved IP is more than + timediff=$(($(date +%s) - $(date -r $POWERLEVEL9K_PUBLIC_IP_FILE +%s))) + [[ $timediff -gt $POWERLEVEL9K_PUBLIC_IP_TIMEOUT ]] && refresh_ip=true + # If tmp file is empty get a fresh IP + [[ -z $(cat $POWERLEVEL9K_PUBLIC_IP_FILE) ]] && refresh_ip=true + [[ -n $POWERLEVEL9K_PUBLIC_IP_NONE ]] && [[ $(cat $POWERLEVEL9K_PUBLIC_IP_FILE) =~ "$POWERLEVEL9K_PUBLIC_IP_NONE" ]] && refresh_ip=true + else + touch $POWERLEVEL9K_PUBLIC_IP_FILE && refresh_ip=true + fi + + # grab a fresh IP if needed + if [[ $refresh_ip =~ true && -w $POWERLEVEL9K_PUBLIC_IP_FILE ]]; then + # if method specified, don't use fallback methods + if [[ -n $POWERLEVEL9K_PUBLIC_IP_METHOD ]] && [[ $POWERLEVEL9K_PUBLIC_IP_METHOD =~ 'wget|curl|dig' ]]; then + local method=$POWERLEVEL9K_PUBLIC_IP_METHOD + fi + if [[ -n $method ]]; then + case $method in + 'dig') + if type -p dig >/dev/null; then + fresh_ip="$(dig +time=1 +tries=1 +short myip.opendns.com @resolver1.opendns.com 2> /dev/null)" + [[ "$fresh_ip" =~ ^\; ]] && unset fresh_ip + fi + ;; + 'curl') + if [[ -z "$fresh_ip" ]] && type -p curl >/dev/null; then + fresh_ip="$(curl --max-time 10 -w '\n' "$POWERLEVEL9K_PUBLIC_IP_HOST" 2> /dev/null)" + fi + ;; + 'wget') + if [[ -z "$fresh_ip" ]] && type -p wget >/dev/null; then + fresh_ip="$(wget -T 10 -qO- "$POWERLEVEL9K_PUBLIC_IP_HOST" 2> /dev/null)" + fi + ;; + esac + else + if type -p dig >/dev/null; then + fresh_ip="$(dig +time=1 +tries=1 +short myip.opendns.com @resolver1.opendns.com 2> /dev/null)" + [[ "$fresh_ip" =~ ^\; ]] && unset fresh_ip + fi + + if [[ -z "$fresh_ip" ]] && type -p curl >/dev/null; then + fresh_ip="$(curl --max-time 10 -w '\n' "$POWERLEVEL9K_PUBLIC_IP_HOST" 2> /dev/null)" + fi + + if [[ -z "$fresh_ip" ]] && type -p wget >/dev/null; then + fresh_ip="$(wget -T 10 -qO- "$POWERLEVEL9K_PUBLIC_IP_HOST" 2> /dev/null)" + fi + fi + + # write IP to tmp file or clear tmp file if an IP was not retrieved + [[ -n $fresh_ip ]] && echo $fresh_ip > $POWERLEVEL9K_PUBLIC_IP_FILE || echo $POWERLEVEL9K_PUBLIC_IP_NONE > $POWERLEVEL9K_PUBLIC_IP_FILE + fi + + # read public IP saved to tmp file + local public_ip=$(cat $POWERLEVEL9K_PUBLIC_IP_FILE) + + if [[ -n $public_ip ]]; then + $1_prompt_segment "$0" "$2" "$DEFAULT_COLOR" "$DEFAULT_COLOR_INVERTED" "${public_ip}" 'PUBLIC_IP_ICON' + fi +} + # Context: user@hostname (who am I and where am I) # Note that if $DEFAULT_USER is not set, this prompt segment will always print prompt_context() {