open
All Top-level Files
Not logged in
Public Repositories
mwm's Repositories

Files in the top-level directory in any check-in


-*- Mode: text -*-


What it is

open is a tool for mapping a command and a file name to an application
invocation. Currently supported commands are "open", to
view/play/etc. a file, "edit" to edit the contents of a file, and
"convert" to convert a file to a different file type. Planned commands
include "mail", to send a file as email, and "print", to print a file.

You specify the command with the "-c" option to open. If you don't
specify a command that way, the last part of the executable name is
used. I.e. - you can link this into your path as "open", "edit" or
"convert". This all collide with existing application names on some
systems. I'm not willing to change to less obvious command names to
avoid that, but would love to hear more obvious command names. I'm
also willing to consider alternative ways to set the default command
name from the executable name.

Right now, it is very much a proof-of-concept program. Everything is
up in the air - including the name of the thing.


What I intend it to be

The general idea is that "open" will handle all the interactions with
the user when it comes to choosing an application to open/edit/convert
a file type. The data model is similar to that for termcap: a global
database that describes all applications, and user preferences that
select entries from the global database for this user. The global
database should *not* be edited by the user, or by the
installation. Changes to it should come back to me to be integrated
into the distributed database.

You - or an appropriately configured application - invokes "open -c
stuff foo.type" to do "stuff" to a file "foo.type". Open will consult
the users preferences file to find out what application the user would
prefer for this action in the current environment. If it finds one
such application, it just runs the appropriate command. This should be
the most common case.

If open finds no files for the action at hand, it will consult the
database of Unix applications to generate for a list of applications
that could be used. It will then check $PATH to see which, if any, of
those are installed. The resulting list is displayed to the user so
they can select an application. By default, this application will be
added to their preferences file, though that can be disabled. The list
will include an "info" button that will launch a web browser on the
home page for the application in question, assuming it's available.

If none of the applications from the database are installed along
$PATH, open will offer the list of possible applications to the user
as suggested applications to install. This will include the "info"
button as well. An "install" button will be available to install an
application for the user. Again, once an application is selected, the
users preferences will be updated by default.

Both applications lists will have a button to invoke a file system
browser so the user can choose an application from those already
installed. If the user does this, and the selected application isn't
in the database, then open will by default email me a description of
the action and application so I can add them to the database.

Currently, the application database doesn't exist, so all you get is
the file system browser. The database is the next thing on the list of
things to do. If you know where I can get such a database (somebody
has to have one somewhere!), I'd certainly like to hear about it.

It's not clear to me how the "install" functionality will work, so
that may appear late - or never.


Installation

To install this, do "python setup.py install". This will install the
"open" script in the same prefix as your python command. On Debian,
this overwrites the console tool of the same name. Use the
"--install-scripts" option of install to install this elsewhere.  If
you want, symlink "edit" and "convert" to the "open" script, those
this will collide with applications from ImageMagick and ee,
respectively.

At the time of this writing, it requires Python 2.4.


Configuration

Open checks two places for configuration information: First, it checks
the environment variable OPENERS. \n and \\ in that string are mapped
as you'd expect. If no match is found there, it looks in
~/.openrc. Blank lines and lines whose first non-white character is
'#' are skipped.

Non-blank lines have the format "flags ; extensions ; name ; command"

        flags is a white-space separated list of flags describing this
        Application and the action it takes.

        extensions is a white-space separated list of extensions used on files
        that this Application knows how to handle.

        flags and extensions are both case insensitive.

        name is a string to be used to name the application in the
        user interface. For now, that means the -a flag. This hasn't
        been thoroughly tested.

        command is the shell command line used by this Application to
        take the indicated action. The standard mode is the simplest:
        whitespace separates the command and any arguments, the file
        name will be appended to the list, and the entire thing passed
        to the OS. No shell processing is done at all. If a %s shows
        up in the command, then the file name will be quoted to guard
        special characters from interpretation by the shell, and then
        substituted in place of the %s. The resulting string will be
        passed to the shell. If you need shell processing - I/O
        redirection, pipes, etc. - you can use a %s even if the
        command doesn't really need it to get them.

See the file openrc for a sample .openrc file.

Currently recognized flags in .openrc/OPENERS are:
	open: This application will display the file.
        edit: This application will edit the file.
        print: This application will print the file (NOT IMPLEMENTED).
	X: Must run in an X environment.
        noX: Must run in a terminal environment.
	convert: This application will create a new file of a different type.
	<extension>: Used in conjunction with the convert flag to specify
		the type that this application will create.
	internal: Used internally by open.

Extensions we plain to used with the "internal" flag:
        mail:  used to send mail.
        print: used to print files.
        ui: used to find a user interface skin.


Miscellaneous

If you are opening a file in a terminal emulator running under X,
using the --noX option will force it to use a command-line tool to
open the file.

open now supports conversions. To convert a file in format foo to
format bar, invoke open as "open -c convert -f foo filename.bar" (or,
if you have it symlinked, "convert -f foo typename.bar".  If you're
using the ApplicationList class, set have to ['convert', 'foo'] Upon
running the application, you'll get a file of the appropriate type as
filename.foo. This is still under development.

I favor putting full path names in .openrc, so that you don't get
surprised when you fiddle your path, or things get added to
it. Instead, you get surprised when commands move. If you want to
toggle which applications get used when you for a specific invocation
of open, you should use the OPENERS environment variable. If you have
strong feelings that this is wrong, please let me know why you feel
that way!

Applications that are using the ApplicationList type should set
'internal' in not_have, otherwise they may find applications that they
aren't intended to use.

Applications should feel free to specify their own flags. Ideally,
send me a list of the operations they want to perform, and I'll send
back a list of flags to use.  They can then specify those on the have
list if they are using the API, or they can specify it via the "-c" or
"-f" flags if they are running the open command. They can even symlink
to open with that flag as the name, then run the symlink.

I admit it, the GUI sucks. If you think you can do better - prove it!
And then send it to me so I can bundle it with the next
release. You'll even get an early copy of the next release so you can
update your gui. The interface is trivial - see open.simplegui for
details.


Alternatives and standards

Naturally, open isn't the first tool to do this kind of thing. The
GNOME desktop has gnome-open, and the KDE desktop has kfmclient. These
are both tide to the desktops in question, and depend on those
desktops to handle creating what I'm calling the user preferences
file. Neither of them work outside of an X display. Neither of them
provides the flexibility that "open" does for specifying different
action types.

The freedesktop.org folks are establishing standards for some of the
things that open does. Two in particular need to be considered by
open. The first is the shared MIME database. This is a database for
mapping files to MIME types. This is basically a re-implementation of
the de-facto standard magic(5) file in XML, distributed across
multiple files. At this time. open doesn't use MIME types - it uses
extensions. Switching to MIME types may happen in the future. At that
time, I'll decide whether to use the shared MIME database or magic.

The shared MIME database standard does acknowledge that it should
include an entries for invoking applications. However, this part of
the standard is still in the "gathering requirements" stage, so
applications are apparently rolling their own. I consider the format
for this database unacceptable for the preferences file - which format
should be tailored for use by open, as opposed to sharing. I'll
certainly do something with the shard MIME database for open's global
database, if only to provide a tool to import the shared MIME database
into the open database.

The other activity of interest at freedesktop.org is the standardized
data directories structure. This would involve checking for .openrc in
a different place than ~. I'll probably add support for that at some
point, but it's not a priority.


mwm@mired.org