X-Git-Url: https://git.donarmstrong.com/?p=bin.git;a=blobdiff_plain;f=bibtex_to_paper;h=a6350eb98caedfecffcac5d9b248c5ac41760660;hp=121a85544354bf60f8f2c2336371f1d8f1802713;hb=HEAD;hpb=7f5ebb78dfe45ece2ce9f461aebbdf067381c426 diff --git a/bibtex_to_paper b/bibtex_to_paper index 121a855..a6350eb 100755 --- a/bibtex_to_paper +++ b/bibtex_to_paper @@ -18,6 +18,7 @@ use File::Spec qw(rel2abs); use Text::BibTeX; use User; use Data::Printer; +use POSIX; use DBI; @@ -33,8 +34,10 @@ bibtex_to_paper [options] bibtexkey --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 @@ -56,6 +59,10 @@ Bibtex cache file; rebuilt if bibtex file changes 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) @@ -82,6 +89,10 @@ use vars qw($DEBUG); my %options = (debug => 0, help => 0, man => 0, + only_print => 0, + search_by_pmid => 0, + search_by_file => 0, + use_git => 1, 'bibtex_cache' => File::Spec->catfile(User->Home,'.bibtex_to_paper_cache'), ); @@ -90,6 +101,10 @@ GetOptions(\%options, '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!', + 'search_by_file|search-by-file!', 'clear_cache|clear-cache!', 'papers_directory|papers-directory=s@', 'debug|d+','help|h|?','man|m'); @@ -145,13 +160,17 @@ sub main{ 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; @@ -172,21 +191,27 @@ sub load_papers_into_database { my @dirs = ref($dir)?@{$dir}:$dir; - my $actually_load_it = sub { - if (/\.git/) { - $File::Find::prune = 1; - return; - } - 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 { @@ -199,7 +224,7 @@ sub load_bibtex_entries_into_database { 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; } @@ -210,7 +235,14 @@ sub open_bibtex_key { 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); + } elsif ($options->{search_by_file}) { + $entry = select_entry_from_file($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); } @@ -223,6 +255,11 @@ sub fork_exec { 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 (STDERR, ">&STDOUT"); exec(@cmd); } else { return $child; @@ -233,11 +270,11 @@ sub fork_exec { 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{ @@ -249,6 +286,10 @@ sub open_entry{ 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) { @@ -260,30 +301,59 @@ sub open_entry{ 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_file{ + my ($dbh,$sth,$filename) = @_; + + return select_one($dbh,$sth->{select_bibtex_by_file_name_like},'%'.$filename.'%'); +} + + 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; } @@ -324,11 +394,13 @@ sub parse_bibtex_file { 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}} = @@ -368,6 +440,7 @@ sub open_cache { CREATE TABLE bibtex ( bibtex_key TEXT PRIMARY KEY, file_name TEXT, +pmid TEXT, doi TEXT, html TEXT ); @@ -377,6 +450,9 @@ CREATE UNIQUE INDEX bibtex_file_name ON bibtex(file_name); EOF $dbh->do(<do(<do(< <<'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_papers_by_pmid => <<'EOF', +SELECT * FROM papers JOIN bibtex ON papers.file_name = bibtex.file_name WHERE bibtex.pmid = ?; +EOF + select_papers_by_name_like => <<'EOF', SELECT * FROM papers WHERE file_name LIKE ?; EOF select_papers_by_path => <<'EOF', @@ -416,6 +495,12 @@ SELECT * FROM bibtex WHERE bibtex_key LIKE ?; EOF select_bibtex_by_file_name => <<'EOF', SELECT * FROM bibtex WHERE file_name = ?; +EOF + select_bibtex_by_file_name_like => <<'EOF', +SELECT * FROM bibtex WHERE file_name LIKE ?; +EOF + select_bibtex_by_pmid => <<'EOF', +SELECT * FROM bibtex WHERE pmid = ?; EOF clear_papers_cache => <<'EOF', DELETE FROM papers;