Applescript that gets guitar tabs?

Ok, I have no idea how to do this but if anyone could make a script for me it would be awesome. Heres what i want.

I want a dialog where I type the song I want to search.

display dialog "Search for song" default answer ""

And it will search it on www.ultimate-guitar.com . Then I want it to display a list of the top 5 results and when you click on one it will display a dialog where you can scroll through the tab. And if no results come up in the search it will display a dialog that tells you. I’ve tried figuring it out forever but I can’t figure it out. I’m not even sure if dialog boxes can have scroll bars.

So if you can figure this one out let me know. And if there’s something in there thats impossible to do, just work around it any way you can.

Hello,

… here is my (second) attempt about the exercise…


-- /* http://macscripter.net/viewtopic.php?id=31013 */
-- /* TESTED UNDER OSX.4.11 (Tiger) */
-- /* version 0.3 */

property theURL : "http://www.ultimate-guitar.com"
property theURL_search : "http://www.ultimate-guitar.com/search.php"
-- Numerical values expected
property type1_opt : 1 -- {"tab", "bass tab", "chords", "power tab", "guitar pro", "video lesson", " drum tab"}
property type2_opt : "" -- {"whole song", "intro", "solo", "album"}
property rating_opt : {5, 4, 3, 2, 1}
-- String values expected or leave empty
property level_opt : "" -- {"novice", "intermediate", "advanced"}
property tuning_opt : "" -- empty string stands for "Standard" {"Standard", "Half-Step Down", "B tuning", "C tuning", "D tuning", "Drop A", "Drop A#", "Drop B", "Drop C", "Drop C#", "Drop D", "Open C", "Open D", "Open E", "Open G"}
-- Misc
property ui_multi : («data utxt2318» as Unicode text) & "+click for multiple selections."

--=====================================================
-- <! -- ADJUST TO YOUR NEEDS -->
set dflt_band to "Metallica" -- Led Zeppelin
set dflt_song to "Master of puppets" -- Stairway To Heaven
--
set TabsDownloadFolderName to "Ultimate GTR Tabs"
--=====================================================

-- get a nice icon or not
set GB_app to "/Applications/GarageBand.app"
try
	set icn to path to resource "GarageBand App.icns" in bundle POSIX file GB_app
on error
	set icn to 1
end try

-- Input BAND NAME
set my_band to ¬
	text returned of ¬
	(display dialog "Enter BAND name or leave empty." default answer dflt_band ¬
		with title theURL ¬
		buttons {"Cancel", "OK"} ¬
		default button 2 ¬
		with icon icn)

-- Input SONG NAME
if (my_band's number = 0) then
	set |note| to return & "Note: query must be at least 3 letters long."
else
	set |note| to return & "(leave empty to get all " & my_band & "'s tabs.)"
end if
--
repeat
	set my_song to ¬
		text returned of ¬
		(display dialog "Enter SONG name." & |note| default answer dflt_song ¬
			with title theURL ¬
			buttons {"Cancel", "OK"} ¬
			default button 2 ¬
			with icon icn)
	if ((my_band's number > 0 and my_song's number ≥ 0)  ¬
		or (my_band's number = 0 and my_song's number ≥ 3)) then exit repeat
end repeat

-- Select TABLATURE RATING
set my_rating to choose from list rating_opt with title theURL with prompt "Choose a rating." & return & ui_multi ¬
	default items {rating_opt's item 1, rating_opt's item 2} with multiple selections allowed
if my_rating is false then
	return
else
	set rate_opt to ""
	repeat with i in my_rating
		set rate_opt to rate_opt & "&rating\\[\\]=" & i
	end repeat
end if

-- URL ENCODE STRINGS
set bandquery_enc to (do shell script "/usr/bin/php -r 'print urlencode(\"" & my_band & "\");'")
set songquery_enc to (do shell script "/usr/bin/php -r 'print urlencode(\"" & my_song & "\");'")

-- BUILD FULLPATH TO REQUEST
set theQuery to theURL_search & "?bn=" & bandquery_enc & "&sn=" & songquery_enc & "&type\\[\\]=" & type1_opt & "&type2\\[\\]=" & type2_opt & rate_opt & "&level\\[\\]=" & level_opt & "&tuning\\[\\]=" & tuning_opt & "&npage="

-- RUN QUERY 
try
	set query_result to do shell script "
	query=$(/usr/bin/curl -s " & quoted form of theQuery & "1)
	err=$?
	if [ $err -gt 0 ]; then
		exit $err
	fi
	#
	tabscount=$(/usr/bin/sed -En '/tabs found/ s/<[^>]*>//g; s/^.*: ([0-9]+) .*/\\1/p' <<< \"$query\")
	if [[ $tabscount -eq 0 ]] ; then 
		exit 0
	else
		# get first page
		/usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' <<< \"$query\" | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
	fi
	# ... more than 50 tabs found ? => get'em all.
	pagecount=$(($tabscount / 50));
	if [[ $(($tabscount % 50)) -gt 1 ]]; then
		pagecount=$(($pagecount + 1))
		 /usr/bin/curl " & quoted form of theQuery & "[2-$pagecount] | /usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
	fi
"
on error msg number e
	beep
	return display dialog msg & return & "error# " & e buttons {"OK"} default button 1 with icon 0
end try

-- NOTHING FOUND => ABORT
if query_result = "" then return display dialog "Search results:" & return & "Nothing found :o(" with title theURL buttons {"OK"} default button 1 with icon 0 giving up after 3

-- SELECT IN FOUND LIST
set my_selection to choose from list (paragraphs of query_result) with title "Select." with prompt "Tabs found: " & (count paragraphs of query_result) & return & ui_multi with multiple selections allowed
if my_selection is not false then
	-- Set path to download folder
	set TabsFolderPath_px to POSIX path of ((path to desktop as Unicode text) & TabsDownloadFolderName)
	
	-- Connect to file, grab tab data, write to temp file, convert file from text to rtf using momospaced font
	repeat with aPath in my_selection
		do shell script "
		dirpath=\"" & TabsFolderPath_px & "/$(dirname " & aPath & ")\"
		filename=$(basename -s _tab.htm " & aPath & ")\".rtf\"
		filepath=\"$dirpath/$filename\"
		
		cd " & POSIX path of (path to temporary items) & "
		/bin/mkdir -p  \"$dirpath\"
		/usr/bin/curl -s " & theURL & "/tabs/" & aPath & " | 
			/usr/bin/awk '/Tabbed by:/{gsub(/(^[ \\t]*|<[^>]*>)/,\"\"); print}; 
				/<xmp>/,/<\\/xmp>/{gsub(/[ \\t]*<[^>]*>/,\"\"); print}' > tmp.txt;
		/usr/bin/textutil -convert rtf -font Monaco -fontsize 10 -output \"$filepath\" tmp.txt"
	end repeat
	beep
	tell application "System Events" to open folder (TabsFolderPath_px as POSIX file as string)
end if

It’s awesome so far but for some reason it doesn’t work. I did Metallica, Master of Puppets, and 4 or 5 star rating and an error came up that said

sh: line 5: [[: puppets’: syntax error: invalid arithmetic operator (error token is “'”)
sh: line 8: puppets’ / 50 : syntax error: invalid arithmetic operator (error token is "’ / 50 ")

And I tried other random songs and they didn’t work.

Hi Guitarocker,

My bad, I didn’t test using a value in the first dialog box (band name). Sorry.

By including this additional element to the query, the command in charge of extracting the number of tabs has been turned upside and that’s why text came to mix with arithmetic evaluation thereby causing the error.

I corrected the offending lines and updated the script in my first post . Hope this time it will run better.

Beware though, it would be wise to add a robust error trapping.

Wow this is awesome thanks! I had no idea stuff like this was possible. Thanks.

This is good and works but I want to change a few things and keep having problems.

  1. I want to change the icon from the garage band icon to a picture i downloaded off the internet. How do I do that.

  2. I edited the part if there was no results to

-- NOTHING FOUND => ABORT
if query_result = "" then return display dialog "Search results:" & return & "Nothing found" with title theURL buttons {"OK", "Request this tab"} default button 1 with icon 0
if button returned of the result is "request this tab" then
	tell application "Safari"
		activate
		go to "http://www.ultimate-guitar.com/home/request_queue.php"
	end tell
else

But when I press request this tab it doesn’t do anything.

  1. When change the title on all the dialog boxes (theURL) for some reason the text file comes out blank.
 property theURL : "Tab Finder"

Hi,

“Display dialog” expects a file reference to a ‘.icns’ file.
Therefore you have to convert your image (jpg, png, tiff etc…) image to “icns”. You will find plenty of free tools who do this just by simple drag&drop.

Modify this part of the script to:


-- ...
-- get a nice icon or not
try
	set icn to "/Path/to/Your/beautifull/file.icns" as POSIX file
on error
	set icn to 1
end try
-- ...

Did you find “go” is Safari’s terminology ?
Try this instead.


-- add this property at the beginning of the script
property theURL_request : "http://www.ultimate-guitar.com/home/request_queue.php/"
-- ...
-- ...
if button returned of the result is "request this tab" then
	tell application "Safari"
		activate
		open location theURL_request
	end tell
end if

This is normal behavior.
If you follow the script, you’ll see that the “theURL” property is used in the last shell script; the one in charge of tabs download.

add a new property


...
property ui_DialogTitle : "Tab Finder"

and edit every “display dialog” and “chose from list” statements (except the “No Tab Found” dialog) by changing the “with title theURL” part to “with title ui_DialogTitle

Thanks but the request tab part still doesn’t work.

--I have this in the beginning of the script
property theURL_request : "http://www.ultimate-guitar.com/home/request_queue.php/"
--and this down in the no results part
if query_result = "" then return display dialog "Search results:" & return & "Nothing found" with title "TabFinder" buttons {"OK", "Request this tab"} default button 1 with icon 0
if button returned of the result is "request this tab" then
	tell application "Safari"
		activate
		open location theURL_request
	end tell
end if

Ok here is the script so far. I changed a few things and added a few things. My problems are 1. Request tab button doesn’t work, 2. Now the tabs are coming out blank again.


-- /* http://macscripter.net/viewtopic.php?id=31013 */
-- /* TESTED UNDER OSX.4.11 (Tiger) */
-- /* version 0.3 */

property theURL : "http://www.ultimate-guitar.com"
property theURL_search : "http://www.ultimate-guitar.com/search.php"
-- Numerical values expected
property type1_opt : 1 -- {"tab", "bass tab", "chords", "power tab", "guitar pro", "video lesson", " drum tab"}
property type2_opt : "" -- {"whole song", "intro", "solo", "album"}
property rating_opt : {5, 4, 3, 2, 1}
-- String values expected or leave empty
property level_opt : "" -- {"novice", "intermediate", "advanced"}
property tuning_opt : "" -- empty string stands for "Standard" {"Standard", "Half-Step Down", "B tuning", "C tuning", "D tuning", "Drop A", "Drop A#", "Drop B", "Drop C", "Drop C#", "Drop D", "Open C", "Open D", "Open E", "Open G"}
-- Misc
property ui_multi : («data utxt2318» as Unicode text) & "+click for multiple selections."

property theURL_request : "http://www.ultimate-guitar.com/home/request_queue.php/" --=====================================================
-- <! -- ADJUST TO YOUR NEEDS -->
set dflt_band to "" -- Led Zeppelin
set dflt_song to "" -- Stairway To Heaven
--
set TabsDownloadFolderName to "TabFinder Tabs"
--=====================================================

-- get a nice icon or not
set GB_app to "/Applications/GarageBand.app"
try
	set icn to "/Users/garrett/Desktop/brights-brights_icons-music.ico-128x128.icns" as POSIX file
on error
	set icn to 1
end try
-- Input BAND NAME
set my_band to ¬
	text returned of ¬
	(display dialog "Enter BAND name or leave empty." default answer dflt_band ¬
		with title ¬
		"TabFinder 1.0" buttons {"Cancel", "OK"} ¬
		default button 2 ¬
		with icon icn)

-- Input SONG NAME
if (my_band's number = 0) then
	set |note| to return & "Note: query must be at least 3 letters long."
else
	set |note| to return & "(leave empty to get all " & my_band & "'s tabs.)"
end if
--
repeat
	set my_song to ¬
		text returned of ¬
		(display dialog "Enter SONG name." & |note| default answer dflt_song ¬
			with title ¬
			"TabFinder 1.0" buttons {"Cancel", "OK"} ¬
			default button 2 ¬
			with icon icn)
	if ((my_band's number > 0 and my_song's number ≥ 0) ¬
		or (my_band's number = 0 and my_song's number ≥ 3)) then exit repeat
end repeat

-- Select TABLATURE RATING
set my_rating to choose from list rating_opt with title theURL with prompt "Choose a rating." & return & ui_multi ¬
	default items {rating_opt's item 1, rating_opt's item 2} with multiple selections allowed
if my_rating is false then
	return
else
	set rate_opt to ""
	repeat with i in my_rating
		set rate_opt to rate_opt & "&rating\\[\\]=" & i
	end repeat
end if

-- URL ENCODE STRINGS
set bandquery_enc to (do shell script "/usr/bin/php -r 'print urlencode(\"" & my_band & "\");'")
set songquery_enc to (do shell script "/usr/bin/php -r 'print urlencode(\"" & my_song & "\");'")

-- BUILD FULLPATH TO REQUEST
set theQuery to theURL_search & "?bn=" & bandquery_enc & "&sn=" & songquery_enc & "&type\\[\\]=" & type1_opt & "&type2\\[\\]=" & type2_opt & rate_opt & "&level\\[\\]=" & level_opt & "&tuning\\[\\]=" & tuning_opt & "&npage="

-- RUN QUERY 
try
	set query_result to do shell script "
	query=$(/usr/bin/curl -s " & quoted form of theQuery & "1)
	err=$?
	if [ $err -gt 0 ]; then
		exit $err
	fi
	#
	tabscount=$(/usr/bin/sed -En '/tabs found/ s/<[^>]*>//g; s/^.*: ([0-9]+) .*/\\1/p' <<< \"$query\")
	if [[ $tabscount -eq 0 ]] ; then 
		exit 0
	else
		# get first page
		/usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' <<< \"$query\" | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
	fi
	# ... more than 50 tabs found ? => get'em all.
	pagecount=$(($tabscount / 50));
	if [[ $(($tabscount % 50)) -gt 1 ]]; then
		pagecount=$(($pagecount + 1))
		 /usr/bin/curl " & quoted form of theQuery & "[2-$pagecount] | /usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
	fi
"
on error msg number e
	beep
	return display dialog msg & return & "error# " & e buttons {"OK"} default button 1 with icon 0
end try

-- NOTHING FOUND => ABORT
if query_result = "" then
	return display dialog "Search results:" & return & "Nothing found" with title "TabFinder 1.0" buttons {"OK", "Request this tab"} default button 1 with icon 0
	if button returned of the result is "request this tab" then
		tell application "Safari"
			activate
			open location theURL_request
		end tell
	end if
else
	
	-- SELECT IN FOUND LIST
	set my_selection to choose from list (paragraphs of query_result) with title "Select." with prompt "Tabs found: " & (count paragraphs of query_result) & return & ui_multi with multiple selections allowed
	if my_selection is not false then
		-- Set path to download folder
		set TabsFolderPath_px to POSIX path of ((path to desktop as Unicode text) & TabsDownloadFolderName)
		
		-- Connect to file, grab tab data, write to temp file, convert file from text to rtf using momospaced font
		repeat with aPath in my_selection
			do shell script "
		dirpath=\"" & TabsFolderPath_px & "/$(dirname " & aPath & ")\"
		filename=$(basename -s _tab.htm " & aPath & ")\".rtf\"
		filepath=\"$dirpath/$filename\"
		
		cd " & POSIX path of (path to temporary items) & "
		/bin/mkdir -p  \"$dirpath\"
		/usr/bin/curl -s " & theURL & "/tabs/" & aPath & " | 
			/usr/bin/awk '/Tabbed by:/{gsub(/(^[ \\t]*|<[^>]*>)/,\"\"); print}; 
				/<xmp>/,/<\\/xmp>/{gsub(/[ \\t]*<[^>]*>/,\"\"); print}' > tmp.txt;
		/usr/bin/textutil -convert rtf -font Monaco -fontsize 10 -output \"$filepath\" tmp.txt"
		end repeat
		say "Tab saved"
		tell application "System Events" to open folder (TabsFolderPath_px as POSIX file as string)
	end if
end if

Hello Garrett,
1 - Indeed, tab button doesnt’t work because “Display dialog” is preceeded by the “return” command, which causes your script to stop executing.

2 - Hélas, c’est la vie ! (Alas, that’s life) for HTML pages. They change according to the needs and moods of WebMasters.
Yesterday the text of the tablature was located between the tags & and today it is between

 & 
.
But if tomorrow files return empty, you should look for the right tags in the source code of a valid tab page and edit the properties (RE_oTag & RE_cTag) accordingly.

-- /* http://macscripter.net/viewtopic.php?id=31013 */
-- /* TESTED UNDER OSX.4.11 (Tiger) */
-- /* version 0.4 */
-- /* added Request form fill automation */

--------------------------------------------------
--     CUSTOM SETTINGS
--------------------------------------------------
property TabDownloadFolderName : "TabFinder Tabs"
property dialog_title : "TabFinder 1.0"
property dialog_request_btn : "Request this tab"

--property GB_app : "/Applications/GarageBand.app"
try
	set icn to "/Users/garrett/Desktop/brights-brights_icons-music.ico-128x128.icns" as POSIX file as alias
	--set icn to path to resource "GarageBand App.icns" in bundle POSIX file GB_app
on error
	set icn to 1
end try

property dialog_dflt_band : "" -- Yngwie Malmsteen
property dialog_dflt_song : "" -- Little Savage
property dialog_ui_multi : («data utxt2318» as Unicode text) & "+click for multiple selections."

-- The opening and closing tag between which the tablature is situated.
property RE_oTag : "<pre>"
property RE_cTag : "<\\/pre>" -- slash (and other reserved characters) has to be escaped twice!

-- Request submission
property myTimeout : 20 -- The time in seconds for the Request page to be fully displayed.
property request_NotifyMe : true -- true/false [Notify me by e-mail when the tab is posted on Ultimate-Guitar.com]
property request_myEmail : "youremail@somewhere.com"

--------------------------------------------------
--     SEARCH SETTINGS
--------------------------------------------------

property theURL : "http://www.ultimate-guitar.com"
property theURL_search : "http://www.ultimate-guitar.com/search.php"
property theURL_request : "http://www.ultimate-guitar.com/home/request_queue.php/?#submit_form"
property cookieName : "bbuserid"

-- Empty or Numerical values expected
property searchType1 : 1 -- {"tab", "bass tab", "chords", "power tab", "guitar pro", "video lesson", " drum tab"}
property searchType2 : "" -- {"whole song", "intro", "solo", "album"}
property searchRating_list : {5, 4, 3, 2, 1}

-- Empty or String values expected
property searchLevel : "" -- {"novice", "intermediate", "advanced"}
property searchTuning : "" -- empty string stands for "Standard" {"Standard", "Half-Step Down", "B tuning", "C tuning", "D tuning", "Drop A", "Drop A#", "Drop B", "Drop C", "Drop C#", "Drop D", "Open C", "Open D", "Open E", "Open G"}


--------------------------------------------------
--     HANDLERS
--------------------------------------------------
on page_loaded(timeout_value)
	delay 1
	repeat with i from 1 to the timeout_value
		tell application "Safari"
			if (do JavaScript "document.readyState" in document 1) is "complete" then
				return true
			else if i is the timeout_value then
				return false
			else
				delay 1
			end if
		end tell
	end repeat
	return false
end page_loaded

to LogInStatus()
	tell application "Safari"
		set nv_string to (do JavaScript "unescape(document.cookie)" in document 1)
		--
		set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "; "}
		set nv_string to every text item of nv_string
		--
		set CookieArray to {}
		try
			repeat with i in nv_string
				set AppleScript's text item delimiters to "="
				set {a, b} to every text item of i
				set CookieArray's end to {a} & {b}
			end repeat
		end try
		set AppleScript's text item delimiters to tid
		--
		repeat with i in CookieArray
			if i's item 1 is cookieName then return true
		end repeat
		return false
	end tell
end LogInStatus

to FillForm(aList)
	tell application "Safari"
		activate
		try
			set thisWindow to first window --whose visible is true
		on error
			set thisWindow to make new document
		end try
		
		if my page_loaded(myTimeout) is false then return
		set url_list to (get URL of tabs of thisWindow)
		-- 
		if theURL_request is in contents of url_list then -- URL is already open in a tab.
			set tabNum to 1
			repeat with i in url_list
				if (i as string) = theURL_request then exit repeat
				set tabNum to tabNum + 1
			end repeat
			tell thisWindow to set current tab to tab tabNum
		else
			tell thisWindow to set current tab to make new tab with properties {URL:theURL_request}
		end if
		
		--
		if my page_loaded(myTimeout) is false then return
		set thisDoc to name of document 1
		
		--
		tell document thisDoc
			-- am I logged in ?
			set formNum to 1
			if my LogInStatus() is true then set formNum to 0
			
			-- conditionally remove email adrress from list
			if request_NotifyMe is false or formNum = 0 then set aList to aList's items 1 thru ((count aList) - 1)
			set cnt to (count aList)
			
			-- scroll to form fragment
			do JavaScript "window.location.href = '#submit_form'"
			repeat with i from 2 to cnt
				set var to aList's item i as string
				if i ≠ 8 then
					do JavaScript "document.forms[" & formNum & "].elements[" & i & "].value = " & quoted form of var
				else
					do JavaScript "document.forms[" & formNum & "].elements[" & i & "].checked=" & var
				end if
			end repeat
			
			if aList's item 2 = "" then
				do JavaScript "document.forms[" & formNum & "].elements[2].focus(); return"
			else if aList's item 3 = "" then
				do JavaScript "document.forms[" & formNum & "].elements[3].focus(); return"
			else
				do JavaScript "document.forms[" & formNum & "].elements[7].focus(); return"
			end if
		end tell
	end tell
end FillForm

--------------------------------------------------
--     Routine
--------------------------------------------------

-- ARTIST/BAND NAME INPUT
set searchBand to ¬
	text returned of ¬
	(display dialog "Enter BAND name or leave empty." default answer dialog_dflt_band ¬
		with title dialog_title ¬
		buttons {"Cancel", "OK"} ¬
		default button 2 ¬
		with icon icn)

-- SONG NAME INPUT
if (searchBand's number = 0) then
	set |note| to return & "Note: query must be at least 3 letters long."
else
	set |note| to return & "(leave empty to get all " & searchBand & "'s tabs.)"
end if

repeat
	set searchSong to ¬
		text returned of ¬
		(display dialog "Enter SONG name." & |note| default answer dialog_dflt_song ¬
			with title dialog_title ¬
			buttons {"Cancel", "OK"} ¬
			default button 2 ¬
			with icon icn)
	if ((searchBand's number > 0 and searchSong's number ≥ 0) ¬
		or (searchBand's number = 0 and searchSong's number ≥ 3)) then exit repeat
end repeat

-- TABLATURE RATING SELECTION
set searchRating to choose from list searchRating_list with title dialog_title with prompt "Choose a rating." & return & dialog_ui_multi ¬
	default items {searchRating_list's item 1, searchRating_list's item 2} with multiple selections allowed
if searchRating is false then
	return
else
	set rate_opt to ""
	repeat with j in searchRating
		set rate_opt to rate_opt & "&rating\\[\\]=" & j
	end repeat
end if

--------------------------------------------------
-- URL ENCODE STRINGS
set searchBand_encoded to (do shell script "/usr/bin/php -r 'print urlencode(\"" & searchBand & "\");'")
set searchSong_encoded to (do shell script "/usr/bin/php -r 'print urlencode(\"" & searchSong & "\");'")

-- BUILD FULLPATH TO QUERY
set theQuery to theURL_search & "?bn=" & searchBand_encoded & "&sn=" & searchSong_encoded & "&type\\[\\]=" & searchType1 & "&type2\\[\\]=" & searchType2 & rate_opt & "&level\\[\\]=" & searchLevel & "&tuning\\[\\]=" & searchTuning & "&npage="

-- RUN QUERY
try
	set query_result to do shell script "
query=$(/usr/bin/curl -s " & quoted form of theQuery & ")
err=$?
if [ $err -gt 0 ]; then
	exit $err
fi
#
tabscount=$(sed -En '/tabs found/ s/<[^>]*>//g; s/^.*: ([0-9]+) .*/\\1/p' <<< \"$query\")
if [[ $tabscount -eq 0 ]] ; then
	exit 0
else
# Get tab locations from page 1.
/usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' <<< \"$query\" | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
fi

# Get the rest of tab locations if more than 50.
pagecount=$(($tabscount / 50))
if [[ $(($tabscount % 50)) -gt 0 ]]; then
	pagecount=$((($tabscount / 50) + 1))
fi
if [[ $pagecount -gt 1 ]]; then
	/usr/bin/curl " & quoted form of theQuery & "[2-$pagecount] | /usr/bin/grep -o '<a href=\\\"/tabs\\/.*_tab\\.htm' | /usr/bin/awk '{gsub(/<a href=\\\"\\/tabs\\//,\"\"); print}'
fi"
on error msg number err
	beep
	return display dialog msg & return & "error# " & err buttons {"OK"} default button 1 with icon 0
end try

--------------------------------------------------
-- NOTHING FOUND
if query_result = "" then
	display dialog "Search results:" & return & "Nothing found" with title dialog_title buttons {"Cancel", dialog_request_btn} default button 2 with icon 0
	
	-- FILL REQUEST FORM
	if button returned of the result = dialog_request_btn then
		-- Type=1 (guitar tab), Part=1 (whole song), Tuning=1 (Standard), Notes=""
		set myRequest to {missing value, searchBand, searchSong, 1, 1, 1, "", request_NotifyMe, request_myEmail}
		return FillForm(myRequest)
	end if
end if

--------------------------------------------------
-- CHOOSE IN FOUND LIST
set myChosenTabs to choose from list (paragraphs of query_result) with title dialog_title & " - Select." with prompt "Artist/Band: " & searchBand & return & "Song: " & searchSong & return & "Tabs found: " & (count paragraphs of query_result) & return & return & dialog_ui_multi OK button name "Save" with multiple selections allowed


if myChosenTabs is not false then
	
	-- Set path to download folder
	set TabsFolderPath_px to POSIX path of ((path to desktop as Unicode text) & TabDownloadFolderName)
	
	-- Connect to file, grab tab data, write to temp file, convert file from text to rtf using momospaced font
	repeat with thisPath in myChosenTabs
		do shell script "
dirpath=\"" & TabsFolderPath_px & "/$(dirname " & thisPath & ")\"
filename=$(basename -s _tab.htm " & thisPath & ")\".rtf\"
filepath=\"$dirpath/$filename\"

cd " & POSIX path of (path to temporary items) & "
/bin/mkdir -p \"$dirpath\"
/usr/bin/curl -s " & theURL & "/tabs/" & thisPath & " |
	/usr/bin/awk '/" & RE_oTag & "/,/" & RE_cTag & "/{gsub(/(^.*" & RE_oTag & "|" & RE_cTag & ".*$)/,\"\"); print}' > tmp.txt;
/usr/bin/textutil -convert rtf -font Monaco -fontsize 10 -output \"$filepath\" tmp.txt"
	end repeat
	beep
	tell application "System Events" to open folder (TabsFolderPath_px as POSIX file as string)
end if

Thanks