You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
9.4 KiB

#!/usr/bin/env python
import sys, os
import datetime
import shutil
import tempfile
import textwrap
from subprocess import call
import webbrowser
import urllib
13 years ago
import ConfigParser
13 years ago
import yaml
try:
import pybtex
13 years ago
import pybtex.database
import pybtex.database.input
import pybtex.database.input.bibtex
import pybtex.database.input.bibtexml
import pybtex.database.input.bibyaml
import pybtex.database.output
import pybtex.database.output.bibtex
import pybtex.database.output.bibtexml
import pybtex.database.output.bibyaml
except ImportError:
print '{}error{}: you need to install Pybtex; try running \'pip install pybtex\'.'.format(red, end)
# display
bold = '\033[1m'
end = '\033[0m'
black = '\033[0;30m'
red = '\033[0;31m'
green = '\033[0;32m'
yellow = '\033[0;33m'
blue = '\033[0;34m'
purple = '\033[0;35m'
cyan = '\033[0;36m'
grey = '\033[0;37m'
# Bold
bblack = '\033[1;30m'
bred = '\033[1;31m'
bgreen = '\033[1;32m'
byellow = '\033[1;33m'
bblue = '\033[1;34m'
bpurple = '\033[1;35m'
bcyan = '\033[1;36m'
bgrey = '\033[1;37m'
# utility functions
13 years ago
currentdir = os.getcwd()
papersdir = None
def find_papersdir():
global papersdir
curdir = os.path.abspath(os.getcwd())
while curdir != '':
if os.path.exists(curdir + '/.papers') and os.path.isdir(curdir + '/.papers'):
papersdir = curdir + '/.papers'
curdir = ''
if curdir == '/':
curdir = ''
else:
curdir = os.path.split(curdir)[0]
if papersdir is None:
print '{}error{} : no papers repo found in this directory or in any parent directory.{}'.format(red, grey, end)
exit(0)
def write_configfile(config, filepath):
try:
with open(filepath, 'w') as f:
config.write(f)
except IOError as e:
print '{}error{} : impossible to write on file {}{:s}{}'.format(red, grey, cyan, filepath, end)
print 'Verify permissions'
exit(-1)
def write_papers(config):
write_configfile(config, papersdir + os.sep + 'papers')
def read_configfile(filepath):
try:
with open(filepath, 'r') as f:
config = ConfigParser.ConfigParser()
config.readfp(f)
return config
except IOError as e:
print '{}error{} : impossible to read file {}{:s}{}'.format(red, grey, cyan, filepath, end)
print 'Verify permissions'
exit(-1)
def read_papers():
return read_configfile(papersdir + os.sep + 'papers')
13 years ago
def vim_input(initial = ""):
"""Use an editor to get input"""
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=False) as temp_file:
tfile_name = temp_file.name
temp_file.write(initial)
temp_file.flush()
call([EDITOR, tfile_name])
with open(tfile_name) as temp_file:
content = temp_file.read()
os.remove(tfile_name)
return content
def load_externalbibfile(fullbibpath):
check_file(fullbibpath)
filename, ext = os.path.splitext(os.path.split(fullbibpath)[1])
if ext == '.bib':
parser = pybtex.database.input.bibtex.Parser()
bib_data = parser.parse_file(fullbibpath)
elif ext == '.xml' or ext == '.bibtexml':
parser = pybtex.database.input.bibtexml.Parser()
bib_data = parser.parse_file(fullbibpath)
elif ext == '.yaml' or ext == '.bibyaml':
parser = pybtex.database.input.bibyaml.Parser()
bib_data = parser.parse_file(fullbibpath)
else:
print '{}error{}: {}{}{} not recognized format for bibliography{}'.format(red, grey, cyan, ext, grey, end)
return bib_data
13 years ago
def load_bibfile(filename):
fullbibpath = papersdir + os.sep + 'bibdata' + os.sep + filename
return load_externalbibfile(fullbibpath)
13 years ago
def write_bibfile(bib_data, filename):
filepath = papersdir + os.sep + 'bibdata' + os.sep + filename + '.bibyaml'
with open(filepath, 'w') as f:
parser = pybtex.database.output.bibyaml.Writer()
parser.write_stream(bib_data, f)
def write_meta(meta_data, filename):
filepath = papersdir + os.sep + 'meta' + os.sep + filename + '.meta'
with open(filepath, 'w') as f:
meta_data.write(f)
def check_file(filepath):
if not os.path.exists(filepath):
print '{}error{}: {}{}{} does not exists{}'.format(red, grey, cyan, filepath, grey, end)
exit(-1)
if not os.path.isfile(filepath):
print '{}error{}: {}{}{} is not a file{}'.format(red, grey, cyan, filepath, grey, end)
exit(-1)
13 years ago
def person_repr(p):
return ' '.join(s for s in [' '.join(p.first(abbr = True)),
' '.join(p.middle(abbr = True)),
' '.join(p.prelast(abbr = False)),
' '.join(p.last(abbr = False)),
' '.join(p.lineage(abbr = True))] if s)
def bib_oneliner(bib_data):
13 years ago
article = bib_data.entries[list(bib_data.entries.keys())[0]]
authors = ', '.join(person_repr(p) for p in article.persons['author'])
title = article.fields['title']
year = article.fields['year']
journal = article.fields['journal']
return '{}{}{} \"{}{}{}\" {}{}{} {}({}{}{}){}'.format(green, authors, grey, bcyan, title, grey, yellow, journal, end, grey, end, year, grey, end)
def bib_desc(bib_data):
article = bib_data.entries[list(bib_data.entries.keys())[0]]
s = '\n'.join('author: {}'.format(person_repr(p)) for p in article.persons['author'])
s += '\n'
s += '\n'.join('{}: {}'.format(k, v) for k, v in article.fields.items())
return s
# commands
def init_cmd():
"""Create a .papers directory"""
global papersdir
# create dir
papersdir = os.getcwd() + '/.papers'
if not os.path.exists(papersdir):
print '{}initializing papers in {}{}{}'.format(grey, cyan, papersdir, end)
os.makedirs(papersdir)
13 years ago
os.makedirs(papersdir+os.sep+'bibdata')
os.makedirs(papersdir+os.sep+'meta')
papers = ConfigParser.ConfigParser()
papers.add_section('header')
papers.set('header', 'count', 0)
papers.add_section('papers')
write_papers(papers)
else:
print '{}error{} : papers already present in {}{}{}'.format(red, grey, cyan, papersdir, end)
13 years ago
exit(-1)
def install_cmd():
"""Install command on the system"""
print '{}file to install : {}{}{}'.format(grey, cyan, __file__, end)
default = '/usr/local/bin'
print "{}folder to install the papers command [{}{:s}{}] : {}".format(grey, cyan, default, grey, end),
sys.stdout.flush()
path = raw_input()
if path == '':
path = default
if not os.path.exists(path):
print "{}error{}: {}{:s}{} does not exist - installation aborted".format(red, end, cyan, path, end)
else:
if os.path.exists(path+'/papers'):
if os.path.samefile(path+'/papers', __file__):
return
shutil.copy(__file__, path)
def websearch_cmd(search_string):
url = 'https://scholar.google.fr/scholar?hl=fr&q={}&lr='.format(urllib.quote_plus(search_string))
webbrowser.open(url)
13 years ago
def add_cmd(pdffilepath, bibtex = None):
"""
:param pdffilepath path (no url yet) to a pdf or ps file
:param bibtex bibtex file (in .bib, .bibml or .yaml format.
"""
fullpdfpath = os.path.abspath(pdffilepath)
fullbibpath = os.path.abspath(bibtex)
check_file(fullpdfpath)
check_file(fullbibpath)
filename, ext = os.path.splitext(os.path.split(fullpdfpath)[1])
if ext != '.pdf' and ext != '.ps':
print '{}warning{}: extention {}{}{} not recognized{}'.format(yellow, grey, cyan, ext, grey, end)
meta = ConfigParser.ConfigParser()
meta.add_section('metadata')
13 years ago
meta.set('metadata', 'filename', filename)
meta.set('metadata', 'extension', ext)
meta.set('metadata', 'path', os.path.normpath(fullpdfpath))
13 years ago
meta.add_section('notes')
if bibtex is not None:
bib_data = load_externalbibfile(fullbibpath)
print '{}bibliographic data present in {}{}{}'.format(grey, cyan, bibtex, end)
print bib_desc(bib_data)
13 years ago
write_bibfile(bib_data, filename)
papers = read_papers()
count = papers.get('header', 'count')
papers.set('header', 'count', int(count) + 1)
papers.set('papers', 'p' + count, filename)
write_papers(papers)
13 years ago
write_meta(meta, filename)
13 years ago
def list_cmd():
papers = read_papers()
13 years ago
articles = []
for p in papers.options('papers'):
filename = papers.get('papers', p)
number = p[1:]
bibdata = load_bibfile(filename + '.bibyaml')
bibdesc = bib_oneliner(bibdata)
articles.append('{:3d} {}'.format(int(number), bibdesc))
13 years ago
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=True) as tmpf:
tmpf.write('\n'.join(articles))
tmpf.flush()
call(['less', '-XRF', tmpf.name])
13 years ago
# argument parsing (old school)
cmds = {'init': init_cmd,
'install': install_cmd,
'websearch': websearch_cmd,
13 years ago
'add': add_cmd,
13 years ago
'list': list_cmd,
}
error_msg = "{}banana {}banana {}banana{}".format(purple, yellow, cyan, end)
if len(sys.argv) == 1:
print error_msg
else:
cmd = sys.argv[1]
if cmd in cmds and cmd not in ['init', 'install', 'websearch']:
find_papersdir()
13 years ago
args = sys.argv[2:]
cmds[cmd](*args)
# try:
# args = sys.argv[2:]
# cmds[cmd](*args)
# except KeyError, TypeError:
# print error_msg
#