How can I edit itunes song lyrics from the terminal? - applescript

I can get the lyrics using:
osascript -e '''tell application "iTunes" to lyrics of the current track'''
but how can I set them?
I'm trying to make corrections to the current lyrics using my text editor.

osascript -e 'tell application "iTunes" to set lyrics of current track to "hoho"'
Thanks to regulus6633
And as a cli script
#!/usr/bin/env osascript
-- update_lyrics <track persisten ID> <lyric file>
on run argv
try
set trackPersistentID to item 1 of argv
set lyricsFile to item 2 of argv
-- use awk to strip leading empty lines
set cmdString to "cat " & lyricsFile & " | awk 'p;/^#+$/{p=1}'"
set newLyrics to do shell script cmdString
on error
return "update_lyrics <trackID> <lyricsFile>"
end try
tell application "iTunes"
set mainLibrary to library playlist 1
try
set foundTrack to (first file track of mainLibrary whose persistent ID = trackPersistentID)
set lyrics of foundTrack to newLyrics
on error err_mess
log err_mess
end try
end tell
end run

Related

How can I retrieve the contents of an iTerm session with Applescript?

I am working on an Applescript to make logging into 2-factor authentication domains a little easier. Long story short, instead of using delays and sending text, I'd like to poll the contents of the current session and enter usernames/passwords/tokencodes as soon as the prompt for them appears. Luckily, iTerm v3.X has a bunch of cool AppleScript stuff:
https://www.iterm2.com/documentation-scripting.html
But I'm having a lot of trouble reading the contents of the terminal session. Here's what I've got so far:
on run
# Start or activate iTerm
tell application "iTerm"
activate
tell the first window
# Create a new tab, which will create a new session inside
set newTab to (create tab with default profile)
tell newTab
# Since we just created the tab, there should only be one session right now.
repeat with aSession in sessions
tell aSession
delay 3
#set myvar to (tty)
#set myvar to (text)
set myvar to (contents)
#do shell script "echo " & myvar & " >> ~/some_file.txt"
#write text (contents)
end tell
end repeat
end tell
end tell
end tell
return myvar
end run
As you can see, I've tried several different things, "contents" seemed like the most promising solution according to the documentation, but crazy stuff comes out, like this:
session id "0986F3BD-D2AF-480F-B517-AB7A43B2A0C4" of tab 3 of window id "window-1" of application "iTerm"
What is this stuff? Why don't I see what I expect, which is something like this:
Last login: Fri Jun 10 18:18:22 on ttys001
me#MacBook-Pro:~|⇒
I got this to work for a good 3-5 times in a row, but as soon as I edited my script again, it started returning that session ID stuff. At that point, I decided that applescript or iTerm's applescript API is just too opaque. I hammered out a workaround that actually seems to work pretty well, here it is for anyone who comes after me:
on grepCountsFor(searchString)
set terminalContents to my getContents()
log "terminal contents: " & terminalContents
set oneline to ""
set allRecords to paragraphs of terminalContents
repeat with aRecord in allRecords
if length of aRecord is greater than 0 then
set variable to aRecord
log "variable: " & variable
set oneline to oneline & variable
end if
end repeat
log "oneline: " & oneline
set command to "echo \"" & oneline & "\" | grep -o \"" & searchString & "\" | wc -l"
log "command: " & command
set counts to do shell script command
return counts as number
end grepCountsFor
on getContents()
#iTerm needs to be in the front for key presses to register.
my waitForWindow("iTerm")
# Mush buttons in the app
tell application "System Events"
keystroke "a" using command down
keystroke "c" using command down
set sessionContents to do shell script "pbpaste"
end tell
return sessionContents
end getContents
# Waits for a window to come into focus
on waitForWindow(appName)
# Poll until "appName" is the active window
set activeApp to "noApp"
repeat until activeApp is appName
set activeApp to (path to frontmost application as Unicode text)
# If the active app name does not contain the target,
# try to activate it again.
if appName is not in activeApp then
tell application appName
activate
end tell
else
# Done
exit repeat
end if
delay 0.1
end repeat
end waitForWindow

How to indent applescript when running in bash script?

osascript -e "set x to 3"
osascript -e "if x is 5 then"
osascript -e " tell application \"System Events\" to keystroke return"
osascript -e "end if"
The output i get
14:14: syntax error: Expected end of line but found end of script. (-2741)
0:6: syntax error: A “if” can’t go after this “end”. (-2740)
Can't see whats wrong with the script. Might be some issue with indentation. Anyone used osascript inside bash files ?
Put all your applescript lines together. This way:
osascript -e "set x to 3
if x is 5 then
tell application \"System Events\" to keystroke return
end if"
Additionally, you can create a file like the following with all your applescript code:
#!/usr/bin/osascript
set x to 3
if x is 5 then
tell application "System Events" to keystroke return
end if
I find this way easiest in respect of quoting and double-quoting and escaping, and using bash variables in the osascript:
#!/bin/bash
# Set bash variable to 3, then use it in osascript
count=3
osascript <<EOF
beep $count
tell application "Safari"
set theURL to URL of current tab of window 1
end tell
EOF
# Continue in bash
echo done

End Service if already running on Mac

I'm trying to create an Automator service that allows me to speak selected text.
I want to be able to use a keyboard shortcut, however, I also want to use a keyboard shortcut to end the service before it finishes.
I cannot figure out how to make the service stop once started running.
Here is my applescript code in Automator:
on run {input, parameters}
say input using "Alex" speaking rate 400
return input
end run
I know you can speak text in system prefs. But it maxes out at 300 wpm. I need this to do more than 300. Hence the Automator service.
Thanks for your help.
Another way should be to start saying nothing.
say "" stopping current speech true
If executed it will stop the current say output.
It's possible by getting the pid of the service, just write the pid to a temporary file.
When you want to stop the speaking, the script get the pid in the temporary file to quit this process ID.
on run {input, parameters}
set tFile to POSIX path of (path to temporary items as text) & "__auto_Runner_Speak_text__last_Pid__.txt"
try
set lastPid to word 1 of (read tFile) -- get the pid of the last speak text
if lastPid is not "" then
set tPids to words of (do shell script "/bin/ps -Axcro pid,command | sed -n '/Automator Runner/s/^ \\([0-9]*\\).*/\\1/p'")
if lastPid is in tPids then
do shell script "echo '' > " & (quoted form of tFile) & ";/bin/kill " & lastPid & " > /dev/null 2>&1 &" -- empty the file and stop the speaking
return -- quit this service
end if
end if
end try
do shell script "echo $PPID > " & quoted form of tFile -- write the PID of this workflow to the temp file
say input using "Alex" speaking rate 400
do shell script "echo '' > " & quoted form of tFile -- remove the PID of this workflow in the temp file
end run
Basically you'll have to kill the speech synthesis process...
try
set thePID to word 1 of (do shell script "/bin/ps -Axcro pid,command | grep speechsynthesis")
do shell script "kill -15 " & thePID
end try

how to rename a folder in applescript without getting -10006 error

after an automator script that asks a user to choose a folder i have this applescript-
on run {input, parameters}
try
set theFolder to input
tell application "Finder" to set name of theFolder to "test"
on error e number n
set theLine to (do shell script "date +'%Y-%m-%d %H:%M:%S'" as string) & " " & "OOPs: " & e & " " & n
do shell script "echo " & theLine & " >> ~/Library/Logs/AudioModdeer-events.log"
end try
return input
end run
my log gives me the following error-
2013-09-03 16:50:56 OOPs: AppleEvent handler failed. -10000
2013-09-03 16:51:28 OOPs: Can’t set name of {alias Macintosh HD:Users:Audio:Music:Ableton:User Library:Samples:Samples:} to test. -10006
You have to reference one item from the Input list...
set theFolder to first item of input
I'm pretty much a newbie to AppleScript, but I found out today that the following works, too:
move contents of <oldFolder> to make new folder at alias <currentLocation> with properties {name:"<newName>"}
Hope this works for you, too.

Why does this preinstall script just partly run?

I use PackageMaker to create an installation package. The following is my preinstall script to be called by Installer:
#!/bin/sh
/usr/bin/osascript <<EOF
tell application "System Events"
if exists (application process "Dictionary") then
tell application "Dictionary" to quit
end if
end tell
set theFolder to (path to library folder as text) & "Dictionaries:"
set fileNames to {"dict1.dictionary", "dict2.dictionary", "dict3.dictionary", "dict_n.dictionary"}
set dict to {}
repeat with aFile in fileNames
tell application "Finder"
if exists file (theFolder & aFile as text) then set end of dict to aFile & return
end tell
end repeat
try
tell application "System Events"
if dict ≠ {} then display alert "You have XYZ installed" message "Choose 'Upgrade' to install the new version or 'Cancel' if you want to stay with the current version." & return & dict buttons {"Cancel", "Upgrade"} default button "Upgrade"
if the button returned of the result is "Cancel" then
tell current application
set app_name to "Installer"
set the_pid to (do shell script "ps ax | grep " & (quoted form of app_name) & " | grep -v grep | awk '{print $1}'")
if the_pid is not "" then do shell script ("kill -9 " & the_pid)
end tell
end if
end tell
end try
EOF
This script works well in AppleScript Editor as well as in Terminal, i.e. it closes Dictionary app if it's running and force quits Installer if user chooses Cancel.
However, when called during the installation process, it just partly runs: it closes Dictionary app but bypasses force quitting Installer when Cancel button is chosen. Note that I have done chmod 755 the preinstall file.
What have I missed? What have I done wrongly? Can you please give a little help?
Thank you very much.

Resources