Skip to content

Instantly share code, notes, and snippets.

@z448
Last active April 7, 2023 13:02
Show Gist options
  • Save z448/1c27621fad750bcc969f72ef4112af1f to your computer and use it in GitHub Desktop.
Save z448/1c27621fad750bcc969f72ef4112af1f to your computer and use it in GitHub Desktop.
search iOS Safari bookmarks from commandline or export for Firefox
#!/usr/bin/env perl
# work in progress (use revision 3 https://gist.github.com/z448/1c27621fad750bcc969f72ef4112af1f/64709b1fededfef305f360df73d3ece07f297833)
use 5.010;
use warnings;
use strict;
use Data::Dumper;
use JSON::PP;
my $filter = $ARGV[0] || '.';
my $json = <DATA>;
my $conf = decode_json $json;
#die Dumper($conf);
sub get_bookmarks {
my ($path, $sql) = @_;
my $select = qq|sqlite3 '$path' "$sql"|;
my @bookmarks = ();
push my @select, `$select`;
for my $line(@select){
chomp($line);
my %ios;
( $ios{title}, $ios{url} ) = split( /\|/, $line );
push @bookmarks, {%ios};
}
return \@bookmarks;
}
sub export {
my @export = @{get_bookmarks("$conf->{safari}->{path}", $conf->{safari}->{sql})};
open(my $fh,'>', "$ENV{HOME}/bookmarks.html") || die "cant open file: $!";
say $fh '<DT><A HREF="' . $_->{url} . '">' . $_->{title} . '</A>' for @export;
say "$ENV{HOME}/bookmarks.html";
}
# work in progres
sub import {
my ($b, $path, $sql) = @_;
#time
use Time::HiRes;
$b->{dateAdded} = Time::HiRes::time();
$b->{dateAdded} = s/\.//;
# reverse url
$b->{rev_host} = $b->{url};
$b->{rev_host} =~ s/(.*?\:\/\/)(.*?)(\/.*)/$2/;
$b->{rev_host} = scalar reverse $2; $b->{rev_host} = $b->{rev_host} . '.';
# guid
my @chars = ("A".."Z", "a".."z");
$b->{guid} .= $chars[rand @chars] for 1..12;
# insert
my $tmp_sql = qq|sqlite3 '$path' "insert into moz_places (url, title, rev_host, frecency, guid, foreign_count) values( $b->{url}, $b->{title}, $b->{rev_host}, 140, $b->{guid}, 1";|;
`$tmp_sql`;
# moz_hosts - ->118|ebi.ac.uk|140|0|
# moz_places - ->485|http://www.ebi.ac.uk/Tools/msa/muscle/||ku.ca.ibe.www.|0|0|0||140||EM8r2VUJIWKl|1
# moz_bookmarks - ->213|1|485|2|48|MUSCLE|||1478965099312000|1478965099312000|GNXU-wa_1JTj
}
sub search {
print Dumper(grep{ $_->{url} =~ /$filter/ or $_->{title} =~ /$filter/ } @{get_bookmarks("$conf->{safari}->{path}", $conf->{safari}->{sql})})
}
unless($ARGV[0]){ export } else { search }
=head1 NAME
bookmarks.pl
=head1 SYNOPSIS
Search Safari bookmarks or export them for Firefox.
=head1 USAGE
list all bookmarks: C<bookmarks.pl .>
search bookmarks: C<bookmarks.pl filter_keyword>
export bookmarks: C<bookmarks.pl>
=cut
__DATA__
{"safari":{"description":"mobilesafari for ios","path":"Bookmarks.db","sql":"select title, url from bookmarks where url != '';"},"firefox":{"description":"firefox on osx","path":"/Users/zdenek/Library/Application Support/Firefox/Profiles/ls6e2p3m.default/places.sqlite","sql":"select title, url from moz_places where foreign_count = 1 and url != '';"}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment