ufoLib: add readData, writeData and removeData methods

This commit is contained in:
Cosimo Lupo 2018-10-21 15:42:02 +01:00
parent 96ca09c39e
commit fe4381df56
No known key found for this signature in database
GPG Key ID: 59D54DB0C9976482

View File

@ -688,12 +688,18 @@ class UFOReader(object):
This will not list directory names, only file names. This will not list directory names, only file names.
Thus, empty directories will be skipped. Thus, empty directories will be skipped.
""" """
try:
self._dataFS = self.fs.opendir(DATA_DIRNAME)
except fs.errors.ResourceNotFound:
return []
except fs.errors.DirectoryExpected:
raise UFOLibError("The UFO contains a \"data\" file instead of a directory.")
try: try:
# fs Walker.files method returns "absolute" paths (in terms of the # fs Walker.files method returns "absolute" paths (in terms of the
# root of the 'data' SubFS), so we strip the leading '/' to make # root of the 'data' SubFS), so we strip the leading '/' to make
# them relative # them relative
return [ return [
p.lstrip("/") for p in self.fs.opendir(DATA_DIRNAME).walk.files() p.lstrip("/") for p in self._dataFS.walk.files()
] ]
except fs.errors.ResourceError: except fs.errors.ResourceError:
return [] return []
@ -711,12 +717,13 @@ class UFOReader(object):
return [] return []
if validate is None: if validate is None:
validate = self._validate validate = self._validate
if not self.fs.exists(IMAGES_DIRNAME): try:
self._imagesFS = imagesFS = self.fs.opendir(IMAGES_DIRNAME)
except fs.errors.ResourceNotFound:
return [] return []
elif not self.fs.isdir(IMAGES_DIRNAME): except fs.errors.DirectoryExpected:
raise UFOLibError("The UFO contains an \"images\" file instead of a directory.") raise UFOLibError("The UFO contains an \"images\" file instead of a directory.")
result = [] result = []
self._imagesFS = imagesFS = self.fs.opendir(IMAGES_DIRNAME)
for path in imagesFS.scandir("/"): for path in imagesFS.scandir("/"):
if path.is_dir: if path.is_dir:
# silently skip this as version control # silently skip this as version control
@ -731,6 +738,22 @@ class UFOReader(object):
result.append(path.name) result.append(path.name)
return result return result
def readData(self, fileName):
"""
Return bytes for the file named 'fileName' inside the 'data/' directory.
"""
fileName = fsdecode(fileName)
try:
try:
dataFS = self._dataFS
except AttributeError:
# in case readData is called before getDataDirectoryListing
dataFS = self.fs.opendir(DATA_DIRNAME)
data = dataFS.getbytes(fileName)
except fs.errors.ResourceNotFound:
raise UFOLibError("No data file named '%s' on %s" % (fileName, self.fs))
return data
def readImage(self, fileName, validate=None): def readImage(self, fileName, validate=None):
""" """
Return image data for the file named fileName. Return image data for the file named fileName.
@ -742,15 +765,16 @@ class UFOReader(object):
validate = self._validate validate = self._validate
if self._formatVersion < 3: if self._formatVersion < 3:
raise UFOLibError("Reading images is not allowed in UFO %d." % self._formatVersion) raise UFOLibError("Reading images is not allowed in UFO %d." % self._formatVersion)
fileName = fsdecode(fileName)
try:
try: try:
imagesFS = self._imagesFS imagesFS = self._imagesFS
except AttributeError: except AttributeError:
# in case readImage is called before getImageDirectoryListing # in case readImage is called before getImageDirectoryListing
imagesFS = self.fs.opendir(IMAGES_DIRNAME) imagesFS = self.fs.opendir(IMAGES_DIRNAME)
fileName = fsdecode(fileName)
data = imagesFS.getbytes(fileName) data = imagesFS.getbytes(fileName)
if data is None: except fs.errors.ResourceNotFound:
raise UFOLibError("No image file named %s." % fileName) raise UFOLibError("No image file named '%s' on %s" % (fileName, self.fs))
if validate: if validate:
valid, error = pngValidator(data=data) valid, error = pngValidator(data=data)
if not valid: if not valid:
@ -1527,6 +1551,19 @@ class UFOWriter(object):
self.removePath(foundDirectory, removeEmptyParents=False) self.removePath(foundDirectory, removeEmptyParents=False)
del self.layerContents[layerName] del self.layerContents[layerName]
def writeData(self, fileName, data):
"""
Write data to fileName in the 'data' directory.
The data must be a bytes string.
"""
self.writeBytesToPath("%s/%s" % (DATA_DIRNAME, fsdecode(fileName)), data)
def removeData(self, fileName):
"""
Remove the file named fileName from the data directory.
"""
self.removePath("%s/%s" % (DATA_DIRNAME, fsdecode(fileName)))
# /images # /images
def writeImage(self, fileName, data, validate=None): def writeImage(self, fileName, data, validate=None):