pubs/pubs/paper.py
Olivier Mangin de2a50eeb2 Fix tests and terminology.
First this brings a change to the paper API: the terminology of bibdata
and bibentry is clarified: now bibentry is a dictionary of the form
{citekey: bibdata} where bibdata corresponds to the actual dictionary of
bibliographic fields and values {author: ..., year: ...}.
Now bibentry is an attribute of the paper object that is generated from
citekey and bibdata.

This commit fixes all tests in particular an issue with citekey in
bibentry not updated.

Also removes prints in tests and deprecated assertEquals.

Usecase tests now fail if the command ask for unexpected inputs.

Removes queries for user input in attach and add commands (for deletion
of a copied document file). The input was not coherent with tests and is
annoying.
2015-05-07 13:17:44 +02:00

111 lines
3.0 KiB
Python

import copy
from dateutil.parser import parse as datetime_parse
from . import bibstruct
from .p3 import ustr
DEFAULT_META = {'docfile': None, 'tags': set()}
def _clean_metadata(metadata):
meta = copy.deepcopy(DEFAULT_META)
meta.update(metadata or {}) # handles None metadata
meta['tags'] = set(meta.get('tags', [])) # tags should be a set
if 'added' in meta and isinstance(meta['added'], ustr):
meta['added'] = datetime_parse(meta['added'])
return meta
class Paper(object):
""" Paper class.
The object is not responsible of any disk I/O.
self.bibdata is a dictionary of bibligraphic fields
self.metadata is a dictionary
The paper class provides methods to access the fields for its metadata
in a pythonic manner.
"""
def __init__(self, citekey, bibdata, metadata=None):
self.citekey = citekey
self.metadata = _clean_metadata(metadata)
self.bibdata = bibdata
bibstruct.check_citekey(self.citekey)
def __eq__(self, other):
return (isinstance(self, Paper) and type(other) is type(self)
and self.bibdata == other.bibdata
and self.metadata == other.metadata
and self.citekey == other.citekey)
def __repr__(self):
return 'Paper(%s, %s, %s)' % (
self.citekey, self.bibdata, self.metadata)
def __deepcopy__(self, memo):
return Paper(citekey=self.citekey,
metadata=copy.deepcopy(self.metadata, memo),
bibdata=copy.deepcopy(self.bibdata, memo))
def __copy__(self):
return Paper(citekey=self.citekey,
metadata=self.metadata,
bibdata=self.bibdata)
def deepcopy(self):
return self.__deepcopy__({})
# docpath
@property
def bibentry(self):
return {self.citekey: self.bibdata}
@property
def docpath(self):
return self.metadata.get('docfile', '')
@docpath.setter
def docpath(self, path):
"""Does not verify if the path exists."""
self.metadata['docfile'] = path
# tags
@property
def tags(self):
return self.metadata['tags']
@tags.setter
def tags(self, value):
if not hasattr(value, '__iter__'):
raise ValueError('tags must be iterables')
self.metadata['tags'] = set(value)
def add_tag(self, tag):
self.tags.add(tag)
def remove_tag(self, tag):
"""Remove a tag from a paper if present."""
self.tags.discard(tag)
# added date
# Added time, supposed to be stored as datetime object
@property
def added(self):
return self.metadata.get('added', None)
@added.setter
def added(self, value):
self.metadata['added'] = value
@staticmethod
def from_bibentry(bibentry, citekey=None, metadata=None):
bibentry_key, bibdata = bibstruct.get_entry(bibentry)
if citekey is None:
citekey = bibentry_key
return Paper(citekey, bibdata, metadata=metadata)