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.
This commit is contained in:
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):
|
||||
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))
|
||||
if not os.path.isfile(path):
|
||||
raise IOError("{} is not a file.".format(path))
|
||||
return True
|
||||
else:
|
||||
return os.path.exists(path) and os.path.isfile(path)
|
||||
return answer
|
||||
|
||||
|
||||
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 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):
|
||||
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
|
||||
else:
|
||||
return os.path.exists(path) and os.path.isdir(path)
|
||||
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…
x
Reference in New Issue
Block a user