Change repo and removed the update function and the rename function. Now only the save_paper function must be used

main
jgrizou 12 years ago
parent 843d81a0e8
commit 7b555abf92

@ -5,9 +5,7 @@ import itertools
from . import files
from .paper import PaperInRepo, NoDocumentFile
from . import configs
from .events import RemoveEvent, RenameEvent
BASE_FILE = 'papers.yaml'
BIB_DIR = 'bibdata'
@ -25,7 +23,7 @@ class InvalidReference(Exception):
class Repository(object):
def __init__(self, config, load = True):
def __init__(self, config, load=True):
"""Initialize the repository.
:param load: if load is True, load the repository from disk,
@ -52,20 +50,18 @@ class Repository(object):
def __len__(self):
return len(self.citekeys)
# load, save repo
def _init_dirs(self, autodoc = True):
def _init_dirs(self, autodoc=True):
"""Create, if necessary, the repository directories.
Should only be called by load or save.
"""
self.bib_dir = files.clean_path(self.config.papers_dir, BIB_DIR)
self.bib_dir = files.clean_path(self.config.papers_dir, BIB_DIR)
self.meta_dir = files.clean_path(self.config.papers_dir, META_DIR)
if self.config.doc_dir == 'doc':
self.doc_dir = files.clean_path(self.config.papers_dir, DOC_DIR)
else:
self.doc_dir = files.clean_path(self.config.doc_dir)
self.doc_dir = files.clean_path(self.config.doc_dir)
self.cfg_path = files.clean_path(self.config.papers_dir, 'papers.yaml')
for d in [self.bib_dir, self.meta_dir, self.doc_dir]:
@ -84,9 +80,7 @@ class Repository(object):
repo_cfg = {'citekeys': self.citekeys}
files.write_yamlfile(self.cfg_path, repo_cfg)
# reference
def ref2citekey(self, ref):
"""Tries to get citekey from given reference.
Ref can be a citekey or a number.
@ -99,9 +93,7 @@ class Repository(object):
except (IndexError, ValueError):
raise InvalidReference
# papers
def all_papers(self):
for key in self.citekeys:
yield self.get_paper(key)
@ -109,12 +101,10 @@ class Repository(object):
def get_paper(self, citekey):
"""Load a paper by its citekey from disk, if necessary."""
return PaperInRepo.load(self, self._bibfile(citekey),
self._metafile(citekey))
self._metafile(citekey))
# add, remove papers
def add_paper(self, p, overwrite = False):
def add_paper(self, p, overwrite=False):
if p.citekey is None: # TODO also test if citekey is valid
raise ValueError("Invalid citekey: {}.".format(p.citekey))
if not overwrite and p.citekey in self.citekeys:
@ -128,53 +118,22 @@ class Repository(object):
print('Added: {}'.format(p.citekey))
return p
def rename_paper(self, paper, new_citekey, overwrite=False):
"""Modify the citekey of a paper, and propagate changes to disk"""
if paper.citekey not in self:
raise ValueError(
'paper {} not in repository'.format(paper.citekey))
if (not overwrite and paper.citekey != new_citekey
and new_citekey in self):
raise CiteKeyCollision('citekey {} already in use'.format(
new_citekey))
self.remove_paper(paper.citekey, remove_doc = False)
old_citekey = paper.citekey
paper.citekey = new_citekey
self.add_paper(paper, overwrite = overwrite)
self._move_doc(old_citekey, paper)
def update_paper(self, paper, old_citekey=None, overwrite=False):
"""Updates a paper, eventually changing its citekey.
The paper should be in repository. If the citekey changes,
the new citekey should be free except if the overwrite argument
is set to True.
"""
if old_citekey is None:
old_citekey = paper.citekey
if old_citekey not in self.citekeys:
raise(ValueError, 'Paper not in repository. Add first')
else:
if paper.citekey == old_citekey:
self.save_paper(paper)
else:
if paper.citekey in self.citekeys:
if not overwrite:
raise(CiteKeyCollision,
"There is already a paper with citekey: %s."
% paper.citekey)
else:
self.save_paper(paper)
else:
self.add_paper(paper)
# Eventually move document file
paper = PaperInRepo.from_paper(paper, self)
try:
path = self.find_document(old_citekey)
self.import_document(paper.citekey, path)
except NoDocumentFile:
pass
self.remove_paper(old_citekey, remove_doc=True)
def save_paper(self, paper, old_citekey=None, overwrite=False):
if (not paper.citekey in self.citekeys and
not old_citekey in self.citekeys):
raise ValueError('Paper not in repository, first add it.')
if old_citekey is None or old_citekey == paper.citekey:
paper.save(self._bibfile(paper.citekey),
self._metafile(paper.citekey))
else: # paper has changed citekey, raise RenameEvent
if (not overwrite and paper.citekey in self.citekeys):
raise CiteKeyCollision('citekey {} already in use'.format(
paper.citekey))
RenameEvent(old_citekey, paper.citekey)
self._remove_paper(old_citekey, remove_doc=False)
self.add_paper(paper, overwrite=overwrite)
self._move_doc(old_citekey, paper)
def _move_doc(self, old_citekey, paper):
"""Fragile. Make more robust"""
@ -194,6 +153,12 @@ class Repository(object):
return os.path.join(self.meta_dir, citekey + '.meta')
def remove_paper(self, citekey, remove_doc=True):
RemoveEvent(citekey).send()
self._remove_paper(citekey, remove_doc)
def _remove_paper(self, citekey, remove_doc=True):
""" This version of remove is not meant to be accessed from outside.
It removes paper without raising the Remove Event"""
paper = self.get_paper(citekey)
self.citekeys.remove(citekey)
os.remove(self._metafile(citekey))
@ -209,12 +174,6 @@ class Repository(object):
self.save()
def save_paper(self, paper):
if not paper.citekey in self:
raise ValueError('Paper not in repository, first add it.')
paper.save(self._bibfile(paper.citekey),
self._metafile(paper.citekey))
def generate_citekey(self, paper, citekey=None):
"""Create a unique citekey for the given paper."""
if citekey is None:
@ -247,10 +206,9 @@ class Repository(object):
return tags
def _base27(n):
return _base27((n-1) // 26) + chr(97+((n-1)% 26)) if n else ''
return _base27((n - 1) // 26) + chr(ord('a') + ((n - 1) % 26)) if n else ''
def _base(num, b):
q, r = divmod(num - 1, len(b))

@ -3,23 +3,22 @@ import tempfile
import shutil
import os
import testenv
import fixtures
from papers.repo import (Repository, _base27, BIB_DIR, META_DIR,
CiteKeyCollision)
from papers.paper import PaperInRepo
from papers import configs, files
class TestCitekeyGeneration(unittest.TestCase):
class TestCitekeyGeneration(unittest.TestCase):
def test_string_increment(self):
self.assertEqual(_base27(0), '')
for i in range(26):
self.assertEqual(_base27(i+1), chr(97+i))
self.assertEqual(_base27(26+i+1), 'a' + chr(97+i))
self.assertEqual(_base27(i + 1), chr(97 + i))
self.assertEqual(_base27(26 + i + 1), 'a' + chr(97 + i))
def test_generated_key_is_unique(self):
repo = Repository(configs.Config(), load = False)
repo = Repository(configs.Config(), load=False)
repo.citekeys = ['Turing1950', 'Doe2003']
c = repo.generate_citekey(fixtures.turing1950)
repo.citekeys.append('Turing1950a')
@ -31,7 +30,7 @@ class TestRepo(unittest.TestCase):
def setUp(self):
self.tmpdir = tempfile.mkdtemp()
self.repo = Repository(configs.Config(papers_dir = self.tmpdir), load = False)
self.repo = Repository(configs.Config(papers_dir=self.tmpdir), load=False)
self.repo.save()
self.repo.add_paper(fixtures.turing1950)
@ -64,12 +63,12 @@ class TestUpdatePaper(TestRepo):
with self.assertRaises(ValueError):
self.repo.save_paper(fixtures.doe2013)
with self.assertRaises(ValueError):
self.repo.rename_paper(fixtures.doe2013, 'zou')
self.repo.save_paper(fixtures.doe2013, 'zou')
def test_error_on_existing_destination(self):
self.repo.add_paper(fixtures.doe2013)
with self.assertRaises(CiteKeyCollision):
self.repo.rename_paper(fixtures.turing1950, 'Doe2013')
self.repo.save_paper(fixtures.turing1950, old_citekey='Doe2013')
def test_updates_same_key(self):
new = self.repo.get_paper('Turing1950')
@ -80,13 +79,14 @@ class TestUpdatePaper(TestRepo):
def test_updates_same_key_with_old_arg(self):
new = self.repo.get_paper('Turing1950')
new.bibentry.fields['journal'] = u'Mind'
self.repo.rename_paper(new, 'Turing1950')
self.repo.save_paper(new, old_citekey='Turing1950')
self.assertEqual(new, self.repo.get_paper('Turing1950'))
def test_update_new_key_removes_old(self):
self.repo.add_paper(fixtures.doe2013)
self.repo.rename_paper(fixtures.doe2013, 'JohnDoe2003')
self.assertFalse('Doe2003' in self.repo)
fixtures.doe2013.update(key='JohnDoe2003')
self.repo.save_paper(fixtures.doe2013, old_citekey='Doe2013')
self.assertFalse('Doe2013' in self.repo)
def test_update_new_key_updates(self):
# self.repo.rename(fixtures.doe2013, old_citekey='Turing1950')
@ -100,7 +100,9 @@ class TestUpdatePaper(TestRepo):
self.repo.import_document('Turing1950',
os.path.join(os.path.dirname(__file__),
'data/pagerank.pdf'))
self.repo.rename_paper(self.repo.get_paper('Turing1950'), 'Doe2003')
paper = self.repo.get_paper('Turing1950')
paper.update('Doe2003')
self.repo.save_paper(paper, old_citekey='Turing1950')
self.assertFalse(os.path.exists(os.path.join(
self.repo.doc_dir, 'Turing1950.pdf')))
self.assertTrue(os.path.exists(os.path.join(

Loading…
Cancel
Save