git @ Cat's Eye Technologies The-Dipple / master python / open_item_location.py
master

Tree @master (Download .tar.gz)

open_item_location.py @masterraw · history · blame

# Nautilus extension for "Open Item Location" menu item on symlinks.

# SPDX-FileCopyrightText: Chris Pressey, the creator of this work, has dedicated it to the public domain.
# For more information, please refer to <https://unlicense.org/>
# SPDX-License-Identifier: Unlicense

import os
import sys
from gi.repository import Nautilus, GObject, Gio, Gtk


def debug(*args, **kwargs):
    print(*args, file=sys.stderr, flush=True, **kwargs)


class OpenItemLocationExtension(GObject.GObject, Nautilus.MenuProvider):
    def __init__(self):
        debug("OpenItemLocationExtension initialized")

    def get_file_items(self, window, files):
        debug(f"get_file_items called with {len(files)} files")

        if len(files) != 1:
            debug("Not exactly one file selected")
            return []

        file = files[0]
        debug(f"File: {file.get_name()}, URI scheme: {file.get_uri_scheme()}")

        # If the file is a symbolic link to an existing file, add menu item.
        if file.get_uri_scheme() == "file":
            file_path = file.get_location().get_path()
            is_symlink = os.path.islink(file_path)
            debug(f"Is symlink: {is_symlink}")

            if is_symlink:
                target_path = os.path.realpath(file_path)
                target_file = Gio.File.new_for_path(target_path)
                debug(f"Symlink target: {target_path}, Exists: {os.path.exists(target_path)}")

                if os.path.exists(target_path):
                    item = Nautilus.MenuItem(
                        name="OpenItemLocation::open_item_location",
                        label="Open Item Location",
                        tip="Open the folder containing the target of this symbolic link"
                    )
                    item.connect('activate', self.open_item_location, target_file)
                    debug("Menu item created and returned")
                    return [item]
                else:
                    debug("Target file does not exist")
            else:
                debug("File is not a symlink")
        else:
            debug("File is not a local file")
        
        debug("No menu item created")
        return []

    def open_item_location(self, menu, target_file):
        debug(f"open_item_location called for {target_file.get_path()}")
        parent_dir = target_file.get_parent()
        if parent_dir:
            debug(f"Opening parent directory: {parent_dir.get_path()}")

            # Note: We can't select the file in the new window using this method
            try:
                Gio.AppInfo.launch_default_for_uri(parent_dir.get_uri(), None)
                debug("Folder opened successfully")
            except GObject.GError as error:
                debug(f"Error opening folder: {error}")

        else:
            debug("Could not get parent directory")


def nautilus_module_initialize(module):
    debug("nautilus_module_initialize called")
    return OpenItemLocationExtension()