Last active
February 11, 2024 21:03
-
-
Save atanaspam/b43be6c483893bfe411764f3c6902ff7 to your computer and use it in GitHub Desktop.
ohmyzsh macos plugin merged into one file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#MIT License | |
# Copyright (c) 2009-2022 Robby Russell and contributors (https://github.com/ohmyzsh/ohmyzsh/contributors) | |
# Permission is hereby granted, free of charge, to any person obtaining a copy | |
# of this software and associated documentation files (the "Software"), to deal | |
# in the Software without restriction, including without limitation the rights | |
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
# copies of the Software, and to permit persons to whom the Software is | |
# furnished to do so, subject to the following conditions: | |
# The above copyright notice and this permission notice shall be included in all | |
# copies or substantial portions of the Software. | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
# SOFTWARE. | |
# Handle $0 according to the standard: | |
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html | |
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}" | |
0="${${(M)0:#/*}:-$PWD/$0}" | |
# Open the current directory in a Finder window | |
alias ofd='open_command $PWD' | |
# Show/hide hidden files in the Finder | |
alias showfiles="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder" | |
alias hidefiles="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder" | |
# Bluetooth restart | |
function btrestart() { | |
sudo kextunload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport | |
sudo kextload -b com.apple.iokit.BroadcomBluetoothHostControllerUSBTransport | |
} | |
function _omz_macos_get_frontmost_app() { | |
osascript 2>/dev/null <<EOF | |
tell application "System Events" | |
name of first item of (every process whose frontmost is true) | |
end tell | |
EOF | |
} | |
function tab() { | |
# Must not have trailing semicolon, for iTerm compatibility | |
local command="cd \\\"$PWD\\\"; clear" | |
(( $# > 0 )) && command="${command}; $*" | |
local the_app=$(_omz_macos_get_frontmost_app) | |
if [[ "$the_app" == 'Terminal' ]]; then | |
# Discarding stdout to quash "tab N of window id XXX" output | |
osascript >/dev/null <<EOF | |
tell application "System Events" | |
tell process "Terminal" to keystroke "t" using command down | |
end tell | |
tell application "Terminal" to do script "${command}" in front window | |
EOF | |
elif [[ "$the_app" == 'iTerm' ]]; then | |
osascript <<EOF | |
tell application "iTerm" | |
set current_terminal to current terminal | |
tell current_terminal | |
launch session "Default Session" | |
set current_session to current session | |
tell current_session | |
write text "${command}" | |
end tell | |
end tell | |
end tell | |
EOF | |
elif [[ "$the_app" == 'iTerm2' ]]; then | |
osascript <<EOF | |
tell application "iTerm2" | |
tell current window | |
create tab with default profile | |
tell current session to write text "${command}" | |
end tell | |
end tell | |
EOF | |
elif [[ "$the_app" == 'Hyper' ]]; then | |
osascript >/dev/null <<EOF | |
tell application "System Events" | |
tell process "Hyper" to keystroke "t" using command down | |
end tell | |
delay 1 | |
tell application "System Events" | |
keystroke "${command}" | |
key code 36 #(presses enter) | |
end tell | |
EOF | |
else | |
echo "$0: unsupported terminal app: $the_app" >&2 | |
return 1 | |
fi | |
} | |
function vsplit_tab() { | |
local command="cd \\\"$PWD\\\"; clear" | |
(( $# > 0 )) && command="${command}; $*" | |
local the_app=$(_omz_macos_get_frontmost_app) | |
if [[ "$the_app" == 'iTerm' ]]; then | |
osascript <<EOF | |
-- tell application "iTerm" to activate | |
tell application "System Events" | |
tell process "iTerm" | |
tell menu item "Split Vertically With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1 | |
click | |
end tell | |
end tell | |
keystroke "${command} \n" | |
end tell | |
EOF | |
elif [[ "$the_app" == 'iTerm2' ]]; then | |
osascript <<EOF | |
tell application "iTerm2" | |
tell current session of first window | |
set newSession to (split vertically with same profile) | |
tell newSession | |
write text "${command}" | |
select | |
end tell | |
end tell | |
end tell | |
EOF | |
elif [[ "$the_app" == 'Hyper' ]]; then | |
osascript >/dev/null <<EOF | |
tell application "System Events" | |
tell process "Hyper" | |
tell menu item "Split Vertically" of menu "Shell" of menu bar 1 | |
click | |
end tell | |
end tell | |
delay 1 | |
keystroke "${command} \n" | |
end tell | |
EOF | |
else | |
echo "$0: unsupported terminal app: $the_app" >&2 | |
return 1 | |
fi | |
} | |
function split_tab() { | |
local command="cd \\\"$PWD\\\"; clear" | |
(( $# > 0 )) && command="${command}; $*" | |
local the_app=$(_omz_macos_get_frontmost_app) | |
if [[ "$the_app" == 'iTerm' ]]; then | |
osascript 2>/dev/null <<EOF | |
tell application "iTerm" to activate | |
tell application "System Events" | |
tell process "iTerm" | |
tell menu item "Split Horizontally With Current Profile" of menu "Shell" of menu bar item "Shell" of menu bar 1 | |
click | |
end tell | |
end tell | |
keystroke "${command} \n" | |
end tell | |
EOF | |
elif [[ "$the_app" == 'iTerm2' ]]; then | |
osascript <<EOF | |
tell application "iTerm2" | |
tell current session of first window | |
set newSession to (split horizontally with same profile) | |
tell newSession | |
write text "${command}" | |
select | |
end tell | |
end tell | |
end tell | |
EOF | |
elif [[ "$the_app" == 'Hyper' ]]; then | |
osascript >/dev/null <<EOF | |
tell application "System Events" | |
tell process "Hyper" | |
tell menu item "Split Horizontally" of menu "Shell" of menu bar 1 | |
click | |
end tell | |
end tell | |
delay 1 | |
keystroke "${command} \n" | |
end tell | |
EOF | |
else | |
echo "$0: unsupported terminal app: $the_app" >&2 | |
return 1 | |
fi | |
} | |
function pfd() { | |
osascript 2>/dev/null <<EOF | |
tell application "Finder" | |
return POSIX path of (insertion location as alias) | |
end tell | |
EOF | |
} | |
function pfs() { | |
osascript 2>/dev/null <<EOF | |
set output to "" | |
tell application "Finder" to set the_selection to selection | |
set item_count to count the_selection | |
repeat with item_index from 1 to count the_selection | |
if item_index is less than item_count then set the_delimiter to "\n" | |
if item_index is item_count then set the_delimiter to "" | |
set output to output & ((item item_index of the_selection as alias)'s POSIX path) & the_delimiter | |
end repeat | |
EOF | |
} | |
function cdf() { | |
cd "$(pfd)" | |
} | |
function pushdf() { | |
pushd "$(pfd)" | |
} | |
function pxd() { | |
dirname $(osascript 2>/dev/null <<EOF | |
if application "Xcode" is running then | |
tell application "Xcode" | |
return path of active workspace document | |
end tell | |
end if | |
EOF | |
) | |
} | |
function cdx() { | |
cd "$(pxd)" | |
} | |
function quick-look() { | |
(( $# > 0 )) && qlmanage -p $* &>/dev/null & | |
} | |
function man-preview() { | |
[[ $# -eq 0 ]] && >&2 echo "Usage: $0 command1 [command2 ...]" && return 1 | |
local page | |
for page in "${(@f)"$(man -w $@)"}"; do | |
command mandoc -Tpdf $page | open -f -a Preview | |
done | |
} | |
compdef _man man-preview | |
function vncviewer() { | |
open vnc://$@ | |
} | |
# Remove .DS_Store files recursively in a directory, default . | |
function rmdsstore() { | |
find "${@:-.}" -type f -name .DS_Store -delete | |
} | |
# Erases purgeable disk space with 0s on the selected disk | |
function freespace(){ | |
if [[ -z "$1" ]]; then | |
echo "Usage: $0 <disk>" | |
echo "Example: $0 /dev/disk1s1" | |
echo | |
echo "Possible disks:" | |
df -h | awk 'NR == 1 || /^\/dev\/disk/' | |
return 1 | |
fi | |
echo "Cleaning purgeable files from disk: $1 ...." | |
diskutil secureErase freespace 0 $1 | |
} | |
_freespace() { | |
local -a disks | |
disks=("${(@f)"$(df | awk '/^\/dev\/disk/{ printf $1 ":"; for (i=9; i<=NF; i++) printf $i FS; print "" }')"}") | |
_describe disks disks | |
} | |
compdef _freespace freespace | |
################################################################## | |
function music itunes() { | |
local APP_NAME=Music sw_vers=$(sw_vers -productVersion 2>/dev/null) | |
autoload is-at-least | |
if [[ -z "$sw_vers" ]] || is-at-least 10.15 $sw_vers; then | |
if [[ $0 = itunes ]]; then | |
echo >&2 The itunes function name is deprecated. Use \'music\' instead. | |
return 1 | |
fi | |
else | |
APP_NAME=iTunes | |
fi | |
local opt=$1 playlist=$2 | |
(( $# > 0 )) && shift | |
case "$opt" in | |
launch|play|pause|stop|rewind|resume|quit) | |
;; | |
mute) | |
opt="set mute to true" | |
;; | |
unmute) | |
opt="set mute to false" | |
;; | |
next|previous) | |
opt="$opt track" | |
;; | |
vol) | |
local new_volume volume=$(osascript -e "tell application \"$APP_NAME\" to get sound volume") | |
if [[ $# -eq 0 ]]; then | |
echo "Current volume is ${volume}." | |
return 0 | |
fi | |
case $1 in | |
up) new_volume=$((volume + 10 < 100 ? volume + 10 : 100)) ;; | |
down) new_volume=$((volume - 10 > 0 ? volume - 10 : 0)) ;; | |
<0-100>) new_volume=$1 ;; | |
*) echo "'$1' is not valid. Expected <0-100>, up or down." | |
return 1 ;; | |
esac | |
opt="set sound volume to ${new_volume}" | |
;; | |
playlist) | |
# Inspired by: https://gist.github.com/nakajijapan/ac8b45371064ae98ea7f | |
if [[ -n "$playlist" ]]; then | |
osascript 2>/dev/null <<EOF | |
tell application "$APP_NAME" | |
set new_playlist to "$playlist" as string | |
play playlist new_playlist | |
end tell | |
EOF | |
if [[ $? -eq 0 ]]; then | |
opt="play" | |
else | |
opt="stop" | |
fi | |
else | |
opt="set allPlaylists to (get name of every playlist)" | |
fi | |
;; | |
playing|status) | |
local currenttrack currentartist state=$(osascript -e "tell application \"$APP_NAME\" to player state as string") | |
if [[ "$state" = "playing" ]]; then | |
currenttrack=$(osascript -e "tell application \"$APP_NAME\" to name of current track as string") | |
currentartist=$(osascript -e "tell application \"$APP_NAME\" to artist of current track as string") | |
echo -E "Listening to ${fg[yellow]}${currenttrack}${reset_color} by ${fg[yellow]}${currentartist}${reset_color}" | |
else | |
echo "$APP_NAME is $state" | |
fi | |
return 0 | |
;; | |
shuf|shuff|shuffle) | |
# The shuffle property of current playlist can't be changed in iTunes 12, | |
# so this workaround uses AppleScript to simulate user input instead. | |
# Defaults to toggling when no options are given. | |
# The toggle option depends on the shuffle button being visible in the Now playing area. | |
# On and off use the menu bar items. | |
local state=$1 | |
if [[ -n "$state" && "$state" != (on|off|toggle) ]]; then | |
print "Usage: $0 shuffle [on|off|toggle]. Invalid option." | |
return 1 | |
fi | |
case "$state" in | |
on|off) | |
# Inspired by: https://stackoverflow.com/a/14675583 | |
osascript >/dev/null 2>&1 <<EOF | |
tell application "System Events" to perform action "AXPress" of (menu item "${state}" of menu "Shuffle" of menu item "Shuffle" of menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" ) | |
EOF | |
return 0 | |
;; | |
toggle|*) | |
osascript >/dev/null 2>&1 <<EOF | |
tell application "System Events" to perform action "AXPress" of (button 2 of process "iTunes"'s window "iTunes"'s scroll area 1) | |
EOF | |
return 0 | |
;; | |
esac | |
;; | |
""|-h|--help) | |
echo "Usage: $0 <option>" | |
echo "option:" | |
echo "\t-h|--help\tShow this message and exit" | |
echo "\tlaunch|play|pause|stop|rewind|resume|quit" | |
echo "\tmute|unmute\tMute or unmute $APP_NAME" | |
echo "\tnext|previous\tPlay next or previous track" | |
echo "\tshuf|shuffle [on|off|toggle]\tSet shuffled playback. Default: toggle. Note: toggle doesn't support the MiniPlayer." | |
echo "\tvol [0-100|up|down]\tGet or set the volume. 0 to 100 sets the volume. 'up' / 'down' increases / decreases by 10 points. No argument displays current volume." | |
echo "\tplaying|status\tShow what song is currently playing in Music." | |
echo "\tplaylist [playlist name]\t Play specific playlist" | |
return 0 | |
;; | |
*) | |
print "Unknown option: $opt" | |
return 1 | |
;; | |
esac | |
osascript -e "tell application \"$APP_NAME\" to $opt" | |
} | |
function _music() { | |
local app_name | |
case "$words[1]" in | |
itunes) app_name="iTunes" ;; | |
music|*) app_name="Music" ;; | |
esac | |
local -a cmds subcmds | |
cmds=( | |
"launch:Launch the ${app_name} app" | |
"play:Play ${app_name}" | |
"pause:Pause ${app_name}" | |
"stop:Stop ${app_name}" | |
"rewind:Rewind ${app_name}" | |
"resume:Resume ${app_name}" | |
"quit:Quit ${app_name}" | |
"mute:Mute the ${app_name} app" | |
"unmute:Unmute the ${app_name} app" | |
"next:Skip to the next song" | |
"previous:Skip to the previous song" | |
"vol:Change the volume" | |
"playlist:Play a specific playlist" | |
{playing,status}":Show what song is currently playing" | |
{shuf,shuff,shuffle}":Set shuffle mode" | |
{-h,--help}":Show usage" | |
) | |
if (( CURRENT == 2 )); then | |
_describe 'command' cmds | |
elif (( CURRENT == 3 )); then | |
case "$words[2]" in | |
vol) subcmds=( 'up:Raise the volume' 'down:Lower the volume' ) | |
_describe 'command' subcmds ;; | |
shuf|shuff|shuffle) subcmds=('on:Switch on shuffle mode' 'off:Switch off shuffle mode' 'toggle:Toggle shuffle mode (default)') | |
_describe 'command' subcmds ;; | |
esac | |
elif (( CURRENT == 4 )); then | |
case "$words[2]" in | |
playlist) subcmds=('play:Play the playlist (default)' 'stop:Stop the playlist') | |
_describe 'command' subcmds ;; | |
esac | |
fi | |
return 0 | |
} | |
compdef _music music itunes | |
################################################################## | |
function spotify() { | |
# Copyright (c) 2012--2023 Harish Narayanan <mail@harishnarayanan.org> | |
# | |
# Contains numerous helpful contributions from Jorge Colindres, Thomas | |
# Pritchard, iLan Epstein, Gabriele Bonetti, Sean Heller, Eric Martin | |
# and Peter Fonseca. | |
# Permission is hereby granted, free of charge, to any person | |
# obtaining a copy of this software and associated documentation files | |
# (the "Software"), to deal in the Software without restriction, | |
# including without limitation the rights to use, copy, modify, merge, | |
# publish, distribute, sublicense, and/or sell copies of the Software, | |
# and to permit persons to whom the Software is furnished to do so, | |
# subject to the following conditions: | |
# The above copyright notice and this permission notice shall be | |
# included in all copies or substantial portions of the Software. | |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
# SOFTWARE. | |
USER_CONFIG_DEFAULTS="CLIENT_ID=\"\"\nCLIENT_SECRET=\"\""; | |
USER_CONFIG_FILE="${HOME}/.shpotify.cfg"; | |
if ! [[ -f "${USER_CONFIG_FILE}" ]]; then | |
touch "${USER_CONFIG_FILE}"; | |
echo -e "${USER_CONFIG_DEFAULTS}" > "${USER_CONFIG_FILE}"; | |
fi | |
source "${USER_CONFIG_FILE}"; | |
# Set the percent change in volume for vol up and vol down | |
VOL_INCREMENT=10 | |
showAPIHelp() { | |
echo; | |
echo "Connecting to Spotify's API:"; | |
echo; | |
echo " This command line application needs to connect to Spotify's API in order to"; | |
echo " find music by name. It is very likely you want this feature!"; | |
echo; | |
echo " To get this to work, you need to sign up (or in) and create an 'Application' at:"; | |
echo " https://developer.spotify.com/dashboard/create"; | |
echo; | |
echo " Once you've created an application, find the 'Client ID' and 'Client Secret'"; | |
echo " values, and enter them into your shpotify config file at '${USER_CONFIG_FILE}'"; | |
echo; | |
echo " Be sure to quote your values and don't add any extra spaces!"; | |
echo " When done, it should look like this (but with your own values):"; | |
echo ' CLIENT_ID="abc01de2fghijk345lmnop"'; | |
echo ' CLIENT_SECRET="qr6stu789vwxyz"'; | |
} | |
showHelp () { | |
echo "Usage:"; | |
echo; | |
echo " `basename $0` <command>"; | |
echo; | |
echo "Commands:"; | |
echo; | |
echo " play # Resumes playback where Spotify last left off."; | |
echo " play <song name> # Finds a song by name and plays it."; | |
echo " play album <album name> # Finds an album by name and plays it."; | |
echo " play artist <artist name> # Finds an artist by name and plays it."; | |
echo " play list <playlist name> # Finds a playlist by name and plays it."; | |
echo " play uri <uri> # Play songs from specific uri."; | |
echo; | |
echo " next # Skips to the next song in a playlist."; | |
echo " prev # Returns to the previous song in a playlist."; | |
echo " replay # Replays the current track from the beginning."; | |
echo " pos <time> # Jumps to a time (in secs) in the current song."; | |
echo " pause # Pauses (or resumes) Spotify playback."; | |
echo " stop # Stops playback."; | |
echo " quit # Stops playback and quits Spotify."; | |
echo; | |
echo " vol up # Increases the volume by 10%."; | |
echo " vol down # Decreases the volume by 10%."; | |
echo " vol <amount> # Sets the volume to an amount between 0 and 100."; | |
echo " vol [show] # Shows the current Spotify volume."; | |
echo; | |
echo " status # Shows the current player status."; | |
echo " status artist # Shows the currently playing artist."; | |
echo " status album # Shows the currently playing album."; | |
echo " status track # Shows the currently playing track."; | |
echo; | |
echo " share # Displays the current song's Spotify URL and URI." | |
echo " share url # Displays the current song's Spotify URL and copies it to the clipboard." | |
echo " share uri # Displays the current song's Spotify URI and copies it to the clipboard." | |
echo; | |
echo " toggle shuffle # Toggles shuffle playback mode."; | |
echo " toggle repeat # Toggles repeat playback mode."; | |
showAPIHelp | |
} | |
cecho(){ | |
bold=$(tput bold); | |
green=$(tput setaf 2); | |
reset=$(tput sgr0); | |
echo $bold$green"$1"$reset; | |
} | |
showArtist() { | |
echo `osascript -e 'tell application "Spotify" to artist of current track as string'`; | |
} | |
showAlbum() { | |
echo `osascript -e 'tell application "Spotify" to album of current track as string'`; | |
} | |
showTrack() { | |
echo `osascript -e 'tell application "Spotify" to name of current track as string'`; | |
} | |
showStatus () { | |
state=`osascript -e 'tell application "Spotify" to player state as string'`; | |
cecho "Spotify is currently $state."; | |
duration=`osascript -e 'tell application "Spotify" | |
set durSec to (duration of current track / 1000) as text | |
set tM to (round (durSec / 60) rounding down) as text | |
if length of ((durSec mod 60 div 1) as text) is greater than 1 then | |
set tS to (durSec mod 60 div 1) as text | |
else | |
set tS to ("0" & (durSec mod 60 div 1)) as text | |
end if | |
set myTime to tM as text & ":" & tS as text | |
end tell | |
return myTime'`; | |
position=`osascript -e 'tell application "Spotify" | |
set pos to player position | |
set nM to (round (pos / 60) rounding down) as text | |
if length of ((round (pos mod 60) rounding down) as text) is greater than 1 then | |
set nS to (round (pos mod 60) rounding down) as text | |
else | |
set nS to ("0" & (round (pos mod 60) rounding down)) as text | |
end if | |
set nowAt to nM as text & ":" & nS as text | |
end tell | |
return nowAt'`; | |
echo -e $reset"Artist: $(showArtist)\nAlbum: $(showAlbum)\nTrack: $(showTrack) \nPosition: $position / $duration"; | |
} | |
if [ $# = 0 ]; then | |
showHelp; | |
else | |
if [ ! -d /Applications/Spotify.app ] && [ ! -d $HOME/Applications/Spotify.app ]; then | |
echo "The Spotify application must be installed." | |
return 1 | |
fi | |
if [ $(osascript -e 'application "Spotify" is running') = "false" ]; then | |
osascript -e 'tell application "Spotify" to activate' || return 1 | |
sleep 2 | |
fi | |
fi | |
while [ $# -gt 0 ]; do | |
arg=$1; | |
case $arg in | |
"play" ) | |
if [ $# != 1 ]; then | |
# There are additional arguments, so find out how many | |
array=( $@ ); | |
len=${#array[@]}; | |
SPOTIFY_SEARCH_API="https://api.spotify.com/v1/search"; | |
SPOTIFY_TOKEN_URI="https://accounts.spotify.com/api/token"; | |
if [ -z "${CLIENT_ID}" ]; then | |
cecho "Invalid Client ID, please update ${USER_CONFIG_FILE}"; | |
showAPIHelp; | |
return 1; | |
fi | |
if [ -z "${CLIENT_SECRET}" ]; then | |
cecho "Invalid Client Secret, please update ${USER_CONFIG_FILE}"; | |
showAPIHelp; | |
return 1; | |
fi | |
SHPOTIFY_CREDENTIALS=$(printf "${CLIENT_ID}:${CLIENT_SECRET}" | base64 | tr -d "\n"|tr -d '\r'); | |
SPOTIFY_PLAY_URI=""; | |
getAccessToken() { | |
cecho "Connecting to Spotify's API"; | |
SPOTIFY_TOKEN_RESPONSE_DATA=$( \ | |
curl "${SPOTIFY_TOKEN_URI}" \ | |
--silent \ | |
-X "POST" \ | |
-H "Authorization: Basic ${SHPOTIFY_CREDENTIALS}" \ | |
-d "grant_type=client_credentials" \ | |
) | |
if ! [[ "${SPOTIFY_TOKEN_RESPONSE_DATA}" =~ "access_token" ]]; then | |
cecho "Authorization failed, please check ${USER_CONFG_FILE}" | |
cecho "${SPOTIFY_TOKEN_RESPONSE_DATA}" | |
showAPIHelp | |
return 1 | |
fi | |
SPOTIFY_ACCESS_TOKEN=$( \ | |
printf "${SPOTIFY_TOKEN_RESPONSE_DATA}" \ | |
| command grep -E -o '"access_token":".*",' \ | |
| sed 's/"access_token"://g' \ | |
| sed 's/"//g' \ | |
| sed 's/,.*//g' \ | |
) | |
} | |
searchAndPlay() { | |
type="$1" | |
Q="$2" | |
getAccessToken; | |
cecho "Searching ${type}s for: $Q"; | |
SPOTIFY_PLAY_URI=$( \ | |
curl -s -G $SPOTIFY_SEARCH_API \ | |
-H "Authorization: Bearer ${SPOTIFY_ACCESS_TOKEN}" \ | |
-H "Accept: application/json" \ | |
--data-urlencode "q=$Q" \ | |
-d "type=$type&limit=1&offset=0" \ | |
| command grep -E -o "spotify:$type:[a-zA-Z0-9]+" -m 1 | |
) | |
} | |
case $2 in | |
"list" ) | |
_args=${array[@]:2:$len}; | |
Q=$_args; | |
getAccessToken; | |
cecho "Searching playlists for: $Q"; | |
results=$( \ | |
curl -s -G $SPOTIFY_SEARCH_API --data-urlencode "q=$Q" -d "type=playlist&limit=10&offset=0" -H "Accept: application/json" -H "Authorization: Bearer ${SPOTIFY_ACCESS_TOKEN}" \ | |
| command grep -E -o "spotify:playlist:[a-zA-Z0-9]+" -m 10 \ | |
) | |
count=$( \ | |
echo "$results" | command grep -c "spotify:playlist" \ | |
) | |
if [ "$count" -gt 0 ]; then | |
random=$(( $RANDOM % $count)); | |
SPOTIFY_PLAY_URI=$( \ | |
echo "$results" | awk -v random="$random" '/spotify:playlist:[a-zA-Z0-9]+/{i++}i==random{print; exit}' \ | |
) | |
fi;; | |
"album" | "artist" | "track" ) | |
_args=${array[@]:2:$len}; | |
searchAndPlay $2 "$_args";; | |
"uri" ) | |
SPOTIFY_PLAY_URI=${array[@]:2:$len};; | |
* ) | |
_args=${array[@]:1:$len}; | |
searchAndPlay track "$_args";; | |
esac | |
if [ "$SPOTIFY_PLAY_URI" != "" ]; then | |
if [ "$2" = "uri" ]; then | |
cecho "Playing Spotify URI: $SPOTIFY_PLAY_URI"; | |
else | |
cecho "Playing ($Q Search) -> Spotify URI: $SPOTIFY_PLAY_URI"; | |
fi | |
osascript -e "tell application \"Spotify\" to play track \"$SPOTIFY_PLAY_URI\""; | |
else | |
cecho "No results when searching for $Q"; | |
fi | |
else | |
# play is the only param | |
cecho "Playing Spotify."; | |
osascript -e 'tell application "Spotify" to play'; | |
fi | |
break ;; | |
"pause" ) | |
state=`osascript -e 'tell application "Spotify" to player state as string'`; | |
if [ $state = "playing" ]; then | |
cecho "Pausing Spotify."; | |
else | |
cecho "Playing Spotify."; | |
fi | |
osascript -e 'tell application "Spotify" to playpause'; | |
break ;; | |
"stop" ) | |
state=`osascript -e 'tell application "Spotify" to player state as string'`; | |
if [ $state = "playing" ]; then | |
cecho "Pausing Spotify."; | |
osascript -e 'tell application "Spotify" to playpause'; | |
else | |
cecho "Spotify is already stopped." | |
fi | |
break ;; | |
"quit" ) cecho "Quitting Spotify."; | |
osascript -e 'tell application "Spotify" to quit'; | |
break ;; | |
"next" ) cecho "Going to next track." ; | |
osascript -e 'tell application "Spotify" to next track'; | |
showStatus; | |
break ;; | |
"prev" ) cecho "Going to previous track."; | |
osascript -e ' | |
tell application "Spotify" | |
set player position to 0 | |
previous track | |
end tell'; | |
showStatus; | |
break ;; | |
"replay" ) cecho "Replaying current track."; | |
osascript -e 'tell application "Spotify" to set player position to 0' | |
break ;; | |
"vol" ) | |
vol=`osascript -e 'tell application "Spotify" to sound volume as integer'`; | |
if [[ $2 = "" || $2 = "show" ]]; then | |
cecho "Current Spotify volume level is $vol."; | |
break ; | |
elif [ "$2" = "up" ]; then | |
if [ $vol -le $(( 100-$VOL_INCREMENT )) ]; then | |
newvol=$(( vol+$VOL_INCREMENT )); | |
cecho "Increasing Spotify volume to $newvol."; | |
else | |
newvol=100; | |
cecho "Spotify volume level is at max."; | |
fi | |
elif [ "$2" = "down" ]; then | |
if [ $vol -ge $(( $VOL_INCREMENT )) ]; then | |
newvol=$(( vol-$VOL_INCREMENT )); | |
cecho "Reducing Spotify volume to $newvol."; | |
else | |
newvol=0; | |
cecho "Spotify volume level is at min."; | |
fi | |
elif [[ $2 =~ ^[0-9]+$ ]] && [[ $2 -ge 0 && $2 -le 100 ]]; then | |
newvol=$2; | |
cecho "Setting Spotify volume level to $newvol"; | |
else | |
echo "Improper use of 'vol' command" | |
echo "The 'vol' command should be used as follows:" | |
echo " vol up # Increases the volume by $VOL_INCREMENT%."; | |
echo " vol down # Decreases the volume by $VOL_INCREMENT%."; | |
echo " vol [amount] # Sets the volume to an amount between 0 and 100."; | |
echo " vol # Shows the current Spotify volume."; | |
return 1; | |
fi | |
osascript -e "tell application \"Spotify\" to set sound volume to $newvol"; | |
break ;; | |
"toggle" ) | |
if [ "$2" = "shuffle" ]; then | |
osascript -e 'tell application "Spotify" to set shuffling to not shuffling'; | |
curr=`osascript -e 'tell application "Spotify" to shuffling'`; | |
cecho "Spotify shuffling set to $curr"; | |
elif [ "$2" = "repeat" ]; then | |
osascript -e 'tell application "Spotify" to set repeating to not repeating'; | |
curr=`osascript -e 'tell application "Spotify" to repeating'`; | |
cecho "Spotify repeating set to $curr"; | |
fi | |
break ;; | |
"status" ) | |
if [ $# != 1 ]; then | |
# There are additional arguments, a status subcommand | |
case $2 in | |
"artist" ) | |
showArtist; | |
break ;; | |
"album" ) | |
showAlbum; | |
break ;; | |
"track" ) | |
showTrack; | |
break ;; | |
esac | |
else | |
# status is the only param | |
showStatus; | |
fi | |
break ;; | |
"info" ) | |
info=`osascript -e 'tell application "Spotify" | |
set durSec to (duration of current track / 1000) | |
set tM to (round (durSec / 60) rounding down) as text | |
if length of ((durSec mod 60 div 1) as text) is greater than 1 then | |
set tS to (durSec mod 60 div 1) as text | |
else | |
set tS to ("0" & (durSec mod 60 div 1)) as text | |
end if | |
set myTime to tM as text & "min " & tS as text & "s" | |
set pos to player position | |
set nM to (round (pos / 60) rounding down) as text | |
if length of ((round (pos mod 60) rounding down) as text) is greater than 1 then | |
set nS to (round (pos mod 60) rounding down) as text | |
else | |
set nS to ("0" & (round (pos mod 60) rounding down)) as text | |
end if | |
set nowAt to nM as text & "min " & nS as text & "s" | |
set info to "" & "\nArtist: " & artist of current track | |
set info to info & "\nTrack: " & name of current track | |
set info to info & "\nAlbum Artist: " & album artist of current track | |
set info to info & "\nAlbum: " & album of current track | |
set info to info & "\nSeconds: " & durSec | |
set info to info & "\nSeconds played: " & pos | |
set info to info & "\nDuration: " & mytime | |
set info to info & "\nNow at: " & nowAt | |
set info to info & "\nPlayed Count: " & played count of current track | |
set info to info & "\nTrack Number: " & track number of current track | |
set info to info & "\nPopularity: " & popularity of current track | |
set info to info & "\nId: " & id of current track | |
set info to info & "\nSpotify URL: " & spotify url of current track | |
set info to info & "\nArtwork: " & artwork url of current track | |
set info to info & "\nPlayer: " & player state | |
set info to info & "\nVolume: " & sound volume | |
set info to info & "\nShuffle: " & shuffling | |
set info to info & "\nRepeating: " & repeating | |
end tell | |
return info'` | |
cecho "$info"; | |
break ;; | |
"share" ) | |
uri=`osascript -e 'tell application "Spotify" to spotify url of current track'`; | |
remove='spotify:track:' | |
url=${uri#$remove} | |
url="https://open.spotify.com/track/$url" | |
if [ "$2" = "" ]; then | |
cecho "Spotify URL: $url" | |
cecho "Spotify URI: $uri" | |
echo "To copy the URL or URI to your clipboard, use:" | |
echo "\`spotify share url\` or" | |
echo "\`spotify share uri\` respectively." | |
elif [ "$2" = "url" ]; then | |
cecho "Spotify URL: $url"; | |
echo -n $url | pbcopy | |
elif [ "$2" = "uri" ]; then | |
cecho "Spotify URI: $uri"; | |
echo -n $uri | pbcopy | |
fi | |
break ;; | |
"pos" ) | |
cecho "Adjusting Spotify play position." | |
osascript -e "tell application \"Spotify\" to set player position to $2"; | |
break ;; | |
"help" ) | |
showHelp; | |
break ;; | |
* ) | |
showHelp; | |
return 1; | |
esac | |
done | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment