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 ..paper import Paper
|
||||||
from ..configs import config
|
from ..configs import config
|
||||||
from ..uis import get_ui
|
from ..uis import get_ui
|
||||||
|
from ..content import system_path, read_file
|
||||||
|
|
||||||
|
|
||||||
def parser(subparsers):
|
def parser(subparsers):
|
||||||
@ -37,7 +37,7 @@ def many_from_path(bibpath):
|
|||||||
"""
|
"""
|
||||||
coder = endecoder.EnDecoder()
|
coder = endecoder.EnDecoder()
|
||||||
|
|
||||||
bibpath = os.path.expanduser(bibpath)
|
bibpath = system_path(bibpath)
|
||||||
if os.path.isdir(bibpath):
|
if os.path.isdir(bibpath):
|
||||||
print([os.path.splitext(f)[-1][1:] for f in os.listdir(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)
|
all_files = [os.path.join(bibpath, f) for f in os.listdir(bibpath)
|
||||||
@ -47,8 +47,7 @@ def many_from_path(bibpath):
|
|||||||
|
|
||||||
biblist = []
|
biblist = []
|
||||||
for filepath in all_files:
|
for filepath in all_files:
|
||||||
with open(filepath, 'r') as f:
|
biblist.append(coder.decode_bibdata(read_file(filepath)))
|
||||||
biblist.append(coder.decode_bibdata(f.read()))
|
|
||||||
|
|
||||||
papers = {}
|
papers = {}
|
||||||
for b in biblist:
|
for b in biblist:
|
||||||
@ -59,7 +58,7 @@ def many_from_path(bibpath):
|
|||||||
|
|
||||||
papers[k] = Paper(bibdata, citekey=k)
|
papers[k] = Paper(bibdata, citekey=k)
|
||||||
papers[k].added = datetime.datetime.now()
|
papers[k].added = datetime.datetime.now()
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
papers[k] = e
|
papers[k] = e
|
||||||
return papers
|
return papers
|
||||||
|
|
||||||
@ -100,5 +99,5 @@ def command(args):
|
|||||||
ui.print_('{} imported'.format(color.dye(p.citekey, color.cyan)))
|
ui.print_('{} imported'.format(color.dye(p.citekey, color.cyan)))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
ui.error('no entry found for citekey {}.'.format(k))
|
ui.error('no entry found for citekey {}.'.format(k))
|
||||||
except IOError, e:
|
except IOError as e:
|
||||||
ui.error(e.message)
|
ui.error(e.message)
|
||||||
|
@ -2,6 +2,7 @@ import os
|
|||||||
import collections
|
import collections
|
||||||
|
|
||||||
from .p3 import configparser
|
from .p3 import configparser
|
||||||
|
from .content import system_path
|
||||||
|
|
||||||
# constant stuff (DFT = DEFAULT)
|
# constant stuff (DFT = DEFAULT)
|
||||||
|
|
||||||
@ -64,7 +65,7 @@ class Config(object):
|
|||||||
return self
|
return self
|
||||||
|
|
||||||
def save(self, path=DFT_CONFIG_PATH):
|
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)
|
self._cfg.write(f)
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
|
@ -10,38 +10,55 @@ import urllib2
|
|||||||
|
|
||||||
# files i/o
|
# files i/o
|
||||||
|
|
||||||
def check_file(path, fail=True):
|
def _check_system_path_exists(path, fail=True):
|
||||||
if fail:
|
answer = os.path.exists(path)
|
||||||
if not os.path.exists(path):
|
if not answer and fail:
|
||||||
raise IOError("File does not exist: {}.".format(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
|
|
||||||
else:
|
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):
|
def check_directory(path, fail=True):
|
||||||
if fail:
|
syspath = system_path(path)
|
||||||
if not os.path.exists(path):
|
return (_check_system_path_exists(syspath, fail=fail)
|
||||||
raise IOError("File does not exist: {}.".format(path))
|
and _check_system_path_is('dir', syspath, fail=fail))
|
||||||
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)
|
|
||||||
|
|
||||||
def read_file(filepath):
|
def read_file(filepath):
|
||||||
check_file(filepath)
|
check_file(filepath)
|
||||||
with open(filepath, 'r') as f:
|
with open(system_path(filepath), 'r') as f:
|
||||||
s = f.read()
|
s = f.read()
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def write_file(filepath, data):
|
def write_file(filepath, data):
|
||||||
check_directory(os.path.dirname(filepath))
|
check_directory(os.path.dirname(filepath))
|
||||||
with open(filepath, 'w') as f:
|
with open(system_path(filepath), 'w') as f:
|
||||||
f.write(data)
|
f.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
def system_path(path):
|
||||||
|
return os.path.abspath(os.path.expanduser(path))
|
||||||
|
|
||||||
|
|
||||||
# dealing with formatless content
|
# dealing with formatless content
|
||||||
|
|
||||||
def content_type(path):
|
def content_type(path):
|
||||||
@ -51,6 +68,7 @@ def content_type(path):
|
|||||||
else:
|
else:
|
||||||
return 'file'
|
return 'file'
|
||||||
|
|
||||||
|
|
||||||
def url_exists(url):
|
def url_exists(url):
|
||||||
parsed = urlparse.urlparse(url)
|
parsed = urlparse.urlparse(url)
|
||||||
conn = httplib.HTTPConnection(parsed.netloc)
|
conn = httplib.HTTPConnection(parsed.netloc)
|
||||||
@ -66,6 +84,7 @@ def check_content(path):
|
|||||||
else:
|
else:
|
||||||
return check_file(path)
|
return check_file(path)
|
||||||
|
|
||||||
|
|
||||||
def get_content(path, ui=None):
|
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':
|
||||||
@ -76,6 +95,7 @@ def get_content(path, ui=None):
|
|||||||
else:
|
else:
|
||||||
return read_file(path)
|
return read_file(path)
|
||||||
|
|
||||||
|
|
||||||
def move_content(source, target, overwrite = False):
|
def move_content(source, target, overwrite = False):
|
||||||
if source == target:
|
if source == target:
|
||||||
return
|
return
|
||||||
@ -83,6 +103,7 @@ def move_content(source, target, overwrite = False):
|
|||||||
raise IOError('target file exists')
|
raise IOError('target file exists')
|
||||||
shutil.move(source, target)
|
shutil.move(source, target)
|
||||||
|
|
||||||
|
|
||||||
def copy_content(source, target, overwrite = False):
|
def copy_content(source, target, overwrite = False):
|
||||||
if source == target:
|
if source == target:
|
||||||
return
|
return
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import re
|
import re
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
from .content import check_file, check_directory, read_file, write_file
|
from .content import (check_file, check_directory, read_file, write_file,
|
||||||
from .content import check_content, content_type, get_content
|
system_path, check_content, content_type, get_content)
|
||||||
|
|
||||||
|
|
||||||
def filter_filename(filename, ext):
|
def filter_filename(filename, ext):
|
||||||
""" Return the filename without the extension if the extension matches 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:
|
if re.match(pattern, filename) is not None:
|
||||||
return filename[:-len(ext)]
|
return filename[:-len(ext)]
|
||||||
|
|
||||||
|
|
||||||
class FileBroker(object):
|
class FileBroker(object):
|
||||||
""" Handles all access to meta and bib files of the repository.
|
""" Handles all access to meta and bib files of the repository.
|
||||||
|
|
||||||
@ -33,11 +34,11 @@ class FileBroker(object):
|
|||||||
|
|
||||||
def _create(self):
|
def _create(self):
|
||||||
if not check_directory(self.directory, fail = False):
|
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):
|
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):
|
if not check_directory(self.bibdir, fail = False):
|
||||||
os.mkdir(self.bibdir)
|
os.mkdir(system_path(self.bibdir))
|
||||||
|
|
||||||
def pull_metafile(self, citekey):
|
def pull_metafile(self, citekey):
|
||||||
filepath = os.path.join(self.metadir, citekey + '.yaml')
|
filepath = os.path.join(self.metadir, citekey + '.yaml')
|
||||||
@ -78,24 +79,23 @@ class FileBroker(object):
|
|||||||
else:
|
else:
|
||||||
return meta_exists or bib_exists
|
return meta_exists or bib_exists
|
||||||
|
|
||||||
|
|
||||||
def listing(self, filestats=True):
|
def listing(self, filestats=True):
|
||||||
metafiles = []
|
metafiles = []
|
||||||
for filename in os.listdir(self.metadir):
|
for filename in os.listdir(system_path(self.metadir)):
|
||||||
citekey = filter_filename(filename, '.yaml')
|
citekey = filter_filename(filename, '.yaml')
|
||||||
if citekey is not None:
|
if citekey is not None:
|
||||||
if filestats:
|
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)
|
metafiles.append(citekey, stats)
|
||||||
else:
|
else:
|
||||||
metafiles.append(citekey)
|
metafiles.append(citekey)
|
||||||
|
|
||||||
bibfiles = []
|
bibfiles = []
|
||||||
for filename in os.listdir(self.bibdir):
|
for filename in os.listdir(system_path(self.bibdir)):
|
||||||
citekey = filter_filename(filename, '.bib')
|
citekey = filter_filename(filename, '.bib')
|
||||||
if citekey is not None:
|
if citekey is not None:
|
||||||
if filestats:
|
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)
|
bibfiles.append(citekey, stats)
|
||||||
else:
|
else:
|
||||||
bibfiles.append(citekey)
|
bibfiles.append(citekey)
|
||||||
@ -118,7 +118,7 @@ class DocBroker(object):
|
|||||||
self.scheme = scheme
|
self.scheme = scheme
|
||||||
self.docdir = os.path.join(directory, subdir)
|
self.docdir = os.path.join(directory, subdir)
|
||||||
if not check_directory(self.docdir, fail = False):
|
if not check_directory(self.docdir, fail = False):
|
||||||
os.mkdir(self.docdir)
|
os.mkdir(system_path(self.docdir))
|
||||||
|
|
||||||
def in_docsdir(self, docpath):
|
def in_docsdir(self, docpath):
|
||||||
try:
|
try:
|
||||||
@ -143,7 +143,7 @@ class DocBroker(object):
|
|||||||
docpath = os.path.join(self.docdir, parsed.netloc, parsed.path[1:])
|
docpath = os.path.join(self.docdir, parsed.netloc, parsed.path[1:])
|
||||||
elif content_type(docpath) != 'file':
|
elif content_type(docpath) != 'file':
|
||||||
return docpath
|
return docpath
|
||||||
return os.path.normpath(os.path.abspath(docpath))
|
return docpath
|
||||||
|
|
||||||
def add_doc(self, citekey, source_path, overwrite=False):
|
def add_doc(self, citekey, source_path, overwrite=False):
|
||||||
""" Add a document to the docsdir, and return its location.
|
""" 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))
|
raise IOError('{} file exists.'.format(full_target_path))
|
||||||
|
|
||||||
doc_content = get_content(full_source_path)
|
doc_content = get_content(full_source_path)
|
||||||
with open(full_target_path, 'wb') as f:
|
write_file(full_target_path, doc_content)
|
||||||
f.write(doc_content)
|
|
||||||
|
|
||||||
return target_path
|
return target_path
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ def copy_dir(fs, real_dir, fake_dir = None):
|
|||||||
if fake_dir is None:
|
if fake_dir is None:
|
||||||
fake_dir = real_dir
|
fake_dir = real_dir
|
||||||
for filename in real_os.listdir(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)
|
fake_path = fs['os'].path.join(fake_dir, filename)
|
||||||
if real_os.path.isfile(real_path):
|
if real_os.path.isfile(real_path):
|
||||||
with real_open(real_path, 'r') as f:
|
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)
|
copy_dir(fs, real_path, fake_path)
|
||||||
|
|
||||||
|
|
||||||
# redirecting output
|
# redirecting output
|
||||||
|
|
||||||
def redirect(f):
|
def redirect(f):
|
||||||
def newf(*args, **kwargs):
|
def newf(*args, **kwargs):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user