Page 2 of 4 FirstFirst 1234 LastLast
Results 11 to 20 of 38

Thread: Extracting data from recently-used.xbel?

  1. #11
    Join Date
    Jul 2005
    Location
    I think I'm here! Maybe?
    Beans
    Hidden!
    Distro
    Xubuntu 22.04 Jammy Jellyfish

    Re: Extracting data from recently-used.xbel?

    Dolphin is not installed in Xubuntu by default; to do so will need 149 extra packages to be installed on my default Xubuntu-20.04 system, mainly because dolphon requires a lot of the KDE/qt libs etc.
    This in itself is not necessarily a problem, but geofftf made it sound as if dolphin was already installed in Xubuntu; it is not, so be warned.

  2. #12
    Join Date
    Dec 2014
    Beans
    2,579

    Re: Extracting data from recently-used.xbel?

    A bit shorter without either awk or an additional shell and with a command substitution:
    Code:
    thunar $(hxselect -c -s '\n' 'bookmark::attr(href)'<$HOME/.local/share/recently-used.xbel | sed 's![^/]*$!!' | sort -u | tr '\n' ' ')
    Both these solutions have one fatal flaw: if any of the directories does not exist because it was removed after working on files in it or because it's on external media which are not currently on line, thunar shows an error and does not open any windows. Since that's quite a normal situation - at least for me, I tend to create temporary working directories and remove them again once I'm done - this one liner is basically useless as it is. To filter out the non-existing paths we'd first need to convert the 'file://'-urls to normal paths; then we could just loop over the lines and remove any that don't exist.

    But while there are several script snippets for decoding urls on stackexchange, those are not enough in this case. If you have any special characters in your directory names - for example ampersand or apostrophe - these will have been translated to xml-entities - like &amp; and &apos;. The simplest way to translate these back into characters is to add some more substitutions to the sed script.

    In my final version I've used urlencode from the package gridsite-clients for url decoding and zenity (package zenity) to produce a graphical selection:
    Code:
    thunar "$(for i in $(hxselect -c -s '\n' 'bookmark::attr(href)'<$HOME/.local/share/recently-used.xbel | sed 's![^/]*$!!;s/&apos;/'\''/g;s/&amp;/&/g' | sort -u); do a=$(urlencode -d "$i");a=${a##file://}; if [ -d "$a" ] ; then echo $a; fi; done|zenity --width 1000 --text "Recently used directories" --list --radiolist --column="" --column="Directory Name")"
    Not exactly beautiful, but it demonstrates the software-tools philosophy: many small programs - each with one well-defined purpose - used together to do a bigger job.

    Holger

  3. #13
    Join Date
    Aug 2018
    Location
    England
    Beans
    52
    Distro
    Xubuntu

    Re: Extracting data from recently-used.xbel?

    I am very impressed Holger. That is well beyond my beginner's skills at Bash scripting. I get a warning when I run your script:

    Code:
    (zenity:3050): GLib-WARNING **: 20:08:29.209: ../../../glib/giounix.c:410Error while getting flags for FD: Bad file descriptor (9)
    Nonetheless, I was able to select a file click it and open Thunar, but the graphical window then disappeared. It would be helpful it remained in place.

    I do not understand why the OP is getting problems displaying French characters in the terminal but (I assume) not elsewhere.

    I do not know how often the .xbel file is weeded, or whether that is configurable. It may be that we need to only select files that were accessed within x days of the current date. That is getting a bit beyond a one liner.

    As far as Dolphin is concerned, I have it on my Xubuntu 20.04 system, but I did not install it. The only KDE application that I have installed is ShowFoto (DigiKam with the photo editing functions, but without the database functions). ShowFoto took a long time to install and pulled in about 600 MB of dependencies (if I remember correctly). Perhaps it pulled in Dolphin, which does seem out of place. ShowFoto loads very quickly and does not take up much RAM.

    I have got doubts about whether Dolphin would be useful to the OP. It does have recently accessed buttons on the front page, but they pull up files as well as directories.

  4. #14
    Join Date
    Dec 2014
    Beans
    2,579

    Re: Extracting data from recently-used.xbel?

    That warning could be the result of zenity actually expecting a file and not the output from a pipe ... It's trying to get some flags from the file descriptor and it seems a pipe doesn't have the flags it's looking for.

    Keeping the list window around is not possible because of the way zenity works. Once you click 'OK' the form is removed and the selection is sent to standard output.

    And it's not only the OP having problems with French characters in the .xbel file. My German umlauts encoded in UTF-8 are also shown as %XX%YY. This is because URLs were originally defined as only containing ASCII characters. So any national special characters are rewritten in the percentage-sign notation.

    AFAIK the .xbel file(s) are not weeded at all. I have three files in ~/.local/share, two of them with additional, random looking suffixes at the end. The oldest one has a date about one year after installation and the second is about one and a half years newer than the oldest.I think it waits until either an age or a size limit is reached and starts a new file. There are three time stamps stored for every bookmark in the .xbel-file. One could get these the same way as the href-attribute, probably in the same call to hxselect and with an -s option to set a separator between the URL and the timestamps.

    IMO the right way to use this would be to put it in a script, make a .desktop file for it and have that in a starter on a panel (that would also hide the warning; it would probably go into ~/xsession-errors). Or one could define a shell-function or an alias for it and have it in ~/.bashrc (and add a redirection for standard error to /dev/null to the call to zenity to hide the warnings).

    Strangely I have quite a few KDE / QT applications in my system (DigiKam, Clementine, Sigil, ...) and Dolphin has not been pulled in. Might be a difference between 18.04 and 20.04.

    Holger

  5. #15
    Join Date
    Sep 2020
    Beans
    9

    Re: Extracting data from recently-used.xbel?

    Quote Originally Posted by Holger_Gehrke View Post
    Not exactly beautiful
    Are you kidding You guys, to me this is nothing short of magical, I'm sincerely admirative of your skill and dedication. Thanks a million to you guys for powering through this dark path with your wizardy shenanigans.

    Geoff, before posting this thread I was nearly ready to switch to KDE for that feature, so I'm stoked about what you're saying. I suppose you can sort the recent folder by type to get the folders on top? (Also after 19.04 upgrade I re-installed 18.04 for its shorter booting time, but this would make me switch back - although do you find the new versions get heavier too?)

    One last trick I was trying was copying the current path on Thunar, hoping to access the now famous 'desktop settings>folder>other', but my custom action just doesn't appear when I'm in there. I can't help but wonder, the "recipe" to this folder surely is encoded somewhere?
    Last edited by erza-k-rot; September 16th, 2020 at 01:15 PM.

  6. #16
    Join Date
    Aug 2018
    Location
    England
    Beans
    52
    Distro
    Xubuntu

    Re: Extracting data from recently-used.xbel?

    Yes, Dolphin allows you to sort by type so that the folders appear on top within a directory. That is usual behaviour. Thunar provides a check box for that which is set by default. Here is the Dolphin handbook:

    https://docs.kde.org/trunk5/en/appli...in/dolphin.pdf

    As you will see Dolphin has recently saved options of today, yesterday, this month and last month on the front page.

    I am running Xubuntu 20.04 on an HP 4300 SFF that I bought from eBay for £49 including postage. It has third generation i3-3220 and 4 GB of DDR3 RAM. I have replaced the 500 GB hard disk with a Kingston A400 120 GB SSD.

    geoff@HP:~$ systemd-analyze
    Startup finished in 1.409s (kernel) + 6.633s (userspace) = 8.043s
    graphical.target reached after 6.616s in userspace

    That is quick enough for me. A used i5-3470S costs about £20 and another 4 GB about £11. Not a lot of money, but there is no point in upgrading right now.

    Lubuntu 20.04 takes about 50 MB less than Xubutu 20.04 after a fresh boot. The Lubuntu team is trying to keep the memory usage down by only using Qt5, but LibreOffice Draw is rubbish with Qt5. I am also using Google Chrome. Does that use Qt5? I doubt it.

  7. #17
    Join Date
    Aug 2018
    Location
    England
    Beans
    52
    Distro
    Xubuntu

    Re: Extracting data from recently-used.xbel?

    I have written a Python program to do this as a beginner's exercise:

    Code:
    import os
    import csv
    from datetime import date
    import urllib.parse
    import subprocess
    from tkinter import *
    
    # Do not show paths that were modified more than MaxDays before today.
    MaxDays = 100
    
    # Extract the directory path names and modification dates from the recently-used.xbel file
    path = os.environ['HOME'] + '/.local/share/recently-used.xbel'
    file = open(path)
    csv_f = csv.reader(file, delimiter = '"')
    PathDate = []
    for row in csv_f:
        if row[0] == '  <bookmark href=' and row[1][0:8] == 'file:///':
            FilePath = row[1][7:]
            ModifiedDate = row[5][:10]
            LastSlash = FilePath.rindex('/')
            DirectoryPath = FilePath[:LastSlash]
            PathDate.append(DirectoryPath + ModifiedDate)
    
    # Sort into descending order of path and then modification date.
    PathDate.sort(reverse=True)
    
    # Remove old or duplicate rows.
    Pruned = []
    PrevPath = ''
    for row in PathDate:
        Path = row[:-10]
        Year = int(row[-10:-6])
        Month = int(row[-5:-3])
        Day = int(row[-2:])
        Date = date(Year, Month, Day)
        DeltaDays = (date.today() - Date).days
        if Path != PrevPath and DeltaDays <= MaxDays:
            Pruned.append(Path)
            PrevPath = Path
    
    # Event handler for a left mouse click on a list box entry.
    def on_click_listbox(event):
        # Get the selected line index tuple.
        index = listbox.curselection()
        # Open Thunar for the selected path name.
        subprocess.Popen(['thunar', Pruned[index[0]]])
    
    # Create the root window.
    root = Tk()
    root.title("Recently Accessed Folders")
    
    # Create a Listbox and attach it to the left side of the root window.
    listbox = Listbox(root, height = 20, width = 50)
    listbox.pack(side = LEFT, fill = BOTH)
    
    # Create a Scrollbar and attach it to the right side of the root window.
    scrollbar = Scrollbar(root)
    scrollbar.pack(side = RIGHT, fill = BOTH)
    scrollbar.config(command = listbox.yview)
        
    # Attach the Listbox to the Scrollbar.
    listbox.config(yscrollcommand = scrollbar.set)
    
    # Bind a left mouse click event to the listbox.
    listbox.bind('<ButtonRelease-1>', on_click_listbox)
    
    # Insert the path names with special characters into the listbox.
    for Path in Pruned:
        listbox.insert(END, urllib.parse.unquote(Path))
    
    root.mainloop()
    You can run it by typing python3 followed by the file name in a terminal. You can set up a keyboard short cut or a desktop file as discussed before. I believe this program avoids the limitations of the terminal commands discussed previously. Special characters are displayed, we have a persistent window and we can click on as many directory names as we choose. I have set a parameter to ensure that only directories with files that were modified within the last 100 days are displayed, but that number can easily be changed in the code. It would not be difficult to add a widget to the GUI to perform that function.
    Last edited by geofftf; September 19th, 2020 at 09:31 AM.

  8. #18
    Join Date
    Dec 2014
    Beans
    2,579

    Re: Extracting data from recently-used.xbel?

    I rarely use Python, but I know that XML handling is part of the standard library (take a look at xml.dom.minidom). And since the .xbel file is XML using those functions would probably make the code shorter, more readable and more robust.

    Holger

  9. #19
    Join Date
    Aug 2018
    Location
    England
    Beans
    52
    Distro
    Xubuntu

    Re: Extracting data from recently-used.xbel?

    I expect that you are right Holger. I do not understand xml, but perhaps I should educate myself. Provided the underlying file format does not change, my code should be OK. I could make it shorter by eliminating the single use variables, but that would not help with readability. The Python documentation page for xml.dom.minidom is:

    https://docs.python.org/3/library/xml.dom.minidom.html

    That page recommends xml.etree.ElementTree for beginners like me:

    https://docs.python.org/3/library/xm...ee.ElementTree

    That is as clear as mud to me. Here is a more readable tutorial:

    https://eli.thegreenplace.net/2012/0...h-elementtree/

    Using xml.etree.ElementTree might make the code more robust to changes. Have you tried running my script? Do the umlauts show up clearly?
    Last edited by geofftf; September 19th, 2020 at 12:38 PM.

  10. #20
    Join Date
    Dec 2014
    Beans
    2,579

    Re: Extracting data from recently-used.xbel?

    Yes, both Umlauts and characters transcribed into entities (&amp; and &apos; happen to be in directory-names I have in my list of recently used files) work as they should.

    What you've forgotten about is the case of a directory having been deleted after being put in recently-used.xbel. I've tried my hand at using minidom and fixing that problem and keeping path and date separate by having dictionaries as elements of the list
    Code:
    import os
    from xml.dom import minidom
    from datetime import date
    import urllib.parse
    import subprocess
    from tkinter import *
    
    # Do not show paths that were modified more than MaxDays before today.
    MaxDays = 100
    
    # Extract the directory path names and modification dates from the recently-used.xbel file
    
    mydom=minidom.parse(os.environ['HOME'] + '/.local/share/recently-used.xbel')
    bookmarkNodeList=mydom.getElementsByTagName('bookmark')
    PathDate = []
    for bookmarkNode in bookmarkNodeList:
        filepath=bookmarkNode.getAttribute('href')
        moddate=bookmarkNode.getAttribute('modified')
        if os.path.exists(urllib.parse.unquote(filepath)[7:]):
            PathDate.append({'path':os.path.dirname(filepath),'date':moddate})
    
    def keyfunc(item):
        return item['path']+item['date']
    
    # Sort into descending order of path and then modification date.
    PathDate.sort(reverse=True,key=keyfunc)
    
    # Remove old or duplicate rows.
    Pruned = []
    PrevPath = ''
    for row in PathDate:
        Path = row['path']
        Year = int(row['date'][0:4])
        Month = int(row['date'][5:7])
        Day = int(row['date'][8:10])
        Date = date(Year, Month, Day)
        DeltaDays = (date.today() - Date).days
        if Path != PrevPath and DeltaDays <= MaxDays:
            Pruned.append(Path)
            PrevPath = Path
    
    # Event handler for a left mouse click on a list box entry.
    def on_click_listbox(event):
        # Get the selected line index tuple.
        index = listbox.curselection()
        # Open Thunar for the selected path name.
        subprocess.Popen(['thunar', Pruned[index[0]]])
    
    # Create the root window.
    root = Tk()
    root.title("Recently Accessed Folders")
    
    # Create a Listbox and attach it to the left side of the root window.
    listbox = Listbox(root, height = 20, width = 100)
    listbox.pack(side = LEFT, fill = BOTH)
    
    # Create a Scrollbar and attach it to the right side of the root window.
    scrollbar = Scrollbar(root)
    scrollbar.pack(side = RIGHT, fill = BOTH)
    scrollbar.config(command = listbox.yview)
        
    # Attach the Listbox to the Scrollbar.
    listbox.config(yscrollcommand = scrollbar.set)
    
    # Bind a left mouse click event to the listbox.
    listbox.bind('<ButtonRelease-1>', on_click_listbox)
    
    # Insert the path names with special characters into the listbox.
    for Path in Pruned:
        listbox.insert(END, urllib.parse.unquote(Path))
    
    root.mainloop()
    Holger
    Last edited by Holger_Gehrke; September 19th, 2020 at 05:05 PM. Reason: fixed a bug ...

Page 2 of 4 FirstFirst 1234 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •