Better handling of path (also fixes bugs).

Paths should be normalized through content.system_path before any actual
operation on files. This is in particular taken care of in content
functions check_file, check_dir, write_file, and read_file.
main
Olivier Mangin 11 years ago
parent f2de611106
commit d2ba13700f

@ -8,7 +8,7 @@ from .. import color
from ..paper import Paper
from ..configs import config
from ..uis import get_ui
from ..content import system_path, read_file
def parser(subparsers):
@ -37,7 +37,7 @@ def many_from_path(bibpath):
"""
coder = endecoder.EnDecoder()
bibpath = os.path.expanduser(bibpath)
bibpath = system_path(bibpath)
if os.path.isdir(bibpath):
print([os.path.splitext(f)[-1][1:] for f in os.listdir(bibpath)])
all_files = [os.path.join(bibpath, f) for f in os.listdir(bibpath)
@ -47,8 +47,7 @@ def many_from_path(bibpath):
biblist = []
for filepath in all_files:
with open(filepath, 'r') as f:
biblist.append(coder.decode_bibdata(f.read()))
biblist.append(coder.decode_bibdata(read_file(filepath)))
papers = {}
for b in biblist:
@ -59,7 +58,7 @@ def many_from_path(bibpath):
papers[k] = Paper(bibdata, citekey=k)
papers[k].added = datetime.datetime.now()
except ValueError, e:
except ValueError as e:
papers[k] = e
return papers
@ -100,5 +99,5 @@ def command(args):
ui.print_('{} imported'.format(color.dye(p.citekey, color.cyan)))
except KeyError:
ui.error('no entry found for citekey {}.'.format(k))
except IOError, e:
except IOError as e:
ui.error(e.message)

@ -2,6 +2,7 @@ import os
import collections
from .p3 import configparser
from .content import system_path
# constant stuff (DFT = DEFAULT)
@ -64,7 +65,7 @@ class Config(object):
return self
def save(self, path=DFT_CONFIG_PATH):
with open(path, 'w') as f:
with open(system_path(path), 'w') as f:
self._cfg.write(f)
def __setattr__(self, name, value):

@ -10,38 +10,55 @@ import urllib2
# files i/o
def check_file(path, fail=True):
if fail:
if not os.path.exists(path):
raise IOError("File does not exist: {}.".format(path))
if not os.path.isfile(path):
raise IOError("{} is not a file.".format(path))
return True
def _check_system_path_exists(path, fail=True):
answer = os.path.exists(path)
if not answer and fail:
raise IOError("File does not exist: {}.".format(path))
else:
return os.path.exists(path) and os.path.isfile(path)
return answer
def check_directory(path, fail=True):
if fail:
if not os.path.exists(path):
raise IOError("File does not exist: {}.".format(path))
if not os.path.isdir(path):
raise IOError("{} is not a directory.".format(path))
return True
def _check_system_path_is(nature, path, fail=True):
if nature == 'file':
check_fun = os.path.isfile
elif nature == 'dir':
check_fun = os.path.isdir
answer = check_fun(path)
if not answer and fail:
raise IOError("{} is not a {}.".format(path, nature))
else:
return os.path.exists(path) and os.path.isdir(path)
return answer
def check_file(path, fail=True):
syspath = system_path(path)
return (_check_system_path_exists(syspath, fail=fail)
and _check_system_path_is('file', syspath, fail=fail))
def check_directory(path, fail=True):
syspath = system_path(path)
return (_check_system_path_exists(syspath, fail=fail)
and _check_system_path_is('dir', syspath, fail=fail))
def read_file(filepath):
check_file(filepath)
with open(filepath, 'r') as f:
with open(system_path(filepath), 'r') as f:
s = f.read()
return s
def write_file(filepath, data):
check_directory(os.path.dirname(filepath))
with open(filepath, 'w') as f:
with open(system_path(filepath), 'w') as f:
f.write(data)
def system_path(path):
return os.path.abspath(os.path.expanduser(path))
# dealing with formatless content
def content_type(path):
@ -51,6 +68,7 @@ def content_type(path):
else:
return 'file'
def url_exists(url):
parsed = urlparse.urlparse(url)
conn = httplib.HTTPConnection(parsed.netloc)
@ -66,6 +84,7 @@ def check_content(path):
else:
return check_file(path)
def get_content(path, ui=None):
"""Will be useful when we need to get content from url"""
if content_type(path) == 'url':
@ -76,6 +95,7 @@ def get_content(path, ui=None):
else:
return read_file(path)
def move_content(source, target, overwrite = False):
if source == target:
return
@ -83,6 +103,7 @@ def move_content(source, target, overwrite = False):
raise IOError('target file exists')
shutil.move(source, target)
def copy_content(source, target, overwrite = False):
if source == target:
return

@ -1,10 +1,10 @@
import os
import shutil
import re
import urlparse
from .content import check_file, check_directory, read_file, write_file
from .content import check_content, content_type, get_content
from .content import (check_file, check_directory, read_file, write_file,
system_path, check_content, content_type, get_content)
def filter_filename(filename, ext):
""" Return the filename without the extension if the extension matches ext.
@ -14,6 +14,7 @@ def filter_filename(filename, ext):
if re.match(pattern, filename) is not None:
return filename[:-len(ext)]
class FileBroker(object):
""" Handles all access to meta and bib files of the repository.
@ -33,11 +34,11 @@ class FileBroker(object):
def _create(self):
if not check_directory(self.directory, fail = False):
os.mkdir(self.directory)
os.mkdir(system_path(self.directory))
if not check_directory(self.metadir, fail = False):
os.mkdir(self.metadir)
os.mkdir(system_path(self.metadir))
if not check_directory(self.bibdir, fail = False):
os.mkdir(self.bibdir)
os.mkdir(system_path(self.bibdir))
def pull_metafile(self, citekey):
filepath = os.path.join(self.metadir, citekey + '.yaml')
@ -78,24 +79,23 @@ class FileBroker(object):
else:
return meta_exists or bib_exists
def listing(self, filestats=True):
metafiles = []
for filename in os.listdir(self.metadir):
for filename in os.listdir(system_path(self.metadir)):
citekey = filter_filename(filename, '.yaml')
if citekey is not None:
if filestats:
stats = os.stat(os.path.join(path, filename))
stats = os.stat(system_path(os.path.join(self.metadir, filename)))
metafiles.append(citekey, stats)
else:
metafiles.append(citekey)
bibfiles = []
for filename in os.listdir(self.bibdir):
for filename in os.listdir(system_path(self.bibdir)):
citekey = filter_filename(filename, '.bib')
if citekey is not None:
if filestats:
stats = os.stat(os.path.join(path, filename))
stats = os.stat(system_path(os.path.join(self.bibdir, filename)))
bibfiles.append(citekey, stats)
else:
bibfiles.append(citekey)
@ -118,7 +118,7 @@ class DocBroker(object):
self.scheme = scheme
self.docdir = os.path.join(directory, subdir)
if not check_directory(self.docdir, fail = False):
os.mkdir(self.docdir)
os.mkdir(system_path(self.docdir))
def in_docsdir(self, docpath):
try:
@ -143,7 +143,7 @@ class DocBroker(object):
docpath = os.path.join(self.docdir, parsed.netloc, parsed.path[1:])
elif content_type(docpath) != 'file':
return docpath
return os.path.normpath(os.path.abspath(docpath))
return docpath
def add_doc(self, citekey, source_path, overwrite=False):
""" Add a document to the docsdir, and return its location.
@ -162,8 +162,7 @@ class DocBroker(object):
raise IOError('{} file exists.'.format(full_target_path))
doc_content = get_content(full_source_path)
with open(full_target_path, 'wb') as f:
f.write(doc_content)
write_file(full_target_path, doc_content)
return target_path

@ -88,7 +88,7 @@ def copy_dir(fs, real_dir, fake_dir = None):
if fake_dir is None:
fake_dir = real_dir
for filename in real_os.listdir(real_dir):
real_path = real_os.path.join(real_dir, filename)
real_path = os.path.abspath(real_os.path.join(real_dir, filename))
fake_path = fs['os'].path.join(fake_dir, filename)
if real_os.path.isfile(real_path):
with real_open(real_path, 'r') as f:
@ -98,7 +98,7 @@ def copy_dir(fs, real_dir, fake_dir = None):
copy_dir(fs, real_path, fake_path)
# redirecting output
# redirecting output
def redirect(f):
def newf(*args, **kwargs):

Loading…
Cancel
Save