How can I write Nautilus scripts in Python?
I want to write a Nautilus script in Python. Is that possible? If it is possible, how can I do that?
Nautilus Scripts
Nautilus scripts can be written in any programming language, including python. You just need to make your python source file executable and copy it to ~/.gnome2/nautilus-scripts
in Ubuntu versions prior to 14.04. For Ubuntu 14.04 and newer the directory is different: ~/.local/share/nautilus/scripts
You will also need to add #!/usr/bin/env python
as the first line of the file. Note that by default #!/usr/bin/env python
points to Python2. If you need Python 3 specifically, use #!/usr/bin/env python3
.
Once you have done all this, the script will be accessible from the scripts
sub-menu of the right click menu in Nautilus.
See also:https://help.ubuntu.com/community/NautilusScriptsHowto
Nautilus Extensions
Nautilus extensions have more flexibility than scripts – eg. they can be used to add an item directly to the context menu. There is are python bindings available (python-nautilus).
Visit the web page of this library and view the documentation for more information.
Here is a script template and an extension template.
To restart Nautilus and reload your code, execute nautilus -q && nautilus ~
.
Scripts
This will log the environment variables which Nautilus sets for scripts to ~/script.log
. It will also log raisable errors (no syntax errors).
myscript.py
#!/usr/bin/python3
import os, logging
logpath = os.path.expanduser('~/script.log')
logging.basicConfig(
filename=logpath,
encoding='utf-8',
level=logging.DEBUG,
format='%(message)s',
)
def logenv(env):
logging.debug(os.environ[env].strip())
try:
logenv('NAUTILUS_SCRIPT_SELECTED_FILE_PATHS')
logenv('NAUTILUS_SCRIPT_SELECTED_URIS')
logenv('NAUTILUS_SCRIPT_CURRENT_URI')
#~ logenv('NAUTILUS_SCRIPT_WINDOW_GEOMETRY') # seems to be not supported any more.
except:
from traceback import format_exc as exception_as_string
logging.debug(exception_as_string())
Put the script into ~/.local/share/nautilus/scripts
. Make it executable. Restart Nautilus (see above). Select some files or folders in Nautilus and right click. The script appears under the "Scripts" menu entry.
Extensions
Extensions are a little bit more complex, but one can do more with them, e.g. chained menus are possible.
First install nautilus-python
using your package manager.
- Fedora:
sudo dnf install nautilus-python
<- can confirm, works - Debian:
sudo apt install nautilus-python
- Arch:
sudo pacman -Sy python-nautilus
Every extension needs to create a class which extends GObject.GObject
and Nautilus.MenuProvider
.
myextension.py
#!/usr/bin/python3
import os, logging
logpath = '~/extension.log'
logging.basicConfig(
filename=os.path.expanduser(logpath),
encoding='utf-8',
level=logging.DEBUG,
format='%(message)s',
)
d = logging.debug
try:
from gi.repository import Nautilus, GObject
class MyInspectExtension(GObject.GObject, Nautilus.MenuProvider):
def __init__(self):
super().__init__()
d("extension initialized")
# Hmm. This gets constantly called.
def get_file_items(self, entries):
d("---nInspect selected entries")
if len(entries) < 1:
d("nothing selected")
return []
item = Nautilus.MenuItem(
name="MyInspectExtension::inspect_selected_entries",
label="Inspect selected entries",
tip=f"Write infos about the `entries` parameter to {logpath}",
)
item.connect("activate", inspect, entries)
return [item]
# Dito.
def get_background_items(self, folder):
logging.debug("---nInspect current folder")
item = Nautilus.MenuItem(
name="MyInspectExtension::inspect_current_folder",
label="Inspect current folder",
tip=f"write infos about the `folder` parameter to {logpath}",
)
item.connect("activate", inspect, [folder])
return [item]
def inspect(menu, entries):
for thing in entries:
d('---')
for attrname in dir(thing):
if attrname.startswith('get_') or attrname.startswith('is_'):
attr = getattr(thing, attrname)
try:
if callable(attr):
d(f'{attrname}(): {attr()}')
else:
d(f'{attrname}: {attr}')
except:
pass
except:
from traceback import format_exc
d(format_exc())
Put the extension script into ~/.local/share/nautilus-python/extensions
. (Notice, nautilus-python
, not nautilus
). Make it executable. Restart Nautilus (see above).
Then, when you right-click on selected files/folders, MyInspectExtension.get_file_items
is called, when you right-click on the background, MyInspectExtension.get_background_items
is called. Both install their menu entry, and, in this case, forward to inspect
.
More extension examples can be found in the nautilus-python repo.
Nautilus seems to constantly reload extensions, every second or so. You can see this in the log, when a Nautilus instance is open. I don’t know why that is so, but it may indicate that one may not install too many and too heavy extensions.