Applescript errors when reading user input (password) that contains escape characters - applescript

Here in my department we use a samba shares server as storage space for employees. For the employees that use Apple machines, we are trying to use an AppleScript application that will obtain the users username and password, then using them to mount the drives. The problem arises when a user enters a password that contains escape characters; for example abcdefg/. Here is the dialog code that sets the variables for username and password:
set user_name_dialog to display dialog "Enter your User ID: " default answer "" buttons {"Next"} default button "Next"
set user_name to text returned of user_name_dialog
--this line prompts the user for their password and sets the returned result as the variable "user_password"
set user_password_dialog to display dialog "Enter your Password. " & return & return & "WARNING: If you are running Panther (MacOS 10.3), your input will be displayed in this box as clear text." default answer "" buttons {"Next"} default button "Next" with hidden answer
set user_password to text returned of user_password_dialog
And here is the shell script line that is ran for mounting a drive:
do shell script "mount -t smbfs //" & user_name & ":" & user_password & "#SOME IP ADDRESS/SOME FOLDER/ /SOME MOUNT POINT/" & user_name & "-SOME SHARE"
Now I know from a little research that it could be something as simple as an extra pair of quotes somewhere, I've even tried
quoted form of
with no luck whatsoever. The error message I get when entering a string with a escape character is as such:
error "mount_smbfs: server connection failed: No route to host" number 68
Any help would be GREATLY appreciated as my experience with AppleScript is very limited.

NOTE: the following is just a guess. I did not test any of it.
I don't believe it is an "escape characters" problem. The forward slash is not an escape character. The backward slash is. The problem is probably that the smbfs command interprets the forward slash as a divisor for path variables, and that's causing the error. So the question becomes... how can you avoid the conflict between the forward slash and the smbfs command?
I would try escaping the forward slash when you pass the command to the shell. Note that applescript also uses a backslash as an escape character so to pass an escape character to the shell you will have to escape the escape. So write a custom handler to pass your passwords through to perform that escape process for you.
So if this is your password, "abcdefg/" then try passing it as "abcdefg\\/" (note the double backslash). As mentioned you can write a custom handler to check your password for the "/" character, and if found then insert "\\" in front of it. But before writing that handler try the proposed solution manually to see if it solves your problem.
set pword to "/abc/defg/"
escapeSlash(pword)
on escapeSlash(x)
if x contains "/" then
set AppleScript's text item delimiters to "/"
set textItems to text items of x
set AppleScript's text item delimiters to "\\/"
set x to textItems as text
set AppleScript's text item delimiters to ""
end if
return x
end escapeSlash

Related

How do I prevent zsh from replacing "%5D" with "]"?

[EDIT] Solved.
The actual issue was a typo in one of the handler variables, and not a zsh issue, as I initially thought.
I am trying to prevent zsh from replacing the code "%5D" for the ] right square bracket with the actual character "]".
For my purposes - calling the last.fm API via curl in shell script, to get info about a track from Apple Music - it needs to stay as "%5D", because otherwise the API doesn't recognise it.
I have tried escaping the "%5D" with backslashes or a second "%" but that doesn't work, it still gets replaced with "]"
Here's an example of what I'm trying to do and what is not working:
The original string of the track's name:
"YESTODAY (Extended Version) [Bonus Track]"
How it needs to be spelled for the API to work:
"YESTODAY+(Extended+Version)+%5BBonus+Track%5D"
The whitespaces get replaced with "+" by my AppleScript handler.
The left [ stays as "%5B" (I guess because it is immediately followed by more letters and therefore zsh cannot recognise it as code and replace it).
The right ] is generally the last character of the track string, not followed by anything and thus "%5D" is recognised by zsh and written as "]" .
How do I fix this?
Any help is greatly appreciated :)
For reference:
The part of the AppleScript that is supposed to replace the "[ ]" with code.
(This is obviously not the complete script). If you run this, it replaces the [ ] correctly. The issue only arises once the entire API call is made with do shell script curl_command because of zsh interpreting the code.
set trackreplace to "YESTODAY (Extended Version) [Bonus Track]"
if trackreplace contains "[" then
set trackreplace to replaceChars("[", "%5B", trackreplace)
end if
if trackreplace contains "]" then
set trackeplace to replaceChars("]", "%5D", trackreplace)
end if
on replaceChars(find, replace, subject)
set savedelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to find
set subject to text items of subject
set AppleScript's text item delimiters to replace
set subject to (subject as string)
set AppleScript's text item delimiters to savedelims
return subject
end replaceChars
It was not a zsh issue but actually just a typo in one of the handler variables (trackeplace instead of trackreplace), as pointed out by #GordonDavisson

how can I fix this apple script shell script combo to accept quotation marks?

First, sorry that its a long post, I tried to explain it as best I could and be succinct. Read it at your own pace if you're bored or something, I'll be responsive to any replies.
Importantly I want to say that I know nothing about scripting, and (not trying to sound like a jerk) don't want to learn it myself because my brain is too fried to learn something that requires decent memory, organization or concentration ability due to an undisclosed reason, I just want to fix the script.
I'm not an idiot though, I can run terminal or script editor and follow instructions and plug things in and give error results.
The script is run from script editor and involves ifttt, webhooks, spotify, applescript and shellscript, but the script is the important part in this, because it's broken.
Basically the script is adding current playing spotify songs to predefined playlists, it works great, BUT if the song title has a quotation mark in it, single or double, it will give error messages (different ones in each situation) and not add those songs, and many songs have those.
So it renders it essentially useless to me, as the value of it to me is to control spotify from outside the app, like if I'm watching twitch.
I tried asking on reddit, hiring a freelancer from freelancer website, and apple support forums, people tried and offered a few suggestions but they didn't work so this is one of my last websites to try, it's very important to me that this script works, because I can't do proper music discovery without it, but it's broken as is.
For background, this is the tutorial I initially followed step by step to get the script working (for songs without quotes in the title).
https://medium.com/#l.krobbach/how-to-automatically-add-your-current-playing-song-to-a-spotify-playlist-on-mac-using-d87a0315475d
This is the script I run in script terminal
if application "Spotify" is running then
tell application "Spotify"
if player state is playing then
set ArtistName to (get artist of current track)
set SongName to (get name of current track)
end if
end tell
end if
do shell script " curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"" & songname & "\",\"value2\":\"" & ArtistName & "\"}' https://maker.ifttt.com/trigger/add/with/key/REPLACEME"
I put my webhooks key in place of REPLACEME when I actually run it, but I was told not to share that online.
If I run it on a song with 1 quote marks ' it says in script editor result
error "sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file" number 2
If I run it on a song with 2 quote marks " it says
"Bad Request"
If I run it on song without quote marks it is a success and adds the song to playlist and says
"Congratulations! You've fired the add event"
2 people from different sites have independently suggested I replace the shellscript with this instead, something about quoted form of
do shell script " curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"" & quoted form of songname & "\",\"value2\":\"" & quoted form of ArtistName & "\"}' https://maker.ifttt.com/trigger/add/with/key/REPLACEME"
It doesn't work though
1 quote fail is
error "sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file" number 2
2 quote fail is
error "sh: -c: line 0: syntax error near unexpected token (' sh: -c: line 0: curl -X POST -H "Content-Type: application/json" -d '{"value1":"'Great Fairy Fountain (From "The Legend of Zelda: Ocarina of Time") - Piano Version'","value2":"'Koji Kondo'"}' https://maker.ifttt.com/trigger/add/with/key/REPLACEME'" number 2
(song info is just whatever I was playing while testing).
Someone also suggested
set myJSONdata to "{\"value1\":\"" & SongName & "\",\"value2\":\"" & ArtistName & "\"}"
do shell script "echo curl -X POST -H \"Content-Type: application/json\" -d " & quoted form of myJSONdata & " hhttps://maker.ifttt.com/trigger/add/with/key/REPLACEME"
I didn't know exactly where to plug that in, but it gave error messages as well
"curl -X POST -H Content-Type: application/json -d {"value1":"Orphée Suite - 6. Orphee's Return","value2":"Philip Glass"} hhttps://maker.ifttt.com/trigger/add/with/key/REPLACEME"
or
error "The variable SongName is not defined." number -2753 from "SongName"
Depending on where I placed it in the script, he didn't reply to me after he suggested it so I don't know if I screwed that up.
The poor guy who spent hours trying for me on freelancer tried, but he didn't have a mac and wasn't experienced in applescript, but he said the applescript part was the problem not the shellscript, after suggesting the quoted form and it didn't work, he tried
if application "Spotify" is running then
tell application "Spotify"
if player state is playing then
set ArtistName to (get artist of current track)
set SongName to (get name of current track)
end if
end tell
end if
set delim to "\""
set {myTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {delim}}
set myList to text items of SongName
set AppleScript's text item delimiters to myTID
set listSize to count of myList
set counter = 0
repeat with myItem in myList
if counter < listSize
set SongName to SongName & delim
end if
end repeat
do shell script " curl -X POST -H \"Content-Type: application/json\" -d '{\"value1\":\"" & songname & "\",\"value2\":\"" & ArtistName & "\"}' https://maker.ifttt.com/trigger/add/with/key/REPLACEME"
It gave error
syntax error, a end of line can't go after this number, then it highlights set counter = 0 line in the script.
I don't really want to try freelancer again because I don't like the pressure of milestone payments deadlines and hiring people to work for me when I am so inexperienced in scripting to discuss it with them, I prefer to take it slowly on forums.
So that's all the info I have, any help is greatly appreciated, I will respond and try any suggestions, I can reimburse to someones paypal who gets it to work for time spent if they desire so, thank you.
Try to add the quotes with quoted form of and escape the double quotes explicitly
if application "Spotify" is not running then return
tell application "Spotify"
if player state is not playing then return
set ArtistName to (get artist of current track)
set SongName to (get name of current track)
end tell
set json to quoted form of ("{\"value1\":" & quote & escapeDoubleQuotes(SongName) & quote & ",\"value2\":" & quote & escapeDoubleQuotes(ArtistName) & quote & "}")
do shell script " curl -X POST -H \"Content-Type: application/json\" -d" & space & json & space & "https://maker.ifttt.com/trigger/add/with/key/REPLACEME"
on escapeDoubleQuotes(theString)
set {TID, text item delimiters} to {text item delimiters, quote}
set textItems to text items of theString
set text item delimiters to "\\\""
set quotedString to textItems as text
set text item delimiters to TID
return quotedString
end escapeDoubleQuotes

Applescript to remove all text not between two strings

I'm trying to make a script that displays a dialog of the current iTunes Top 20. How I intend to do this is get the html code from the top 100 website and then extract for text between two strings to get the name of the song. For the first song, this is extremely successful.
However, it only works for the first song each time. The only way I can think of to fix this is rather then get everything between the two strings, I could delete everything not between them. This would hopefully then give me all the song names as a string.
Does anyone know how to do this?
Get the HTML:
set curlcommand to "curl https://www.apple.com/itunes/charts/songs/"
set html to (do shell script curlcommand)
Get the song name:
set AppleScript's text item delimiters to "width=\"100\" height=\"100\" alt=\""
set theText to item 2 of every text item of html
set AppleScript's text item delimiters to "\"></a>"
set theText to item 1 of every text item of theText
set AppleScript's text item delimiters to ""
You could use the shell to get a list with all song names line by line (this is not a AppleScript list).
set charts to (do shell script "
curl -s 'https://www.apple.com/itunes/charts/songs/'| tr '\"' '\n' |awk '/^ alt=$/ {getline;print}'")
tr '\"' '\n' substitutes the double quotes with new lines (tr manual page)
awk '/^ alt=$/ {getline;print}' prints the line after the line alt= where the song name is written (awk manual page)

How to select line in AppleScript

I'm trying to figure out how to use Text Item Delimiters on a long line of text that is in a log file.
Within the log of information there is always a constant phrase that i'm searching for which leads me to the line of text. I'm getting to the line I want by searching for "[Constant]", for example.
The problem I'm having is that I can't select the whole line to perform a Delimiter. Below is a very basic example of what the log looks like.
qwertyuiop
mnbvcxza
oqeryuiiop
[Constant] 1234567890123456-098765432109876-8765432118976543
odgnsgnsanfadf
joiergjdfmgadfs
Any advice would be appreciated.
So far I'm using:
repeat 16 times
key code 124 using (shift down)
end repeat
Which does the job fine but it is clunky.
An easy way to find a line of text containing a specific string is the shell command grep.
set theConstant to "Constant"
set theText to "qwertyuiop
mnbvcxza
oqeryuiiop
Constant 1234567890123456-098765432109876-8765432118976543
odgnsgnsanfadf
joiergjdfmgadfs"
set foundLine to do shell script "echo " & quoted form of theText & " | tr '\\r' '\\n' | grep " & quoted form of theConstant
the tr part to replace return (0x0d) characters with linefeed (0x0a) characters is necessary to conform to the shell line separator requirements.
If the constant contains special characters it's a bit more complicated, because you have to escape the characters before passing them to the shell.
set theConstant to "\\[Constant\\]"
set theText to "qwertyuiop
mnbvcxza
oqeryuiiop
[Constant] 1234567890123456-098765432109876-8765432118976543
odgnsgnsanfadf
joiergjdfmgadfs"
set foundLine to do shell script "echo " & quoted form of theText & " | tr '\\r' '\\n' | grep " & quoted form of theConstant
If you want to read the text from a file on disk you can use this
set logFile to (path to library folder from user domain as text) & "Logs:myLogFile.log"
set theText to read file logFile as «class utf8»
Your question is puzzling. Do you want to parse a text/log file or a script to work with the GUI of some app? Because that is what your code suggests...
If you want to parse a log file, which is easier, you can use the good old Unix tools OSX comes with. You can use them from inside Applescript like this...
set logfile to "/some/path/file.log"
# Quote the string in case it contains spaces... or add single quotes above...
set qlogfile to quoted form of logfile
# Prepare the shell command to run
set cmd to "grep '^\\[Constant]' " & qlogfile & " | cut -c 12- | tr '-' '\\n'"
# Run it and capture the output
try
set cmdoutput to (do shell script cmd)
on error
# Oh no, command errored. Best we do something there
end try
The result looks like this...
tell current application
do shell script "grep '^\\[Constant]' '/some/path/file.log' | cut -c 12- | tr '-' '\\n'"
--> "1234567890123456
098765432109876
8765432118976543"
end tell
Result:
"1234567890123456
098765432109876
8765432118976543"
So to break it down the shell commands are,
grep ... | will read the contents of the file and select all lines that start ^ with the text [Constant] and pass what it finds | on to the next command
cut cuts out the characters from position 12 until the end - of the line
tr replaced any character - with \n which is the code for newline in unix.
The \\ you see are due to having it executed from inside Applescript. You only need on if you run it inside Terminal.
If you care to know the contents of one line from the other, then remove the last command | tr '-' '\\n' and it will return
Result:
"1234567890123456-098765432109876-8765432118976543"

Script to convert lower case characters into upper case is working differently as service action

I am trying a simple script as a service action in automator which performs this function:
Receives selected text in any application and replaces selected text
with the text containing capital letters
So I used this script:
on run {input, parameters}
set upperCaseString to ""
repeat with i in input
if (ASCII number i) > 96 and (ASCII number i) < 123 then
set upperCaseString to upperCaseString & (ASCII character ((ASCII number i) - 32))
else
set upperCaseString to upperCaseString & (ASCII character (ASCII number i))
end if
end repeat
return upperCaseString
end run
But I found this problem:
It was returning first letter of input as an upper case letter, eg.
input - lowercasetext, output - L, whereas the expected output was -
LOWERCASETEXT.
To check the problem I added this line of code in repeat loop:
display dialog i
and found that it is displaying complete text in place of single character at a time ,ie. in place of displaying l.. o.. w.. in lowercasetext it is displaying lowercasetext at once.
Can anyone suggest me why is it bugging me as service action while it is working fine in Apple Script Editor?
This works for a lot of languages:
on toUpper(s)
tell AppleScript to return do shell script "shopt -u xpg_echo; export LANG='" & user locale of (system info) & ".UTF-8'; echo " & quoted form of s & " | tr [:lower:] [:upper:]"
end toUpper
on toLower(s)
tell AppleScript to return do shell script "shopt -u xpg_echo; export LANG='" & user locale of (system info) & ".UTF-8'; echo " & quoted form of s & " | tr [:upper:] [:lower:]"
end toLower
When I run your script, I get the correct result. But one thing you may want to do is to explicitly coerce your result to text. The easiest way to do that would be at the end:
return upperCaseString as text
That may or may not do it for you, but you'll avoid a lot of frustration if you explicitly coerce data when there is a possibility of ambiguity.
Another (faster) way is to leverage the Unix tr (translate) command the via do shell script:
set upperCaseString to ¬
(do shell script ("echo " & input & " | tr a-z A-Z;"))
That's enough for 'English' language, but you can also add diacritical translation, like so
set upperCaseString to ¬
(do shell script ("echo " & input & " | tr a-zäáà A-ZÄÁÀ;"))
tr will translate anything to anything, so you can add any characters you may encounter and what you'd like them to translate to. A 'leet-speak' translator comes to mind.
You will get the same result in the AppleScript Editor if the input variable is set to a list. The input parameter of an Automator action is also a list, so your comparison isn't doing what you think. Note that text id's have obsoleted ASCII character and ASCII number commands - see the 10.5 AppleScript Release notes.
#Matt Strange:
You could also try:
set upperCaseString to ¬
do shell script "echo " & input & " | tr [:lower:] [:upper:]"
If you run 'man tr' on 'OS X 10.10' you may see that the character classes [:lower:] and [:upper:] should be used instead of explicit character ranges like 'a-z' or 'A-Z', since these may not produce correct results as it is explained there, on the manual page.

Resources