User:Spoiledbroth/ob-chromium
From Openbox
Here is a pipemenu for displaying your chromium bookmarks. Commented throughout. Depends on Perl modules HTML::Entities and JSON::Tiny (though you shouldn't need to download HTML::Entities, as it's part of the standard Perl library).
I encode the bookmark titles with HTML::Entities, and encase the bookark URL itself within a <[!CDATA[ ]]>
block as basic sanity checking before output. I'm not sure what (if any) processing of bookmark URL/titles Chrome does on the backend.
#!/usr/bin/perl # openbox-chromium 0.2a - 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 # HTML::Entities - http://search.cpan.org/dist/HTML-Parser/lib/HTML/Entities.pm use strict; use warnings; use JSON::Tiny qw(decode_json); use HTML::Entities qw(encode_entities); # === CONFIGURATION: === # Change the $bookmarks variable to reflect the location of your # chromium/google-chrome bookmarks. You can try "find ~/.config -name Bookmarks" # if you're having trouble locating the file. my $bookmarks = "/.config/chromium/Profile 1/Bookmarks"; # And here you can enter the command you use to start up your browser. # Tested with chromium and google-chrome on Debian 9.3 my $browser = "chromium"; # Maximum length of bookmark titles (characters) my $maxlength = 35; # === END CONFIGURATION === # 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; # Select only the "root" entries, only loop over what we need, essentially. my $json = $data->{'roots'}; # Build the Openbox menu header print "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" . "<openbox_pipe_menu>\n"; # Here is the main program loop... foreach my $roots (%$json) { # This is pretty shameful right here. I actually suspect I'm doing some # weird typing in the foreach loop above which causes me to have to cast # to an array... FECKING KLUDGE my @folders = $roots; foreach my $i (0 .. $#folders) { # and then check if the supplied ref is a hash- otherwise # we end up with some weird arrays containing only the "root" # name of the bookmarks folder... Hope to fix in 0.3 if ( (ref($folders[$i]) eq 'HASH') && # This line allows us to skip printing any "root" folders with # no children. (0+@{$folders[$i]->{'children'}} != 0) ) { # Now we can print the root folder destinations print "<menu id=\"".$folders[$i]->{'id'}."\" label=\"".encode_entities($folders[$i]->{'name'})."\">\n"; if ($folders[$i]->{'type'} eq "folder") { # lastly we start recursion over the children foreach my $sub_children ($folders[$i]->{'children'}) { # And let your backbone sliiiide... recurse($sub_children); print "</menu> \n"; } } } } } # EOM print "</openbox_pipe_menu>\n"; # Recursion function for bookmark "folders" sub recurse { my ($obtained) = @_; my @thing = @{$obtained}; foreach my $t (0 .. $#thing) { # If it's a folder with children, print and recurse if ( ($thing[$t]->{'type'} eq "folder") && (0+@{$thing[$t]->{'children'}} != 0) ) { print "<menu id=\"".$thing[$t]->{'id'}."\" label=\"".encode_entities($thing[$t]->{'name'})."\"> \n"; my @folder = $thing[$t]->{'children'}; foreach my $z (0 .. $#folder) { recurse($folder[$z]); } print "</menu>\n"; } elsif ($thing[$t]->{'type'} eq "url") { $_ = scalar $thing[$t]{'name'}; $_ =~ s/^(.{1,$maxlength})(.+)?/$1 . (defined $2 ? "..." : "")/e; print "<item label=\"".encode_entities($_)."\">\n" . " <action name=\"Execute\">\n" . " <execute>\n" . " ".$browser." <![CDATA[".$thing[$t]->{'url'}."]]>\n" . " </execute>\n" . " </action>\n" . "</item>\n"; } } return; }