Source code for PyPoE.poe.file.shared.cache
"""
Overview
===============================================================================
+----------+------------------------------------------------------------------+
| Path | PyPoE/poe/file/shared/cache.py |
+----------+------------------------------------------------------------------+
| Version | 1.0.0a0 |
+----------+------------------------------------------------------------------+
| Revision | $Id: 5ea9fe7986eed9718fcd927eaa1d8ec1498edb24 $ |
+----------+------------------------------------------------------------------+
| Author | Omega_K2 |
+----------+------------------------------------------------------------------+
Description
===============================================================================
All file caches classes will inherit :class:`AbstractFileCache`.
.. warning::
None of the abstract classes found here should be instantiated directly.
See also:
* :mod:`PyPoE.poe.file.shared`
* :mod:`PyPoE.poe.file.shared.keyvalues`
Agreement
===============================================================================
See PyPoE/LICENSE
Documentation
===============================================================================
.. autoclass:: AbstractFileCache
:private-members:
"""
# =============================================================================
# Imports
# =============================================================================
# Python
import os
# 3rd-party
# self
from PyPoE.shared.mixins import ReprMixin
from PyPoE.poe.file.ggpk import GGPKFile
# =============================================================================
# Globals
# =============================================================================
__all__ = ['AbstractFileCache']
# =============================================================================
# Classes
# =============================================================================
[docs]class AbstractFileCache(ReprMixin):
"""
Attributes
----------
'_ggpk' : GGPKFile
'_path' : str
'files' : dict[str, AbstractFileReadOnly]
Dictionary of loaded file instances and their related path
"""
FILE_TYPE = None
[docs] def __init__(self, path_or_ggpk=None, files=None, files_shortcut=True,
instance_options=None, read_options=None):
"""
Parameters
----------
path_or_ggpk : str | GGPKFile
The root path (i.e. relative to content.ggpk) where the files are
stored or a :class:`PyPoE.poe.file.ggpk.GGPKFile` instance
files : Iterable
Iterable of files that will be loaded right away
files_shortcut : bool
Whether to use the shortcut function, i.e. self.__getitem__
instance_options : dict[str, object]
options to pass to the file's __init__ method
read_options : dict[str, object]
options to pass to the file instance's read method
Raises
------
TypeError
if path_or_ggpk not specified or invalid type
ValueError
if a :class:`PyPoE.poe.file.ggpk.GGPKFile` was passed, but it was
not parsed
"""
if isinstance(path_or_ggpk, GGPKFile):
if not path_or_ggpk.is_parsed:
raise ValueError('The GGPK File must be parsed.')
self._ggpk = path_or_ggpk
self._path = None
elif isinstance(path_or_ggpk, str):
self._ggpk = None
self._path = path_or_ggpk
else:
raise TypeError(
'path_or_ggpk must be a valid directory or GGPKFile'
)
self.instance_options = {} if instance_options is None else \
instance_options
self.read_options = {} if read_options is None else read_options
self.files = {}
read_func = self.__getitem__ if files_shortcut else self.get_file
if files is not None:
for file in files:
read_func(file)
def __getitem__(self, item):
"""
Shortcut.
Equivalent:
* AbstractFileCache[item] <==> AbstractFileCache.read_file(item)
Parameters
----------
item : str
item to retrieve
Returns
-------
AbstractFileReadOnly
instance
"""
return self.get_file(item)
[docs] def _get_file_instance_args(self, file_name, *args, **kwargs):
"""
Returns a dictionary of keyword arguments to pass to the file's
__init__ method upon initial reading.
Parameters
----------
file_name : str
Name of the file
Returns
-------
dict[str, object]
Dictionary of keyword arguments
"""
options = dict(self.instance_options)
return options
[docs] def _get_read_args(self, file_name, *args, **kwargs):
"""
Returns a dictionary of keyword arguments to pass to the file's
read method upon initial reading.
In particular it sets file_path_or_raw based on how the cache was
instantiated.
Parameters
----------
file_name : str
Name of the file
Returns
-------
dict[str, object]
Dictionary of keyword arguments
"""
options = dict(self.read_options)
if self._ggpk:
options['file_path_or_raw'] = self._ggpk[file_name].record.extract()
elif self._path:
options['file_path_or_raw'] = os.path.join(self._path, file_name)
return options
[docs] def _create_instance(self, file_name, *args, **kwargs):
"""
Creates a new instance for the given file name
Parameters
----------
file_name : str
Name to the file to pass on
Returns
-------
File instance
"""
f = self.FILE_TYPE(
**self._get_file_instance_args(file_name=file_name, *args, **kwargs)
)
f.read(**self._get_read_args(file_name=file_name, *args, **kwargs))
return f
[docs] def get_file(self, file_name, *args, **kwargs):
"""
Returns the the specified file from the cache.
If the file does not exist, read it from the path specified on cache
creation, add it to the cache and then return it.
Parameters
----------
file_name : str
File to retrieve
Returns
-------
AbstractFileReadOnly
read file instance
"""
if file_name not in self.files:
f = self._create_instance(file_name=file_name)
self.files[file_name] = f
else:
f = self.files[file_name]
return f
@property
def path_or_ggpk(self):
"""
The path or :class:`PyPoE.poe.file.ggpk.GGPKFile` instance the cache
was created with
"""
return self._path or self._ggpk