|
|
- #!/usr/bin/env perl
-
- =pod
-
- =head1 NAME
-
- notes-links - work with links within my notes
-
- =head1 SYNOPSIS
-
- Currently this is vimwiki-dependent.
-
- # List pages linking to foo:
- notes links --target foo
-
- # Pages linking to foo.wiki:
- notes links --file ./foo.wiki
-
- # Pages with a date (i.e. logs and diaries) linking to foo:
- notes links --with-date --target foo
-
- # Links in foo (experimental, probably broken):
- notes links --source foo
-
- # Format (defaults to location):
- notes links --format target
-
- =head1 OUTPUT FORMATS
-
- B<--format> options include C<vimwiki>, C<tsv>, C<location>, C<target>,
- C<full>, and C<name>.
-
- Formats may be glitchy.
-
- =head1 AUTHOR
-
- Brennen Bearnes
-
- =cut
-
- use warnings;
- use strict;
- use 5.10.0;
-
- use Cwd;
- use Data::Dumper;
- use DBI;
- use File::Basename;
- use File::Spec;
- use Getopt::Long;
- use Pod::Usage;
- use SQL::Abstract;
- use Sys::Hostname;
-
- # Display formats:
- my %FORMATS = (
- vimwiki => sub {
- my ($data) = @_;
- my $timestamp = '';
- if (defined $data->{timestamp}) {
- $timestamp = $data->{timestamp} . " ";
- }
-
- return ' - '
- . $timestamp
- . '[[/' . $data->{page} . '|'
- . $data->{title}
- . "]]\n";
- },
-
- tsv => sub {
- my ($data) = @_;
- my $timestamp = '(null)';
- if (defined $data->{timestamp}) {
- $timestamp = $data->{timestamp};
- }
- return (join "\t", ($timestamp, $data->{page}, $data->{title})) . "\n";
- },
-
- # vim location list
- #
- # TODO: Note that the "1" here is, theoretically, a line number.
- # Unfortunately, there's no obvious way to extract that from Pandoc's parsing
- # of the original file, and thus no non-hacky way for notes-collect-metadata to
- # store an approximate value in the database. We _could_ read the file
- # line-by-line, or run grep, looking for the file's basename, but this is
- # tricky to get right.
- #
- # If I keep using this long-term, I should solve this problem.
- location => sub {
- my ($data) = @_;
-
- my $result = "$ENV{HOME}/notes/vimwiki/$data->{page}.wiki";
- if ($data->{title}) {
- $result .= ":1:$data->{title}";
- } else {
- $result .= print ":1:$data->{page}"
- }
-
- return $result . "\n";
- },
-
- # List of bare link _target_ names
- target => sub {
- my ($data) = @_;
- return $data->{target} . "\n";
- },
-
- # Fulltext of vimwiki pages:
- full => sub {
- my ($data) = @_;
- my $result = '';
- my $pagepath = "$ENV{HOME}/notes/vimwiki/$data->{page}.wiki";
- $result .= "%% $pagepath {{{\n\n";
- $result .= file_get_contents($pagepath);
- $result .= "\n%% }}}\n\n";
-
- return $result;
- },
-
- # Bare names of wiki pages (no extension):
- name => sub {
- my ($data) = @_;
- return $data->{page} . "\n";
- },
- );
-
- # Handle options, including help generated from the POD above.
- my $debug = 0;
- my $with_date = 0;
- my $target;
- my $source;
- my $file;
- my $format = 'location';
- GetOptions(
- 'debug' => \$debug,
- 'target=s' => \$target,
- 'file=s' => \$file,
- 'format=s' => \$format,
- 'with-date' => \$with_date,
- 'help' => sub { pod2usage(0) },
- ) or pod2usage(2);
-
- if (defined $file)
- {
- my ($name, $path, $suffix) = fileparse($file, '.wiki');
-
- # XXX: This is a dirty fucking hack - get rid of the leading path stuff, but
- # keep subdirs within the vimwiki directory:
- $path =~ s{^.*?notes/vimwiki/}{};
-
- $target = $path . $name;
- }
-
- my %where = ();
-
- # Require that the link point to a given page:
- if (defined $target) {
- $where{target} = $target;
- }
-
- # Get only links from pages that have a datetime:
- if ($with_date) {
- # NOT NULL:
- $where{'pages.datetime'} = { '!=', undef };
- }
-
- my $dbfile = $ENV{HOME} . "/notes/metadata.db";
- my $dbh = DBI->connect("dbi:SQLite:dbname=$dbfile", "", "");
-
- my $sql = SQL::Abstract->new;
- my ($query, @bind) = $sql->select(
- 'links JOIN pages ON links.page = pages.page',
- # timestamp will be null if datetime is
- "*, DATETIME(datetime, 'localtime') AS timestamp",
- \%where,
- {-desc => [ 'datetime', 'page' ] }
- );
-
- if ($debug) {
- say STDERR $query;
- say STDERR Dumper(%where);
- }
-
- my $sth = $dbh->prepare($query);
- $sth->execute(@bind);
-
- while (my $data = $sth->fetchrow_hashref())
- {
- if ($debug) {
- print STDERR Dumper($data);
- }
-
- print $FORMATS{$format}->($data);
- }
-
- $sth->execute();
-
- # PHP-style file-content grabbing:
- sub file_get_contents {
- my ($file) = @_;
-
- open my $fh, '<', $file
- or die "Couldn't open $file: $!\n";
-
- my $contents;
- {
- # line separator:
- local $/ = undef;
- $contents = <$fh>;
- }
-
- close $fh or die "Couldn't close $file: $!";
- return $contents;
- }
-
- 1;
|