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)
Related
I'm splitting a string using osascript (was working this way, not with bash), and assigning the resulting array to a bash variable, and continuing with my bash script. I'm doing it like so:
tempArrayApplications=$(osascript >/dev/null <<EOF
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to "/"
set theArray to every text item of "$noSplitString"
set AppleScript's text item delimiters to oldDelimiters
return theArray
EOF)
However, the command line returns the error that it went to the end of the file without finding the matching ')'. However, when I don't assign a bash variable to the osascript output, everything works fine, so I know it's not a problem with the AppleScript section. I ran shellcheck, and it doesn't detect any errors, and the other solutions seem to be related to an unclosed quote or unescaped character, but I don't seem to have that problem. Clearly it's due to trying to assign it to a bash variable, but for the life of me I don't know what I'm doing wrong. Thanks for the help.
Have you paused to consider that you're taking a bash variable ($noSplitString); inserting this into an AppleScript that splits the text using / as the delimiter; executing this AppleScript inside a bash command (osascript); then storing its output (which actually gets destroyed) in another bash variable ($tempArrayApplications)...?
My inclination would be to remove the AppleScript altogether (3 out of its 5 lines are redundant, anyway), and create the array from the string within bash.
So, given this:
noSplitString="item 1/item 2/item 3"
Then simply do this:
IFS='/'
tempArrayApplications=($noSplitString)
Now $tempArrayApplications will be an array with three items, starting at index 0 and ending at index 2. You can echo a specific element in the array like this:
echo "${tempArrayApplications[1]}" # "item 2"
IFS is the bash equivalent of the AppleScript text item delimiters. It typically has a default value of ⎵\t\n (where ⎵ indicates a space character). More can be read about it in this article: Bash IFS: its Definition, Viewing it and Modifying it
My team requires an Automator service that will allow us to copy file paths from within OS X Finder such that they always start with "afp://server-name/" instead of "/Volumes/server-name/" BUT ALSO replaces all spaces with "%20".
Right now, we are using the following code, which does replace the first space in a given string, but does not replace all spaces.
on run {input, parameters}
set output to {}
repeat with f in input
set end of output to replace(POSIX path of f, "/Volumes/Brand Design", "afp://nycp-afp01/Brand%20Design")
end repeat
set text item delimiters to linefeed
set the clipboard to (output as text)
end run
on replace(input, search, replace)
set text item delimiters to search
set ti to text items of input
set text item delimiters to replace
ti as text
end replace
Any help you can provide will be HUGELY appreciated; thanx!
A.
to get rid of spaces use your replace handler again Inside itself (last line).
my replace(ti as text, " ","%20")
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"
I'm looking for a way to get ALL the values for a specified key in a plist file.
Indeed, I want to go through the plist file and every time I read the specified key, I put the value in an array for example.
Thanks a lot :)
You can try to access the values with sed. Assuming:
set keyValues to paragraphs of (do shell script "sed -En '/CFBundleIconFile/ {
n
s/.*>([^<]+).*/\\1/
p
}' < " & quoted form of "/Users/John/Desktop/Info.plist")
I'm not sure I understand you fully, but here's an example on how to read all the IODisplayLocation values from the windowserver preferences and create an applescript array.
set oldDelimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ";"
set theItems to (do shell script "defaults read /Library/Preferences/com.apple.windowserver | grep IODisplayLocation | awk '{print $3}'")
set itemList to (every text item of theItems) as list
set AppleScript's text item delimiters to oldDelimiters
display dialog item 4 of itemList
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.