pythonlinuxgtk3bookmarksthunar

Python script fails to change Thunar bookmarks


I'm using Linux and I am writing a script that edits the Thunar bookmarks, but I'm having some issues.

I have the following Python code:

if os.path.exists("/home/user/.config/gtk-3.0/bookmarks"):
    with open("/home/user/.config/gtk-3.0/bookmarks", 'r') as self.file:
        self.bookmarks = self.file.readlines()
        for i in range(len(self.bookmarks)):
            if "/home/user/MyBookmark" in self.bookmarks[i]:
                self.bookmarks.pop(i)
    print(self.bookmarks)
    file.close()
    
    with open("/home/user/.config/gtk-3.0/bookmarks", 'w') as file:
        for bookmark in self.bookmarks:
            print(bookmark)
            file.write(bookmark)
    file.close()

What it does is basically remove MyBookmark from thunar bookmarks, this code is in a PySide6 script, and it is not working fully, it is executed when I start the program, and it removes the bookmark as intended, but as soon as I end the execution, the bookmarks are restored and MyBookmark returns.

This is the only time in the whole script that I'm touching bookmarks.

I found out that this issue only happens if I'm with thunar open while running the program, so I did

os.system('killall thunar 2>/dev/null')

Before running the part that changes it, and it works, but for obvious reasons it isn't the best solution.

Does anyone know about anything that could be causing this trouble? Is there another solution for this?


Solution

  • In your code, when you pop at an index, it delete the list element and shift everything up, which makes you miss the next item. Here is a demonstration. Suppose your file looks like this:

    foo
    bar
    /home/user/MyBookmark/1
    /home/user/MyBookmark/2
    last
    

    When you pop at index 2, the list becomes

    foo
    bar
    /home/user/MyBookmark/2
    last
    

    and you move on to index 3, which means you did not process the ../MyBookmark/2 line.

    Here is a fix: use list comprehension:

    with open("bookmarks") as stream:
        lines = [line for line in stream if "/home/user/MyBookmark" not in line]
    
    with open("bookmarks", "w") as stream:
        stream.writelines(lines)
    

    The first with block will gather all the lines that does not contain your specific text. The next block then write these lines out.