User:Spoiledbroth/ob-chromium
From Openbox
Here is a pipemenu for displaying your chromium bookmarks. Commented throughout. Depends on Perl module JSON::Tiny.
I encase the bookark URL itself within a <[!CDATA[ ]]>
block as some kind of prophylactic measure before output. I'm not sure what (if any) processing of bookmark URL/titles Chrome does on the backend.
#!/usr/bin/perl # openbox-chromium 1.0-beta - openbox chrome browser bookmarks pipemenu # Copyright (C) 2018 http://openbox.org/wiki/User:Spoiledbroth # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # === DEPENDENCIES: === # JSON::Tiny - http://search.cpan.org/~davido/JSON-Tiny-0.58/lib/JSON/Tiny.pod use strict; use warnings; use JSON::Tiny qw(decode_json); # === CONFIGURATION: === # $bookmarks - Location of your chromium/google-chrome bookmarks. # You can try "find ~/.config -name Bookmarks" if you're having finding it. # $browser - browser command, either x-www-browser, chromium or google-chrome # $maxlength - upper limit of characters for bookmark titles my $bookmarks = "/home/marston/.config/chromium/Profile 1/Bookmarks"; my $browser = "chromium"; my $maxlength = 35; # Lets open up that bookmarks file my $file = do { local $/ = undef; open my $fh, "<", $bookmarks or die "could not open $bookmarks: $!"; <$fh> }; # Now, get the bookmark JSON into a reference my $data = decode_json $file; # Cast that reference to a hash of the 'roots' entries in the bookmark file. my %json = %{$data->{'roots'}}; # ... so we only loop over what we need, essentially. # Build the Openbox menu header print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" . "<openbox_pipe_menu>\n"; # Main program loop... foreach (keys %json) { traversal ($data->{'roots'}->{$_}); } # End of menu print "</openbox_pipe_menu>\n"; # Recursion function for bookmark "folders" sub traversal { my ($obtained) = @_; # If the entry is a folder with >0 children, build an entry and recurse if (($obtained->{'type'} eq "folder") && (0+@{$obtained->{'children'}} != 0)) { build_entry($obtained); my @children = @{$obtained->{'children'}}; foreach my $i (0 .. $#children) { traversal($children[$i]); } print "</menu>\n"; # I'm not perfect... # Else, we need to build an entry for a URL. } elsif ($obtained->{'type'} eq "url") { build_entry($obtained); } return; } # Function to build the menu (seperation of concerns) sub build_entry { my ($entry) = @_; if ($entry->{'type'} eq "folder") { # print case for bookmark folder print " <menu id=\"" .$entry->{'id'}."\" label=\"".$entry->{'name'}."\">\n"; } elsif ($entry->{'type'} eq "url") { # print case for bookmark link my $truncated = scalar $entry->{'name'}; $truncated =~ s/^(.{1,$maxlength})(.+)?/$1 . (defined $2 ? "..." : "")/e; print " <item label=\"".$truncated."\">\n" . " <action name=\"Execute\">\n" . " <execute>\n" . " ".$browser." <![CDATA[".$entry->{'url'}."]]>\n" . " </execute>\n" . " </action>\n" . " </item>\n"; } return; }