Extending Nautilus with Scripts and Extensions

4457

Author: Peter Enseleit

Nautilus, the GNOME file manager, has a host of functionality for browsing and managing file systems, and for accessing remote servers including Windows shares, FTP servers, SSH servers, and WebDAV servers. On top of its built-in capabilities, you can extend the functionality of Nautilus by using Nautilus Scripts and Extensions. It’s not too hard to do, and I’ll show you how to get started.

Nautilus Scripts

A Nautilus Script is an executable file, written in a scripting language, which can perform some function on files or folders selected from within the Nautilus file manager window.

Linux is rich with scripting languages, including Python, Perl, and Ruby, and has a variety of command line shells to choose from, such as Bash, Zsh, and Csh. Any of these can be used to write a Nautilus Script.

You don’t need to know how to write Nautilus Scripts to use them. A search on the Web for Nautilus Scripts will return a number of links to scripts other people have already written and have made available for others to use. G-Scripts is a site that gathers many of these scripts.

Installation

Scripts are usually packaged in compressed archives, so, once you’ve downloaded a script you’re interested in, you’ll need to extract it using an archiving program such as File Roller for GNOME, or Ark for KDE.

Next, you need to copy the file to the .gnome2/nautilus-scripts folder inside your home folder. The dot in front of the folder name means it is a hidden folder, so you will need to make sure you can see it in Nautilus by selecting Show Hidden Files from the View menu.

Finally, you need to make the script executable. View the properties of the file in Nautilus and, on the Permissions tab, check the Execute checkbox for the owner of the file — that should be you.

If you prefer to use the command line, open a terminal and navigate to the folder where you downloaded your script, then unpack it with one of the following commands, depending on the file extension of the file you wish to decompress:

tar -zxvf myscript.tgz
tar -zxvf myscript.tar.gz
tar -jxvf myscript.bz2

Copy the script to the nautilus-scripts folder:

cp myscript ~/.gnome2/nautilus-scripts

Change the script’s permissions so that it is executable:

chmod u+x myscript

If you want all users on your system to be able to use the script, it should be installed into the /usr/share/nautilus-scripts folder. You’ll need to have superuser privileges to copy the script into this folder and change its file permissions.

Usage

How do you use a script? From within Nautilus, navigate to a file and select it. Then click it with your right mouse button, and a context menu will appear with a Scripts menu item. You can also open the Scripts menu item from the File menu and, if you are using Nautilus to manage your Desktop, from a right mouse click on the Desktop. This menu item is not visible if no Nautilus Scripts are installed. Expand the Scripts menu item and you should see your script listed. Click it, and the script will perform its actions on the file you have selected. Many scripts allow you to select multiple files at once.

If you’re looking for ready-made scripts, see the G-Scripts site. G-Scripts has scripts for archiving files, opening files with particular applications, sending files via email, image manipulation, integration with the Subversion version control system, and package management, to name just a few.

Writing a Nautilus Script

To write a Nautilus Script, you’ll need to know at least the basics of your chosen scripting language. A good starting point is to look at how others have written their Nautilus Scripts and get ideas from them.

If you are using an external program in your script, you will also need to find out which command line parameters it accepts. In your script, construct the parameters your external program needs, then call the program, passing it those parameters.

Let’s take a look at a simple script, which creates a new email message using the Sylpheed-Claws email client, and includes the files you select in Nautilus as attachments.

Next: A sample script

#!/bin/bash

if [ -x sylpheed-claws-gtk2 ] then
      sylpheed-claws-gtk2 --compose --attach $*
fi

Nautilus Scripts are run in the shell. All scripts start with a line that tells the shell which program to use to run the script. In this case, the script should be run using the bash shell.

The next line is a test to see if the program you want to run is installed and executable. If the program is not detected, or is detected but is not executable, then the call to Sylpheed-Claws will not be made.

Then comes the command to open Sylpheed-Claws with parameters that instruct it to compose a new email message and add all the files selected in Nautilus as attachments. The $* argument expands to a list of all the file names passed to the shell from Nautilus.

The paths of the files you have selected are passed to the script so that it can perform its tasks on those files. If you use a script while browsing a remote server, such as a Windows share or an FTP file system, the paths to the files you select are not passed to the script, but Nautilus sets these Environment variables, which can be used by the script:

  • NAUTILUS_SCRIPT_SELECTED_FILE_PATHS: newline-delimited paths for selected files (only if local).
  • NAUTILUS_SCRIPT_SELECTED_URIS: newline-delimited URIs for selected files.
  • NAUTILUS_SCRIPT_CURRENT_URI: URI for current location.
  • NAUTILUS_SCRIPT_WINDOW_GEOMETRY: position and size of current window.
  • This script will attach only local files to the new email message.

    This script does not populate your Send To field with any email addresses; you have to do that manually. It could, however, be extended to ask you for the email address of the person you want to send the files to and then send the message and its attachments to that person automatically. Obviously, you can do many more things with scripts, but this simple example demonstrates that you don’t need a degree in computer science to get something simple happening.

    Next: Nautilus Extensions

    Nautilus Extensions need to be written to conform to a set of interfaces that Nautilus exposes. They can change the look and feel of Nautilus and can integrate with Nautilus in such a way as to extend its behavior. For example, you could write an Extension to display a property page that shows information about the currently selected PDF file.

    While Nautilus Scripts need to be accessed through the Scripts menu item, Nautilus Extensions can create their own menu items. Nautilus Extensions look and feel as if they are a part of Nautilus itself, and are as simple to use as selecting a menu or toolbar item or reading the property page of a file, or a property column in a file list view.

    Nautilus Extensions are often packaged together with another application, such as FileRoller, and as such, are installed when you install that application. They are installed into the $(libdir)/nautilus/extensions-1.0 folder and cannot be installed into your home folder. This means that you need to have superuser privileges to install Extensions.

    Writing an Extension

    Extensions are more involved than Nautilus Scripts because they need to implement at least one of the libnautilus-extensions interfaces which are exposed by Nautilus. The Nautilus Script shown above, which is four lines of code, could take 80 lines of code or more to write as an Extension. The libnautilus-extensions library provides several interfaces for working with Nautilus through Extensions, including:

    • The nautilus-column-provider interface allows you to add columns to list views and add details to icon views.
    • The nautilus-menu-provider interface enables you to add context menu entries for files.
    • The nautilus-property-page-provider interface allows you to add property pages to property dialogs.
    • The nautilus-location-widget-provider interface allows you to add extra location widgets for a particular location.
    • The nautilus-info-provider interface provides extra information about files.

    Anyone considering creating an Extension should take a look at the source code of the libnautilus-extensions library and of other Nautilus Extensions, as well as an overview of Nautilus Extensions, with examples, and a paper describing some of the internals of Nautilus. The Nautilus project’s homepage is a good place for further information.

    Most Nautilus Extensions are written in C, but there are also Python and Mono bindings to enable you to write Nautilus Extensions in Python and in managed code such as C#.

    Let’s take a look at how we would write a Nautilus Extension to do the same operation as the Nautilus Script we looked at earlier. It creates a context menu item to “Send via Sylpheed-Claws” and, when clicked, creates a new mail message in Sylpheed-Claws with the selected files as attachments. You can download the source code for this Nautilus Extension.

    To start with, we need to implement the interface Nautilus will use to load the Extension. This comprises three functions:

    void nautilus_module_initialize (GTypeModule  *module)
    {
    	g_print("Initializing Send via Sylpheed-Claws Extensionn");
    	claws_extension_register_type (module);
    	provider_types[0] = claws_extension_get_type ();
    }

    This function is called when Nautilus first starts up. It registers your Extension and the interfaces it is implementing with Nautilus. In this case we use the nautilus-menu-provider interface, which is registered in the claws_extension-register_type function.

    void claws_extension_register_type (GTypeModule *module)
    {
         static const GTypeInfo info = {
           sizeof (ClawsNautilusExtensionClass),
           (GBaseInitFunc) NULL,
           (GBaseFinalizeFunc) NULL,
           (GClassInitFunc) claws_extension_class_init,
           NULL,
           NULL,
           sizeof (ClawsNautilusExtension),
           0,
           (GInstanceInitFunc) claws_extension_instance_init,
         };
    
    	claws_extension_type = g_type_module_register_type (module,
    				G_TYPE_OBJECT,
    				"ClawsNautilusExtension",
    				&info, 0);
    
    	/* Nautilus Menu Provider Interface */
    	static const GInterfaceInfo menu_provider_iface_info =
    	{
    		(GInterfaceInitFunc)claws_extension_menu_provider_iface_init,
    		 NULL,
    		 NULL
    	};
    
    	g_type_module_add_interface (module, claws_extension_type,
    		NAUTILUS_TYPE_MENU_PROVIDER, &menu_provider_iface_info);
    
    	/* Nautilus Info Provider Interface code could be added here */
    	/* Nautilus Property Page Interface code could be added here */
    	/* Nautilus Column Provider Interface code could be added here */
    }
    

    The next function returns the type of object Nautilus needs to create for your extension.

    void nautilus_module_list_types (const GType **types, int *num_types)
    {
    	*types = provider_types;
    	*num_types = G_N_ELEMENTS (provider_types);
    }
    

    Then comes the function that handles any tasks required to shut the Extension down cleanly.

    void nautilus_module_shutdown (void)
    {
    	g_print("Shutting down Send via Sylpheed-Claws Extensionn");
    	/* Any module-specific shutdown code*/
    }

    Now that Nautilus knows about your Extension and the interfaces you are implementing, it will call the functions that those interfaces provides when it needs to. For the nautilus-menu-provider interface, these functions are called when Nautilus creates menus.

    Nautilus can create menu items in several ways: per-file, which is shown in the file’s context menu and the Edit menu through the extension_get_file_items function; per-folder, which is shown in the background context menu and the File menu using the extension_get_background_items function; and on the toolbar using the extension_get_toolbar_items function.

    Within each of these functions, you create a menu or toolbar item, associate a callback function to be called when the menu item or toolbar is clicked, and associate the files currently selected within Nautilus with the menu item or toolbar. When the callback function is called, it gets the list of files associated with the menu item and, in this case, formats them to be sent to Sylpheed-Claws.

    Examples of Extensions

    Many of the Nautilus Extensions available may already be installed with your Linux distribution. In fact, a number of Nautilus menu items that you use may actually be Extensions. FileRoller, a file archiving application, adds Create Archive and Extract Here menu items. The Open in Terminal menu item is installed with the nautilus-open-terminal package. The Sign and Encrypt menu items, installed with Seahorse, form a front end for GnuPG, a digital signature and encryption application. The nautilus-sendto package installs the Send To menu item, which allows you to send files as attachments via Evolution and Gaim, and to Bluetooth devices. The gnome-system-tools package installs the Share Folder menu item, which allows you to share folders over a network.

  • Nautilus Extensions may also add property page tabs to Nautilus. For instance, if you have Totem Movie Player installed, it will add an Audio/Video tab in the properties dialog of multimedia files. Evince adds a document tab in the properties dialog of PDF and PostScript files.

    Other Extensions

    Bulldozer is an extension to integrate build tools into Nautilus. With Bulldozer you can build your software projects directly from Nautilus.

    Novell’s iFolder Extension allows you to share files over networks and across different operating system platforms.

    Nautilus Actions is an Extension that allows you to create customized Nautilus menus. It lets users provide Nautilus with functionality which is similar to Nautilus Scripts, but it is easier to use because it doesn’t require you to learn a scripting language. Using Nautilus Actions, creating a menu item which does the same as the Send via Sylpheed-Claws Nautilus Script above is as simple as creating a new action and filling in the fields.

    See the Ubuntu Forums for more Nautilus Actions examples.

    Conclusion

    If you use the Nautilus file manager and want to extend its abilities without becoming a fully fledged programmer, Nautilus Scripts and the Nautilus Actions Extension are flexible ways to create new functionality.

    Many applications, including many of the command line applications which Linux and Unix are famous for, can be leveraged from the graphical desktop through Nautilus Scripts. Nautilus Actions brings the power of Nautilus Scripts within reach of average users with a graphical interface to easily create and edit script-like Actions which are incorporated into the existing context menu structure. These options give users the power to perform advanced actions on files or folders from within Nautilus without changing the application itself.

    If you want to go a step further, you have the option of writing a Nautilus Extension, which offers a powerful means of enhancing Nautilus well beyond its native capacities, and which can look and feel as if it had always been included in the main Nautilus code base.

    With Nautilus Scripts and Extensions at your fingertips, there’s little that you can’t extend Nautilus to do. So dive in and start customizing Nautilus to suit your needs. Remember, others may also find your solutions useful, so share them around and you’ll be contributing to the community that has brought Nautilus to where it is today.