Source code for yael.asset
#!/usr/bin/env python
# coding=utf-8
"""
An asset (file) of a Publication.
The asset is identified by its `internal_path`
inside the virtual container of the publication.
The contents of the asset can be specified:
1. by storing its bytes in the `data` property
2. by specifying the `absolute_path` to a file on disk
3. by specifying the `absolute_path` (pointing to a directory on disk)
and the corresponding `relative_path` (to a file)
4. by specifying the `absolute_path` (pointing to a ZIP file on disk)
and the corresponding `relative_path` (the ZIP entry name)
"""
import os
import zipfile
from yael.jsonable import JSONAble
import yael.util
__author__ = "Alberto Pettarin"
__copyright__ = "Copyright 2015, Alberto Pettarin (www.albertopettarin.it)"
__license__ = "MIT"
__version__ = "0.0.6"
__email__ = "alberto@albertopettarin.it"
__status__ = "Development"
[docs]class Asset(JSONAble):
"""
Build an asset.
:param absolute_path: the absolute path
:type absolute_path: str
:param relative_path: the relative path
:type relative_path: str
:param internal_path: the internal path
:type internal_path: str
:param data: a data (bytes) object
:type data: bytes
"""
def __init__(
self,
absolute_path=None,
relative_path=None,
internal_path=None,
data=None):
self.absolute_path = absolute_path
self.relative_path = relative_path
self.internal_path = internal_path
self.data = data
self.obfuscation_algorithm = None
self.obfuscation_key = None
def json_object(self, recursive=True):
obj = {
"absolute_path": self.absolute_path,
"relative_path": self.relative_path,
"internal_path": self.internal_path,
"data": (self.data == None),
"obfuscation_algorithm": self.obfuscation_algorithm,
"obfuscation_key": self.obfuscation_key,
}
return obj
@property
def absolute_path(self):
"""
The absolute path of the container of this asset
(if `relative_path` is not None) or
the absolute path of this asset
(if `relative_path` is None).
:rtype: str
"""
return self.__absolute_path
@absolute_path.setter
def absolute_path(self, absolute_path):
self.__absolute_path = absolute_path
@property
def relative_path(self):
"""
The path of this asset,
relative to the container root
specified by `absolute_path`.
:rtype: str
"""
return self.__relative_path
@relative_path.setter
def relative_path(self, relative_path):
self.__relative_path = relative_path
@property
def internal_path(self):
"""
The internal path of this asset,
relative to the virtual container root.
:rtype: str
"""
return self.__internal_path
@internal_path.setter
def internal_path(self, internal_path):
self.__internal_path = internal_path
@property
def data(self):
"""
The contents (i.e., bytes) of this asset,
set programmatically.
:rtype: bytes
"""
return self.__data
@data.setter
def data(self, data):
self.__data = data
@property
def obfuscation_algorithm(self):
"""
The obfuscation algorithm to be used
or None if the asset should not be obfuscated.
:rtype: :class:`yael.obfuscation.Obfuscation`
"""
return self.__obfuscation_algorithm
@obfuscation_algorithm.setter
def obfuscation_algorithm(self, obfuscation_algorithm):
self.__obfuscation_algorithm = obfuscation_algorithm
@property
def obfuscation_key(self):
"""
The obfuscation key to be used
or None if the asset should not be obfuscated.
:rtype: str
"""
return self.__obfuscation_key
@obfuscation_key.setter
def obfuscation_key(self, obfuscation_key):
self.__obfuscation_key = obfuscation_key
@property
def contents(self):
"""
The contents of this asset.
The return value is obtained by either reading
the `data` property (case 1), or by suitably
reading the contents from the file system
(cases 2, 3, and 4).
If the asset is obfuscated, this function
will run the (un)obfuscation algorithm
on the raw_contents.
:rtype: bytes
"""
raw_data = self.raw_contents
if self.obfuscation_key == None:
return raw_data
return yael.util.obfuscate_data(
data=raw_data,
key=self.obfuscation_key,
algorithm=self.obfuscation_algorithm)
@property
def raw_contents(self):
"""
The raw contents of this asset.
The return value is obtained by either reading
the `data` property (case 1), or by suitably
reading the contents from the file system
(cases 2, 3, and 4).
:rtype: bytes
"""
if self.data != None:
return self.data
try:
if (
(self.absolute_path != None) and
(os.path.exists(self.absolute_path))):
if (
(os.path.isdir(self.absolute_path)) or
(self.relative_path == None)):
if self.relative_path == None:
# uncompressed, abs pointing to a file
a_p_asset = self.absolute_path
else:
# uncompressed, abs + rel
a_p_asset = yael.util.norm_join(
self.absolute_path,
self.relative_path)
fil = open(a_p_asset, mode="rb")
string = fil.read()
fil.close()
return string
else:
# compressed
zip_file = zipfile.ZipFile(self.absolute_path, mode="r")
string = zip_file.read(self.relative_path)
zip_file.close()
return string
except:
pass
return None