Adds back edit command.
The Repository rename_paper method has been updated. The citekey update and syncronization with citekey in the bibdata should be handled in a sane manner inside the Paper class.
This commit is contained in:
parent
c9e4f9788c
commit
07cb6f696c
@ -15,5 +15,5 @@ import import_cmd
|
|||||||
# bonus
|
# bonus
|
||||||
import websearch_cmd
|
import websearch_cmd
|
||||||
|
|
||||||
# import edit_cmd
|
import edit_cmd
|
||||||
# import update_cmd
|
# import update_cmd
|
||||||
|
@ -72,7 +72,7 @@ def command(args):
|
|||||||
if bibfile is None:
|
if bibfile is None:
|
||||||
bibdata = bibdata_from_editor(ui, rp)
|
bibdata = bibdata_from_editor(ui, rp)
|
||||||
else:
|
else:
|
||||||
bibdata_raw = content.get_content(bibfile)
|
bibdata_raw = content.get_content(bibfile, ui=ui)
|
||||||
bibdata = rp.databroker.verify(bibdata_raw)
|
bibdata = rp.databroker.verify(bibdata_raw)
|
||||||
if bibdata is None:
|
if bibdata is None:
|
||||||
ui.error('invalid bibfile {}.'.format(bibfile))
|
ui.error('invalid bibfile {}.'.format(bibfile))
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
from ..content import editor_input
|
from ..paper import Paper
|
||||||
from .. import repo
|
from .. import repo
|
||||||
from ..paper import get_bibentry_from_string, get_safe_metadata_from_content
|
|
||||||
from ..configs import config
|
from ..configs import config
|
||||||
from ..uis import get_ui
|
from ..uis import get_ui
|
||||||
|
from ..endecoder import EnDecoder
|
||||||
|
|
||||||
|
|
||||||
def parser(subparsers):
|
def parser(subparsers):
|
||||||
@ -15,24 +15,6 @@ def parser(subparsers):
|
|||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
|
||||||
def edit_meta(citekey):
|
|
||||||
rp = repo.Repository(config())
|
|
||||||
coder = endecoder.EnDecoder()
|
|
||||||
filepath = os.path.join(rp.databroker.databroker.filebroker.metadir(), citekey+'.yaml')
|
|
||||||
with open(filepath) as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def edit_bib(citekey):
|
|
||||||
rp = repo.Repository(config())
|
|
||||||
coder = endecoder.EnDecoder()
|
|
||||||
filepath = os.path.join(rp.databroker.databroker.filebroker.bibdir(), citekey+'.bib')
|
|
||||||
with open(filepath) as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def command(args):
|
def command(args):
|
||||||
|
|
||||||
ui = get_ui()
|
ui = get_ui()
|
||||||
@ -40,31 +22,35 @@ def command(args):
|
|||||||
citekey = args.citekey
|
citekey = args.citekey
|
||||||
|
|
||||||
rp = repo.Repository(config())
|
rp = repo.Repository(config())
|
||||||
coder = endecoder.EnDecoder()
|
paper = rp.pull_paper(citekey)
|
||||||
if meta:
|
|
||||||
filepath = os.path.join(rp.databroker.databroker.filebroker.metadir(), citekey+'.yaml')
|
|
||||||
else:
|
|
||||||
filepath = os.path.join(rp.databroker.databroker.filebroker.bibdir(), citekey+'.bib')
|
|
||||||
|
|
||||||
with open(filepath) as f:
|
coder = EnDecoder()
|
||||||
content = f.read()
|
if meta:
|
||||||
|
encode = coder.encode_metadata
|
||||||
|
decode = coder.decode_metadata
|
||||||
|
suffix = '.yaml'
|
||||||
|
raw_content = encode(paper.metadata)
|
||||||
|
else:
|
||||||
|
encode = coder.encode_bibdata
|
||||||
|
decode = coder.decode_bibdata
|
||||||
|
suffix = '.bib'
|
||||||
|
raw_content = encode(paper.bibdata)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# Get new content from user
|
# Get new content from user
|
||||||
content = editor_input(config().edit_cmd, content)
|
raw_content = ui.editor_input(initial=raw_content, suffix=suffix)
|
||||||
new_key = key
|
|
||||||
bib = None
|
|
||||||
metadata = None
|
|
||||||
# Parse new content
|
# Parse new content
|
||||||
if meta:
|
|
||||||
metadata = get_safe_metadata_from_content(content)
|
|
||||||
else:
|
|
||||||
new_key, bib = get_bibentry_from_string(content)
|
|
||||||
paper.update(key=new_key, bib=bib, meta=metadata)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
paper = rp.save_paper(paper, old_citekey=key)
|
content = decode(raw_content)
|
||||||
|
|
||||||
|
if meta:
|
||||||
|
new_paper = Paper(paper.bibdata, citekey=paper.citekey,
|
||||||
|
metadata=content)
|
||||||
|
else:
|
||||||
|
new_paper = Paper(content, metadata=paper.metadata)
|
||||||
|
rp.rename_paper(new_paper, old_citekey=paper.citekey)
|
||||||
break
|
break
|
||||||
|
|
||||||
except repo.CiteKeyCollision:
|
except repo.CiteKeyCollision:
|
||||||
options = ['overwrite', 'edit again', 'abort']
|
options = ['overwrite', 'edit again', 'abort']
|
||||||
choice = options[ui.input_choice(
|
choice = options[ui.input_choice(
|
||||||
@ -75,6 +61,7 @@ def command(args):
|
|||||||
if choice == 'abort':
|
if choice == 'abort':
|
||||||
break
|
break
|
||||||
elif choice == 'overwrite':
|
elif choice == 'overwrite':
|
||||||
paper = rp.save_paper(paper, old_citekey=key, overwrite=True)
|
paper = rp.push_paper(paper, overwrite=True)
|
||||||
break
|
break
|
||||||
# else edit again
|
# else edit again
|
||||||
|
# Also handle malformed bibtex and metadata
|
||||||
|
@ -7,10 +7,8 @@ import urlparse
|
|||||||
import httplib
|
import httplib
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
import uis
|
|
||||||
|
|
||||||
|
# files i/o
|
||||||
# files i/o
|
|
||||||
|
|
||||||
def check_file(path, fail=True):
|
def check_file(path, fail=True):
|
||||||
if fail:
|
if fail:
|
||||||
@ -44,7 +42,7 @@ def write_file(filepath, data):
|
|||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
|
|
||||||
# dealing with formatless content
|
# dealing with formatless content
|
||||||
|
|
||||||
def content_type(path):
|
def content_type(path):
|
||||||
parsed = urlparse.urlparse(path)
|
parsed = urlparse.urlparse(path)
|
||||||
@ -68,10 +66,11 @@ def check_content(path):
|
|||||||
else:
|
else:
|
||||||
return check_file(path)
|
return check_file(path)
|
||||||
|
|
||||||
def get_content(path):
|
def get_content(path, ui=None):
|
||||||
"""Will be useful when we need to get content from url"""
|
"""Will be useful when we need to get content from url"""
|
||||||
if content_type(path) == 'url':
|
if content_type(path) == 'url':
|
||||||
uis.get_ui().print_('dowloading {}'.format(path))
|
if ui is not None:
|
||||||
|
ui.print_('dowloading {}'.format(path))
|
||||||
response = urllib2.urlopen(path)
|
response = urllib2.urlopen(path)
|
||||||
return response.read()
|
return response.read()
|
||||||
else:
|
else:
|
||||||
@ -92,16 +91,11 @@ def copy_content(source, target, overwrite = False):
|
|||||||
shutil.copy(source, target)
|
shutil.copy(source, target)
|
||||||
|
|
||||||
|
|
||||||
# editor input
|
def editor_input(editor, initial="", suffix='.tmp'):
|
||||||
|
|
||||||
def editor_input(editor, initial="", suffix=None):
|
|
||||||
"""Use an editor to get input"""
|
"""Use an editor to get input"""
|
||||||
if suffix is None:
|
|
||||||
suffix = '.tmp'
|
|
||||||
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as temp_file:
|
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as temp_file:
|
||||||
tfile_name = temp_file.name
|
tfile_name = temp_file.name
|
||||||
temp_file.write(initial)
|
temp_file.write(initial)
|
||||||
temp_file.flush()
|
|
||||||
cmd = editor.split() # this enable editor command with option, e.g. gvim -f
|
cmd = editor.split() # this enable editor command with option, e.g. gvim -f
|
||||||
cmd.append(tfile_name)
|
cmd.append(tfile_name)
|
||||||
subprocess.call(cmd)
|
subprocess.call(cmd)
|
||||||
@ -110,6 +104,7 @@ def editor_input(editor, initial="", suffix=None):
|
|||||||
os.remove(tfile_name)
|
os.remove(tfile_name)
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def edit_file(editor, path_to_file, temporary=True):
|
def edit_file(editor, path_to_file, temporary=True):
|
||||||
if temporary:
|
if temporary:
|
||||||
check_file(path_to_file, fail=True)
|
check_file(path_to_file, fail=True)
|
||||||
|
@ -28,7 +28,7 @@ CORE_CMDS = collections.OrderedDict([
|
|||||||
('import', commands.import_cmd),
|
('import', commands.import_cmd),
|
||||||
|
|
||||||
('websearch', commands.websearch_cmd),
|
('websearch', commands.websearch_cmd),
|
||||||
# ('edit', commands.edit_cmd),
|
('edit', commands.edit_cmd),
|
||||||
# ('update', commands.update_cmd),
|
# ('update', commands.update_cmd),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
23
pubs/repo.py
23
pubs/repo.py
@ -2,7 +2,7 @@ import itertools
|
|||||||
|
|
||||||
from . import bibstruct
|
from . import bibstruct
|
||||||
from . import events
|
from . import events
|
||||||
from . import datacache
|
from datacache import DataCache
|
||||||
from .paper import Paper
|
from .paper import Paper
|
||||||
|
|
||||||
|
|
||||||
@ -23,8 +23,7 @@ class Repository(object):
|
|||||||
def __init__(self, config, create=False):
|
def __init__(self, config, create=False):
|
||||||
self.config = config
|
self.config = config
|
||||||
self._citekeys = None
|
self._citekeys = None
|
||||||
self.databroker = datacache.DataCache(self.config.pubsdir,
|
self.databroker = DataCache(self.config.pubsdir, create=create)
|
||||||
create=create)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def citekeys(self):
|
def citekeys(self):
|
||||||
@ -92,19 +91,19 @@ class Repository(object):
|
|||||||
self.citekeys.remove(citekey)
|
self.citekeys.remove(citekey)
|
||||||
self.databroker.remove(citekey)
|
self.databroker.remove(citekey)
|
||||||
|
|
||||||
def rename_paper(self, paper, new_citekey):
|
def rename_paper(self, paper, new_citekey=None, old_citekey=None):
|
||||||
|
if old_citekey is None:
|
||||||
old_citekey = paper.citekey
|
old_citekey = paper.citekey
|
||||||
|
if new_citekey is None:
|
||||||
|
new_citekey = paper.citekey
|
||||||
|
paper.citekey = new_citekey
|
||||||
# check if new_citekey is not the same as paper.citekey
|
# check if new_citekey is not the same as paper.citekey
|
||||||
if old_citekey == new_citekey:
|
if old_citekey == new_citekey:
|
||||||
push_paper(paper, overwrite=True, event=False)
|
self.push_paper(paper, overwrite=True, event=False)
|
||||||
else:
|
else:
|
||||||
# check if new_citekey does not exists
|
# check if new_citekey does not exists
|
||||||
if self.databroker.exists(new_citekey, both=False):
|
if new_citekey in self:
|
||||||
raise IOError("can't rename paper to {}, conflicting files exists".format(new_citekey))
|
raise CiteKeyCollision("can't rename paper to {}, conflicting files exists".format(new_citekey))
|
||||||
|
|
||||||
new_bibdata = {}
|
|
||||||
new_bibdata[new_citekey] = paper.bibdata[old_citekey]
|
|
||||||
paper.bibdata = new_bibdata
|
|
||||||
|
|
||||||
# move doc file if necessary
|
# move doc file if necessary
|
||||||
if self.databroker.in_docsdir(paper.docpath):
|
if self.databroker.in_docsdir(paper.docpath):
|
||||||
@ -116,8 +115,6 @@ class Repository(object):
|
|||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# push_paper to new_citekey
|
|
||||||
paper.citekey = new_citekey
|
|
||||||
self.push_paper(paper, event=False)
|
self.push_paper(paper, event=False)
|
||||||
# remove_paper of old_citekey
|
# remove_paper of old_citekey
|
||||||
self.remove_paper(old_citekey, event=False)
|
self.remove_paper(old_citekey, event=False)
|
||||||
|
@ -3,6 +3,7 @@ from __future__ import print_function
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .beets_ui import _encoding, input_
|
from .beets_ui import _encoding, input_
|
||||||
|
from .content import editor_input
|
||||||
from . import color
|
from . import color
|
||||||
|
|
||||||
# package-shared ui that can be accessed using :
|
# package-shared ui that can be accessed using :
|
||||||
@ -30,6 +31,7 @@ class UI:
|
|||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.encoding = _encoding(config)
|
self.encoding = _encoding(config)
|
||||||
color.setup(config.color)
|
color.setup(config.color)
|
||||||
|
self.editor = config.edit_cmd
|
||||||
|
|
||||||
def print_(self, *strings):
|
def print_(self, *strings):
|
||||||
"""Like print, but rather than raising an error when a character
|
"""Like print, but rather than raising an error when a character
|
||||||
@ -86,3 +88,6 @@ class UI:
|
|||||||
|
|
||||||
def warning(self, message):
|
def warning(self, message):
|
||||||
self.print_("%s: %s" % (color.dye('warning', color.yellow), message))
|
self.print_("%s: %s" % (color.dye('warning', color.yellow), message))
|
||||||
|
|
||||||
|
def editor_input(self, initial="", suffix='.tmp'):
|
||||||
|
return editor_input(self.editor, initial=initial, suffix=suffix)
|
||||||
|
@ -92,6 +92,7 @@ class CommandTestCase(unittest.TestCase):
|
|||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
fake_env.unset_fake_fs([content, filebroker])
|
fake_env.unset_fake_fs([content, filebroker])
|
||||||
|
|
||||||
|
|
||||||
class DataCommandTestCase(CommandTestCase):
|
class DataCommandTestCase(CommandTestCase):
|
||||||
"""Abstract TestCase intializing the fake filesystem and
|
"""Abstract TestCase intializing the fake filesystem and
|
||||||
copying fake data.
|
copying fake data.
|
||||||
@ -118,6 +119,7 @@ class TestInit(CommandTestCase):
|
|||||||
self.assertEqual(set(self.fs['os'].listdir(pubsdir)),
|
self.assertEqual(set(self.fs['os'].listdir(pubsdir)),
|
||||||
{'bib', 'doc', 'meta', 'notes'})
|
{'bib', 'doc', 'meta', 'notes'})
|
||||||
|
|
||||||
|
|
||||||
class TestAdd(DataCommandTestCase):
|
class TestAdd(DataCommandTestCase):
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self):
|
||||||
@ -246,7 +248,7 @@ class TestUsecase(DataCommandTestCase):
|
|||||||
|
|
||||||
line = '[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) \n'
|
line = '[Page99] Page, Lawrence et al. "The PageRank Citation Ranking: Bringing Order to the Web." (1999) \n'
|
||||||
line1 = re.sub('1999', '2007', line)
|
line1 = re.sub('1999', '2007', line)
|
||||||
line2 = re.sub('L. Page', 'L. Ridge', line1)
|
line2 = re.sub('Page,', 'Ridge,', line1)
|
||||||
line3 = re.sub('Page99', 'Ridge07', line2)
|
line3 = re.sub('Page99', 'Ridge07', line2)
|
||||||
|
|
||||||
cmds = ['pubs init',
|
cmds = ['pubs init',
|
||||||
@ -259,7 +261,6 @@ class TestUsecase(DataCommandTestCase):
|
|||||||
('pubs edit Page99', [bib3]),
|
('pubs edit Page99', [bib3]),
|
||||||
('pubs list', [], line3),
|
('pubs list', [], line3),
|
||||||
]
|
]
|
||||||
|
|
||||||
self.execute_cmds(cmds)
|
self.execute_cmds(cmds)
|
||||||
|
|
||||||
def test_export(self):
|
def test_export(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user