5

I would like to build a Python script that checks if a specific directory is open in nautilus.

So far the best solution I have is to use wmctrl -lxp to list all windows, which gives me output like this:

0x0323d584  0 1006   nautilus.Nautilus     namek Downloads
0x0325083a  0 1006   nautilus.Nautilus     namek test
0x04400003  0 25536  gvim.Gvim             namek yolo_voc.py + (~/code/netharn/netharn/examples) - GVIM4

Then I check if the basename of the directory I'm interested in is in window name of the nautilus.Nautilus windows.

Here is the code for the incomplete solution I just described:

    def is_directory_open(dpath):
        import ubelt as ub  # pip install me! https://github.com/Erotemic/ubelt
        import platform
        from os.path import basename
        import re
        computer_name = platform.node()
        dname = basename(dpath)
        for line in ub.cmd('wmctrl -lxp')['out'].splitlines():
            parts = re.split(' *', line)
            if len(parts) > 3 and parts[3] == 'nautilus.Nautilus':
                if parts[4] == computer_name:
                    # FIXME: Might be a False positive!
                    line_dname = ' '.join(parts[5:])
                    if line_dname == dname:
                        return True
        # Always correctly returns False
        return False

This can definitely determine if it is not open, this only gets me so far, because it might return false positives. If I want to check if /foo/test is open, I can't tell if the second line refers to that directory or some other path, where the final directory is named test. E.g. I can't differentiate /foo/test from /bar/test.

Is there any way to do what I want using builtin or apt-get / pip installable tools on Ubuntu?

Erotemic
  • 3,688
  • 4
  • 28
  • 59
  • Have you looked at https://wiki.gnome.org/Projects/NautilusPython ? – SomeGuyOnAComputer Jan 21 '19 at 08:30
  • @Erotemic, I might be willing to explore SomeGuyOnAComputer's suggestion. You will need access to the following directory: `~/.local/share/nautilus-python/extensions`. Do you have write access to that directory, and is putting a file there a viable solution for you? – Him Jan 21 '19 at 15:46
  • This is not very clear regarding your final aim. From my viewpoint I think you want to know if nautilus or any application has opened this directory ? In this case, you need to use some system features. – sancelot Jan 22 '19 at 08:29
  • My final aim is to put this in my gvim-toolkit (https://github.com/Erotemic/vimtk), which provides commands to interact with a window system. This question is with respect to the nautilus backend. So, I just care if there is a nautilus window that is currently displaying the directory in the background. (If it is open my application will simply bring the window into focus, otherwise it will open it). – Erotemic Jan 23 '19 at 14:25

1 Answers1

2

Using @SomeGuyOnAComputer's suggestion:

First, get the nautilus python bindings:

$ sudo apt install python-nautilus

Make a directory to hold your nautilus python extensions:

$ mkdir -p ~/.local/share/nautilus-python/extensions

Apparently, nautilus python just reads extensions that are in that folder and uses them automagically.

Here is a simple extension that puts the file uri into the title bar:

from gi.repository import Nautilus, GObject, Gtk

class ColumnExtension(GObject.GObject, Nautilus.LocationWidgetProvider):
    def __init__(self):
        pass

    def get_widget(self, uri, window):
        window.set_title(uri)

Put this into "extension.py" and dump it into the above created folder. Restart nautilus. As in kill any nautilus processes and restart them. A simple way to do this is to simply reboot your machine.

This puts the file uri into the title bar, which is what your current script scrapes. In other words, you can simply continue doing what you've been doing, and it will now give you the full path.

Note that this doesn't seem to work when Nautilus first starts up. You have to actually navigate somewhere. In other words, if the title bar says "Home", you are in the home folder, and haven't navigated anywhere.

Him
  • 4,322
  • 2
  • 17
  • 57
  • You can further clean up your python regexing with `awk`: `$ wmctrl -lxp | awk '$4 ~ /nautilus\.Nautilus/ {print $6}'` This will get file names for all open nautilus windows. – Him Jan 21 '19 at 16:29
  • This is a good start, but not quite what I was hoping for. I don't mind installing dependency packages, but I don't want to modify the default behavior of the system. The function that I'm writing is for a package that will be pip-installable on many user machines, so unfortunately I can't enforce that they all register this extension. – Erotemic Jan 23 '19 at 14:21
  • You are writing the `setup.py` for the package? [You can have `setup.py` install the extension for you.](https://stackoverflow.com/questions/26599812/using-setuptools-to-install-files-to-arbitrary-locations) You still need to apt-get install nautilus-python, though. – Him Jan 23 '19 at 14:51
  • The problem is that the current directory being viewed is a memory object that belongs to the Nautilus process. In order to share it, that memory object need be shared, or the information written to file, or to a socket, or some such thing. Since the default behavior of Nautilus does not provide the info, it is prohibitive to access it, since we need to magically know the memory address of the info and then [query the OS](https://unix.stackexchange.com/questions/34830/exploring-ram-contents) for that information. However, using extensions, we can have Nautilus share. – Him Jan 23 '19 at 14:52
  • Indeed, the above option of writing the info to the title bar is kind of hacky. You could also have the above extension share the info by, e.g., writing to a file instead of writing to the title bar. You still need an extension, though. – Him Jan 23 '19 at 14:54
  • I do have a setup.py, but installing an extension seems a bit hacky. However, based on your other two posts it seems like it is not possible otherwise. I was hoping there was a nautilus API that shared the information, but I guess not. While its a negative response it does answer my question. – Erotemic Jan 23 '19 at 15:09