Problems with URL handlers and the "open" command - OS X bug?

Greetings, all. I’m working on a fairly simple one-trick-pony to intercept magnet links, then pass them on with the proper options to keep the client from being activated - rather annoying when you’re watching stuff on your home theater Mac Mini. (Background: the programs sending such links really should be using openURLs with NSWorkspaceLaunchWithoutActivation, but they’re not - so I’m trying to kludge around it).

The following script works well and handles magnet URLs being sent by other programs (e.g. TVShows, Safari, etc), but it fails when the command-line “open” command is used to send a link! When sent by “open”, the “on run” routine fires instead of “on open location” - which means I don’t get the link. Rather annoying.

Does anyone see anything wrong here, or have I uncovered a minor-yet-annoying OS bug?

Mac OS X 10.8.2

property urlPrefix : "magnet:?"
property transmissionLocation : ""
property firstRun : true

on run
    configureHandler()
end run

on configureHandler()
    activate
    set transmissionLocation to (choose file with prompt "Please select the BitTorrent application that should handle magnet links." default location (path to applications folder as alias) of type "APPL" without invisibles) as string
    set firstRun to false
end configureHandler

on open location theURL
    if (the offset of urlPrefix in theURL) < 0 then return
    if firstRun then configureHandler()
    try
        set theCommand to "open -g -a \"" & POSIX path of transmissionLocation & "\" " & theURL
        do shell script theCommand
    on error
        tell me to display alert "The magnet link could not be processed." message "There was a problem sending the marget link. Usually this is due to a missing BitTorrent application or a bad magnet link. " as critical buttons {"OK"} default button "OK"
    end try
end open location

I’ve added the proper entries to the Info.plist:

[code] CFBundleIdentifier
com.joshuaochs.silentmagnet

<key>CFBundleURLTypes</key>
<array>
	<dict>
		<key>CFBundleURLName</key>
		<string>Magnet Link</string>
		<key>CFBundleURLSchemes</key>
		<array>
			<string>magnet</string>
		</array>
	</dict>
</array>[/code]

And I’ve used RCDefaultApp to set it as the proper handler for such links.

Hello.

If the thing is that it triggers your run handler, then you could let your take a paramter that you treat as a list maybe.

I haven’t tried this fully, but if there is no contents in it, then it should be an empty list with zero elements.

Maybe within a try block so you won’t get a runtime error when nothing is passed. then, when there is an element in your list, then you know you have received a url, and can pass that directly to your open location handler.

It is a dubious work around, but it is worth a try. Even if it doesn’t turn out to work. The question is, if you get that far when calling up your run handler that should take a parameter. That is the only way I can see you get a url from the open command and be able to process it too. Another work around, would be to make your own open command, that uses open URL or similar to trigger the on Open location handler.

Yup, I also wondered if somehow the URL was being passed as an argument to the run handler. Tried it; no dice - empty list. Even so, it should by all rights be sending it through the same Apple Event system as any other program.

In my case I could just modify the script to force the URL to go straight to Transmission, but it’s never good to just punch through an abstraction layer like that.

Anyone else mind taking a look at this and seeing if you can replicate it, especially anyone not running 10.8.2?

Hello.

I wonder if you have tried the open handler?

No dice on the open handler either. It’s definitely going to “on run” with no arguments, which leaves me high and dry.

I’m having the same problem, on 10.8.4. Things are ok on 10.7.5.

I want to open URLs from external applications in a new Chrome window. (If you’re interested in why, see http://smoove-operator.blogspot.co.uk/2011/06/open-links-from-external-applications.html).

My script is currently:

Double-clicking a document in the Finder invokes the “on open location” handler, but if I use the “open” command from the command line, the “on run” handler fails with the message…

If I add the line…

… at the beginning of the “on run” handler, it displays:

Does anyone have any ideas? This is very frustrating, especially as the documentation for the open command explicitly says “The open command opens a file (or a directory or URL), just as if you had double-clicked the file’s icon”.

the shell open command calls the default on run event handler, which takes no parameters.

The special case to call the explicit on run handler with parameters is only available with the AppleScript command run script with parameters

I haven’t been following, but how about using osascript?

This might be a solution, but osascript complains about user interaction using commands like display dialog or choose file

Ah, I forgot about that. Maybe one day :wink:

You can tell systemUIServer or other agents to make user interaction:

set theScript to "tell application \"SystemUIServer\"
	activate
	display dialog \"hello world\"
end tell"

do shell script "osascript <<<" & quoted form of theScript

In the on run event handler is there a way to find out what document was given as argument to the open command? Clearly the type of my document is being used to invoke my script, but in the script how can I find what the document is?

Oh, and is this a bug in 10.8.4? It’s different to 10.7.5 as I said before.

Do you know if the behaviour specified somewhere? Or is it a matter of just trying things out?

I’m still on 10.6, but this doesn’t look kosher at all. Here’s a handler with a space in its name, and the parameter is not in parentheses. What’s more, open location is a Standard Additions command, it can never be a handler name. The script compiles, but what part actually runs?? (The script in post 1 also compiles, but when saved as an application it does not display the applet icon.)

Hi alastor933.

It’s a known and acceptable technique (as long as it’s done properly). The idea is to intercept any ‘open location’ messages sent to or within the script so that custom code can inserted or substituted. Using a ‘quit’ handler to intercept ‘quit’ messages is the same technique. Or this stupid example:

on beep n
	try
		say "I shall now beep " & n & " times."
		continue beep n
	on error number -1700 -- No parameter given.
		say "I shall beep this only once."
		continue beep
	end try
	
end beep

beep 3

beep

I’ve written an appscript that does this. it currently works out which chrome profile to load but you can edit it to do whatever you want.

https://github.com/arkarkark/openChrome.app

this is where the script is.
https://github.com/arkarkark/openChrome.app/blob/master/Contents/Resources/Scripts/openChrome

you can open it with the script editor

here’s the guts

on open location myURL
	set myPath to POSIX path of ((path to me as text) & "Contents:Resources:Scripts:openChrome")
	try
		set output to do shell script myPath & " " & quoted form of myURL
	on error the error_message
		display dialog error_message with title "openChrome.app failed"
	end try
end open location

I also got help here

http://superuser.com/questions/373701/create-bash-script-to-open-url-in-mac-os-x
http://apple.stackexchange.com/questions/32386/how-to-register-an-applescript-as-a-potential