use Text::BibTeX;
use User;
use Data::Printer;
+use POSIX;
use DBI;
--bibtex, -b bibtex file to look up key in
--bibtex-cache, -c bibtex cache file
--build-cache, -B build cache using bibtex files
+ --search-by-pmid Search term is a pmid instead of a bibtex key
--pdf-dir pdf directory
--pdfviewer, -p pdf viewer to use
+ --only-print Only print PDF file name
--debug, -d debugging level (Default 0)
--help, -h display this help
--man, -m display manual
PDF viewer to use; defaults to evince unless a .xoj exists, in which
case xournal is used.
+=item B<--only-print>
+
+Only print the PDF file name, don't open it.
+
=item B<--debug, -d>
Debug verbosity. (Default 0)
my %options = (debug => 0,
help => 0,
man => 0,
+ only_print => 0,
+ search_by_pmid => 0,
+ use_git => 1,
'bibtex_cache' => File::Spec->catfile(User->Home,'.bibtex_to_paper_cache'),
);
'bibtex|b=s@',
'bibtex_cache|bibtex-cache|c=s',
'pdfviewer|p=s',
+ 'use_git|use-git!',
+ 'only_print|only-print!',
+ 'search_by_pmid|search-by-pmid!',
'clear_cache|clear-cache!',
'papers_directory|papers-directory=s@',
'debug|d+','help|h|?','man|m');
if (exists $options{papers_directory} and
defined $dbh
) {
+ $dbh->begin_work;
load_papers_into_database($dbh,$sth,$options{papers_directory});
+ $dbh->commit;
}
p %entries if $DEBUG;
if (keys %entries and
defined $dbh) {
+ $dbh->begin_work;
load_bibtex_entries_into_database($dbh,$sth,\%entries);
+ $dbh->commit;
}
p @ARGV if $DEBUG;
my @dirs = ref($dir)?@{$dir}:$dir;
- my $actually_load_it = sub {
- return unless /\.pdf$/;
- my $xoj = 0;
- if (-e "${_}.xoj") {
- $xoj = 1;
+ if ($options{use_git}) {
+ my @files = grep /\.pdf\"?$/, split /\n/, qx(git ls-tree HEAD -r --full-name --name-only);
+ for my $file (@files) {
+ $file =~ s/^\"(.+)\"$/"qq($1)"/gee;
+ insert_or_replace_papers($dbh,$sth,basename($file),File::Spec->rel2abs($file), -e "${file}.xoj");
}
- insert_or_replace_papers($dbh,$sth,basename($File::Find::name),File::Spec->rel2abs($_),$xoj);
- };
-
- my @pdfs;
- find($actually_load_it,@dirs);
+ } else {
+ my $actually_load_it = sub {
+ if (/\.git/) {
+ $File::Find::prune = 1;
+ return;
+ }
+ return unless /\.pdf$/;
+ my $xoj = 0;
+ if (-e "${_}.xoj") {
+ $xoj = 1;
+ }
+ insert_or_replace_papers($dbh,$sth,basename($File::Find::name),File::Spec->rel2abs($_),$xoj);
+ };
+ find($actually_load_it,@dirs);
+ }
}
sub insert_or_replace_papers {
my ($dbh,$sth,$entries) = @_;
for my $entry (keys %{$entries}) {
next unless defined $entries->{$entry};
- $sth->{insert_bibtex}->execute($entry,@{$entries->{$entry}}{qw(file_name doi html)});
+ $sth->{insert_bibtex}->execute($entry,@{$entries->{$entry}}{qw(file_name pmid doi html)});
$sth->{insert_bibtex}->finish();
print STDERR "inserted $entry {".join(',',map {defined $_?"'$_'":"'undef'"} %{$entries->{$entry}})."}\n" if $DEBUG;
}
if (not defined $dbh) {
open_entry($dbh,$sth,$entries->{$bibtex_key},$options);
} else {
- my $entry = select_entry_from_bibtex_key($dbh,$sth,$bibtex_key);
+ my $entry;
+ if ($options->{search_by_pmid}) {
+ $entry = select_entry_from_pmid($dbh,$sth,$bibtex_key);
+ } else {
+ $entry = select_entry_from_bibtex_key($dbh,$sth,$bibtex_key);
+ }
p $entry if $DEBUG;
open_entry($dbh,$sth,$entry,$options);
}
die "Unable to fork for some reason: $!";
}
if ($child == 0) {
+ foreach (0 .. (POSIX::sysconf (&POSIX::_SC_OPEN_MAX) || 1024))
+ { POSIX::close $_ }
+ open (STDIN, "</dev/null");
+ open (STDOUT, ">/dev/null");
+ open (STDERR, ">&STDOUT");
exec(@cmd);
} else {
return $child;
sub open_pdf {
my ($file_name,$options,$has_xoj) = @_;
print STDERR "opening $file_name\n" if $DEBUG;
- if ($has_xoj) {
- fork_exec('xournal',$file_name);
- } else {
- fork_exec('evince',$file_name)
+ my $pdf_viewer = 'xournal';
+ if (exists $options->{pdfviewer} and defined $options->{pdfviewer}) {
+ $pdf_viewer = $options->{pdfviewer};
}
+ fork_exec($pdf_viewer,$file_name);
}
sub open_browser{
my ($dbh,$sth,$entry,$options) = @_;
return unless defined $entry and ref $entry and keys %{$entry};
+ if ($DEBUG) {
+ print STDERR "Entry: \n";
+ p $entry;
+ }
if (defined $entry->{file_name} and length $entry->{file_name}) {
my $paper = select_one($dbh,$sth->{select_papers_by_name},$entry->{file_name});
if (not defined $paper) {
p $paper if $DEBUG;
print STDERR $entry->{file_name} if $DEBUG;
if (defined $paper) {
+ if ($options->{only_print}) {
+ print $paper->{path};
+ return;
+ }
open_pdf($paper->{path},$options,$paper->{has_xoj});
return;
+ } else {
+ print STDERR "Unable to find paper\n" if $DEBUG;
}
}
if (defined $entry->{doi}) {
+ if ($options->{only_print}) {
+ print $entry->{doi};
+ return;
+ }
my $url = $entry->{doi};
$url =~ s{^doi://}{http://dx.doi.org/};
open_browser($url,$options);
return;
}
if (defined $entry->{html}) {
+ if ($options->{only_print}) {
+ print $entry->{html};
+ return;
+ }
open_browser($entry->{html},$options);
return;
}
}
+sub select_entry_from_pmid{
+ my ($dbh,$sth,$pmid) = @_;
+
+ return select_one($dbh,$sth->{select_bibtex_by_pmid},$pmid);
+}
+
+
sub select_entry_from_bibtex_key{
my ($dbh,$sth,$bibtex_key) = @_;
my $entry = select_one($dbh,$sth->{select_bibtex_by_key},$bibtex_key);
if (not defined $entry) {
+ print STDERR "Unable to find entry by exact search\n" if $DEBUG;
$bibtex_key =~ s/:.*$//;
$entry = select_one($dbh,$sth->{select_bibtex_by_approximate_key},$bibtex_key.'%');
}
+ print STDERR "Found entry\n" if $DEBUG and defined $entry;
return $entry;
}
my %field_prefix = (doi => 'doi://',
html => 'http://',
file => '',
+ pmid => '',
);
my %field_name = (doi => 'doi',
html => 'html',
+ pmid => 'pmid',
file => 'file_name',);
- for my $field (qw(file doi html)) {
+ for my $field (qw(file doi html pmid)) {
my $field_value = $entry->get($field);
if (defined $field_value and $field_value =~ /\S+/) {
$entry_data{$field_name{$field}} =
CREATE TABLE bibtex (
bibtex_key TEXT PRIMARY KEY,
file_name TEXT,
+pmid TEXT,
doi TEXT,
html TEXT
);
EOF
$dbh->do(<<EOF);
CREATE UNIQUE INDEX bibtex_bibtex_key ON bibtex(bibtex_key);
+EOF
+ $dbh->do(<<EOF);
+CREATE INDEX bibtex_pmid ON bibtex(pmid);
EOF
$dbh->do(<<EOF);
CREATE TABLE papers (
INSERT OR REPLACE INTO papers(file_name,path,has_xoj) VALUES (?,?,?);
EOF
insert_bibtex => <<'EOF',
-INSERT OR REPLACE INTO bibtex (bibtex_key,file_name,doi,html) VALUES (?,?,?,?);
+INSERT OR REPLACE INTO bibtex (bibtex_key,file_name,pmid,doi,html) VALUES (?,?,?,?,?);
EOF
select_papers_by_name => <<'EOF',
SELECT * FROM papers WHERE file_name = ?;
EOF
select_bibtex_by_file_name => <<'EOF',
SELECT * FROM bibtex WHERE file_name = ?;
+EOF
+ select_bibtex_by_pmid => <<'EOF',
+SELECT * FROM bibtex WHERE pmid = ?;
EOF
clear_papers_cache => <<'EOF',
DELETE FROM papers;