Merge branch 'feat-classes' into develop

main
Olivier Mangin 12 years ago
commit 7d5f7e54c3

@ -1,7 +1,7 @@
[header]
title = citekey support
id = 956ed1a521100b3b0bb0638f61b3b5a03204ffa6
status = open
status = closed
type = feature
author = Fabien Benureau
mail = fabien.benureau+git@gmail.com
@ -9,6 +9,7 @@ date = 2012-10-05 at 15:00 UCT
[eventlog]
opened[0] = opened the 2012-10-05 at 15:00 UCT by Fabien Benureau
closed[1] = closed the 2012-10-11 at 17:57(UCT) by Fabien Benureau
[discussion]
desc = # enter your description here

@ -0,0 +1,16 @@
[header]
title = remove configparser for internal mapping
id = ac8c05c020d251c6fa9ac5fc239038837b636b3b
status = closed
type = bug
author = Fabien Benureau
mail = fabien.benureau+git@gmail.com
date = 2012-10-11 at 07:25 UCT
[eventlog]
opened[0] = opened the 2012-10-11 at 07:25 UCT by Fabien Benureau
closed[1] = closed the 2012-10-11 at 17:57(UCT) by Fabien Benureau
[discussion]
desc = # enter your description here

@ -7,6 +7,7 @@ except ImportError:
from .. import color
from .. import files
from .. import pretty
from .. import repo
def parser(subparsers, config):
@ -20,41 +21,5 @@ def command(config, pdffile, bibfile):
:param pdffilepath path (no url yet) to a pdf or ps file
:param bibtex bibtex file (in .bib, .bibml or .yaml format.
"""
papersdir = files.find_papersdir()
fullpdfpath = os.path.abspath(pdffile)
fullbibpath = os.path.abspath(bibfile)
files.check_file(fullpdfpath)
files.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(
color.yellow, color.grey, color.cyan, ext, color.grey, color.end))
meta = configparser.ConfigParser()
meta.add_section('metadata')
meta.set('metadata', 'filename', filename)
meta.set('metadata', 'extension', ext)
meta.set('metadata', 'path', os.path.normpath(fullpdfpath))
meta.add_section('notes')
if bibfile is not None:
bib_data = files.load_externalbibfile(fullbibpath)
print('{}bibliographic data present in {}{}{}'.format(
color.grey, color.cyan, bibfile, color.end))
print(pretty.bib_desc(bib_data))
files.write_bibdata(bib_data, filename)
papers = files.load_papers()
count = papers.get('header', 'count')
papers.set('header', 'count', int(count) + 1)
citekey = pretty.create_citekey(bib_data)
papers.set('papers', citekey, filename)
papers.set('citekeys', 'ck' + count, citekey)
files.write_papers(papers)
files.write_meta(meta, filename)
rp = repo.Repository()
rp.add_paper(pdffile, bibfile)

@ -26,12 +26,11 @@ def command(config):
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')
papers.add_section('citekeys')
files.write_papers(papers)
papers = {}
papers['count'] = 0
papers['citekeys'] = {}
papers['numbers'] = {}
files.save_papers(papers)
else:
print('{}error {} : papers already present in {}{}{}'.format(

@ -1,25 +1,22 @@
from .. import files
from .. import pretty
from .. import color
import subprocess
import tempfile
from .. import pretty
from .. import color
from .. import repo
def parser(subparsers, config):
parser = subparsers.add_parser('list', help="list all papers")
return parser
def command(config):
papers = files.load_papers()
rp = repo.Repository()
articles = []
for p in papers.options('citekeys'):
number = p[2:]
citekey = papers.get('citekeys', p)
filename = papers.get('papers', citekey)
bibdata = files.load_bibdata(filename + '.bibyaml')
bibdesc = pretty.bib_oneliner(bibdata)
articles.append('{:3d} {}{}{}{} {}'.format(int(number), color.purple, citekey, color.end, (8-len(citekey))*' ', bibdesc))
for n in sorted(rp.numbers.keys()):
paper = rp.paper_from_number(n, fatal = True)
bibdesc = pretty.bib_oneliner(paper.bib_data)
articles.append('{:3d} {}{}{}{} {}'.format(int(paper.number), color.purple, paper.citekey, color.end, (8-len(paper.citekey))*' ', bibdesc))
with tempfile.NamedTemporaryFile(suffix=".tmp", delete=True) as tmpf:
tmpf.write('\n'.join(articles))

@ -1,30 +1,26 @@
try:
import ConfigParser as configparser
except ImportError:
import configparser
import subprocess
from .. import files
from .. import color
from .. import repo
from ..paper import NoDocumentFile
def parser(subparsers, config):
parser = subparsers.add_parser('open', help="open the paper in a pdf viewer")
parser.add_argument("citekey", help="the paper associated citekey")
parser = subparsers.add_parser('open', help='{}open the paper in a pdf viewer{}'.format(color.normal, color.end))
parser.add_argument('citekey', help='{}the paper associated citekey{}'.format(color.normal, color.end))
return parser
def command(config, citekey):
papers = files.load_papers()
rp = repo.Repository()
paper = rp.paper_from_any(citekey, fatal = True)
try:
filename = papers.get('papers', str(citekey))
except configparser.NoOptionError:
try:
ck = papers.get('citekeys', 'ck'+str(citekey))
filename = papers.get('papers', str(ck))
except configparser.NoOptionError:
print('{}error{}: paper with citekey or number {}{}{} not found{}'.format(
color.red, color.grey, color.cyan, citekey, color.grey, color.end))
exit(-1)
meta_data = files.load_meta(filename)
filepath = meta_data.get('metadata', 'path')
p = subprocess.Popen(['open', filepath])
print('{}{}{} opened.{}'.format(color.cyan, filepath, color.grey, color.end))
if paper.check_file():
filepath = paper.get_file_path()
p = subprocess.Popen(['open', filepath])
print('{}{}{} opened.{}'.format(
color.filepath, filepath, color.normal, color.end))
except NoDocumentFile:
print('{}error{}: No document associated to this entry {}{}{}'.format(
color.error, color.normal, color.citekey, citekey, color.end))
exit(-1)

@ -8,6 +8,8 @@ try:
except ImportError:
import configparser
import yaml
import color
try:
@ -49,6 +51,13 @@ def find_papersdir():
return _papersdir
def name_from_path(fullpdfpath, verbose = False):
name, ext = os.path.splitext(os.path.split(fullpdfpath)[1])
if verbose:
if ext != '.pdf' and ext != '.ps':
print('{}warning{}: extension {}{}{} not recognized{}'.format(
color.yellow, color.grey, color.cyan, ext, color.grey, color.end))
return name, ext
def check_file(filepath):
if not os.path.exists(filepath):
@ -59,29 +68,46 @@ def check_file(filepath):
print '{}error{}: {}{}{} is not a file{}'.format(
color.red, color.grey, color.cyan, filepath, color.grey, color.end)
exit(-1)
# yaml I/O
def write_configfile(config, filepath):
def write_yamlfile(filepath, datamap):
try:
with open(filepath, 'w') as f:
config.write(f)
yaml.dump(datamap, f)
except IOError as e:
print '{}error{} : impossible to write on file {}{:s}{}'.format(
print '{}error{} : impossible to read file {}{:s}{}'.format(
color.red, color.grey, color.cyan, filepath, color.end)
print 'Verify permissions'
exit(-1)
def read_configfile(filepath):
def read_yamlfile(filepath):
check_file(filepath)
try:
with open(filepath, 'r') as f:
config = configparser.ConfigParser()
config.readfp(f)
return config
return yaml.load(f)
except IOError as e:
print '{}error{} : impossible to read file {}{:s}{}'.format(
color.red, color.grey, color.cyan, filepath, color.end)
print 'Verify permissions'
color.red, color.grey, color.cyan, paperdir, color.end)
exit(-1)
def save_papers(datamap):
paperyaml = find_papersdir() + os.sep + 'papers.yaml'
write_yamlfile(paperyaml, datamap)
def load_papers():
paperyaml = find_papersdir() + os.sep + 'papers.yaml'
return read_yamlfile(paperyaml)
def save_meta(meta_data, filename):
filepath = find_papersdir() + os.sep + 'meta' + os.sep + filename + '.meta'
write_yamlfile(filepath, meta_data)
def load_meta(filename):
filepath = find_papersdir() + os.sep + 'meta' + os.sep + filename + '.meta'
return read_yamlfile(filepath)
# specific to bibliography data
def load_externalbibfile(fullbibpath):
check_file(fullbibpath)
@ -102,31 +128,17 @@ def load_externalbibfile(fullbibpath):
return bib_data
def write_papers(config):
write_configfile(config, find_papersdir() + os.sep + 'papers')
def load_papers():
return read_configfile(find_papersdir() + os.sep + 'papers')
def load_bibdata(filename):
fullbibpath = find_papersdir() + os.sep + 'bibdata' + os.sep + filename
fullbibpath = find_papersdir() + os.sep + 'bibdata' + os.sep + filename + '.bibyaml'
return load_externalbibfile(fullbibpath)
def write_bibdata(bib_data, filename):
def save_bibdata(bib_data, filename):
filepath = find_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 = find_papersdir() + os.sep + 'meta' + os.sep + filename + '.meta'
write_configfile(meta_data, filepath)
def load_meta(filename):
filepath = find_papersdir() + os.sep + 'meta' + os.sep + filename + '.meta'
return read_configfile(filepath)
# vim input
try:
EDITOR = os.environ['EDITOR']

@ -0,0 +1,68 @@
import os
import files
import color
import pretty
class Paper(object):
"""Paper class. The object is responsible for the integrity of its own data,
and for loading and writing it to disc.
"""
@classmethod
def from_disc(cls, name, citekey = None, number = None):
bib_data = files.load_bibdata(name)
metadata = files.load_meta(name)
p = Paper(name, bib_data = bib_data, metadata = metadata,
citekey = citekey, number = number)
return p
@classmethod
def from_bibpdffiles(cls, pdfpath, bibpath):
bib_data = cls.import_bibdata(bibpath)
name, meta = cls.create_meta(pdfpath, bib_data)
p = Paper(name, bib_data = bib_data, metadata = meta)
return p
def __init__(self, name, bib_data = None, metadata = None,
citekey = None, number = None):
self.name = name
self.bib_data = bib_data
self.metadata = metadata
self.citekey = citekey
self.number = number
def save_to_disc(self):
files.save_bibdata(self.bib_data, self.name)
files.save_meta(self.metadata, self.name)
@classmethod
def import_bibdata(cls, bibfile):
"""Import bibligraphic data from a .bibyaml, .bib or .bibtex file"""
fullbibpath = os.path.abspath(bibfile)
bib_data = files.load_externalbibfile(fullbibpath)
print('{}bibliographic data present in {}{}{}'.format(
color.grey, color.cyan, bibfile, color.end))
print(pretty.bib_desc(bib_data))
return bib_data
@classmethod
def create_meta(cls, pdfpath, bib_data):
fullpdfpath = os.path.abspath(pdfpath)
files.check_file(fullpdfpath)
name, ext = files.name_from_path(pdfpath)
meta = {}
meta['name'] = name
meta['extension'] = ext
meta['path'] = fullpdfpath
meta['notes'] = []
return name, meta

@ -26,33 +26,3 @@ def bib_desc(bib_data):
s += '\n'
s += '\n'.join('{}: {}'.format(k, v) for k, v in article.fields.items())
return s
alphabet = 'abcdefghijklmopqrstuvwxyz'
try:
import ConfigParser as configparser
except ImportError:
import configparser
import files
def create_citekey(bib_data):
"""Create a cite key unique to the paper"""
article = bib_data.entries[list(bib_data.entries.keys())[0]]
first_author = article.persons['author'][0]
year = article.fields['year']
prefix = '{}{}'.format(first_author.last()[0][:6], year[2:])
papers = files.load_papers()
letter = 0, False
citekey = None
citekey = prefix
while not letter[1]:
try:
papers.get('papers', citekey)
citekey = prefix + alphabet[letter[0]]
letter = letter[0]+1, False
except configparser.NoOptionError:
letter = letter[0], True
return citekey

@ -0,0 +1,100 @@
import files
import color
from paper import Paper
alphabet = 'abcdefghijklmopqrstuvwxyz'
class Repository(object):
def __init__(self):
self.paperdir = files.find_papersdir()
self.papers_config = files.load_papers()
self.citekeys = self.papers_config['citekeys']
self.numbers = self.papers_config['numbers']
# loading existing papers
def paper_from_number(self, number, fatal = True):
try:
citekey = self.numbers[int(number)]
paper = self.paper_from_citekey(citekey)
paper.number = int(number)
return paper
except KeyError:
if fatal:
print('{}error{}: no paper with number {}{}{}'.format(
color.error, color.normal, color.citekey, citekey, color.end))
exit(-1)
raise IOError, 'file not found'
def paper_from_citekey(self, citekey, fatal = True):
"""Load a paper by its citekey from disk, if necessary."""
try:
name = self.citekeys[citekey]
paper = Paper.from_disc(name, citekey = citekey)
paper.citekey = citekey
return paper
except KeyError:
if fatal:
print('{}error{}: no paper with citekey {}{}{}'.format(
color.error, color.normal, color.citekey, citekey, color.end))
exit(-1)
raise IOError, 'file not found'
def paper_from_any(self, key, fatal = True):
try:
return self.paper_from_citekey(key, fatal = False)
except IOError:
try:
return self.paper_from_number(key, fatal = False)
except IOError:
if fatal:
print('{}error{}: paper with citekey or number {}{}{} not found{}'.format(
color.error, color.normal, color.citekey, key, color.normal, color.end))
exit(-1)
raise IOError, 'file not found'
# creating new papers
def add_paper(self, pdfpath, bibpath):
p = Paper.from_bibpdffiles(pdfpath, bibpath)
# updating papersconfig
p.citekey = self.create_citekey(p.bib_data)
p.number = self.create_number()
self.papers_config['citekeys'][p.citekey] = p.name
self.papers_config['numbers'][p.number] = p.citekey
self.citekeys[p.citekey] = p.name
self.numbers[p.number] = p.citekey
# writing all to disk
files.save_papers(self.papers_config)
p.save_to_disc()
return p
def create_citekey(self, bib_data, allowed = tuple()):
"""Create a cite key unique to a given bib_data"""
article = bib_data.entries[list(bib_data.entries.keys())[0]]
first_author = article.persons['author'][0]
year = article.fields['year']
prefix = '{}{}'.format(first_author.last()[0][:6], year[2:])
letter = 0
citekey = None
citekey = prefix
while citekey in self.citekeys and citekey not in allowed:
citekey = prefix + alphabet[letter]
letter += 1
return citekey
def create_number(self):
count = int(self.papers_config['count'])
self.papers_config['count'] = count + 1
return count
Loading…
Cancel
Save