More documentation for experimental Python support

This commit is contained in:
Marcus Holland-Moritz 2020-12-06 17:28:49 +01:00
parent de72939d69
commit ee3ebf449a
3 changed files with 74 additions and 1 deletions

View File

@ -212,7 +212,7 @@ If possible, try building with clang as your compiler, this will
make DwarFS significantly faster. If you have both gcc and clang make DwarFS significantly faster. If you have both gcc and clang
installed, use: installed, use:
# cmake .. -DWITH_TESTS=1 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ # CC=clang CXX=clang++ cmake .. -DWITH_TESTS=1
To build with experimental Lua support, you need to install both To build with experimental Lua support, you need to install both
`lua` and `luabind`. The latter isn't very well maintained and I `lua` and `luabind`. The latter isn't very well maintained and I
@ -231,6 +231,23 @@ Installing is as easy as:
Though you don't have to install the tools to play with them. Though you don't have to install the tools to play with them.
### Experimental Python Scripting Support
You can build `mkdwarfs` with experimental support for Python
scripting:
# cmake .. -DWITH_TESTS=1 -DWITH_PYTHON=1
This also requires Boost.Python. If you have multiple Python
versions installed, you can explicitly specify the version to
build against:
# cmake .. -DWITH_TESTS=1 -DWITH_PYTHON=1 -DWITH_PYTHON_VERSION=3.8
Note that only Python 3 is supported. You can take a look at
[scripts/example.py](scripts/example.py) to get an idea for
what can currently be done with the interface.
## Usage ## Usage
Please check out the man pages for [mkdwarfs](doc/mkdwarfs.md) Please check out the man pages for [mkdwarfs](doc/mkdwarfs.md)

View File

@ -167,6 +167,14 @@ Most other options are concerned with compression tuning:
Show program help, including defaults, compression level detail and Show program help, including defaults, compression level detail and
supported compression algorithms. supported compression algorithms.
If experimental Python support was compiled into `mkdwarfs`, you can use the
following option to enable customizations via the scripting interface:
* `--script=`*file*[`:`*class*[`(`arguments`...)`]]:
Specify the Python script to load. The class name is optional if there's
a class named `mkdwarfs` in the script. It is also possible to pass
arguments to the constuctor.
## TIPS & TRICKS ## TIPS & TRICKS
### Compression Ratio vs Decompression Speed ### Compression Ratio vs Decompression Speed

View File

@ -1,24 +1,72 @@
class mkdwarfs(object): class mkdwarfs(object):
"""
The class defining mkdwarfs customization.
If this is named `mkdwarfs`, you only have to specify the path to
the script file with `--script`. You can define multiple classes in
a single script, in which case you'll have to pass the class name
in addition to the script path as `--script <file>:<class>`. If the
class has a custom contructor, it is also possible to pass arguments
to the constuctor from the command line.
All methods are optional. If you want to define methods beyond the
ones specified below, make sure you start their names with an
underscore, otherwise there will be a warning to ensure you don't
accidentally mistype the names of the methods.
You can use the global `logger` object for logging.
"""
def __init__(self): def __init__(self):
"""
Optional constructor
"""
logger.info("this is python!") logger.info("this is python!")
def configure(self, config): def configure(self, config):
"""
Configuration
This will be called early and allows you to change the default
for or even override (command line) parameters. Only a small
number of parameters are currently supported.
"""
# Enable similarity hash computation, useful if you actually
# want to use it in the `order` method.
config.enable_similarity() config.enable_similarity()
config.set_order(file_order_mode.script, set_mode.override) config.set_order(file_order_mode.script, set_mode.override)
config.set_remove_empty_dirs(True, set_mode.default) config.set_remove_empty_dirs(True, set_mode.default)
def filter(self, entry): def filter(self, entry):
"""
Filtering
This will be called for every file system entry. If you return
`False`, the entry will be skipped.
"""
logger.debug(f"filter: {entry.path()} [{entry.type()}]") logger.debug(f"filter: {entry.path()} [{entry.type()}]")
if entry.type() == 'directory' and entry.name() == 'dev': if entry.type() == 'directory' and entry.name() == 'dev':
return False return False
return True return True
def transform(self, entry): def transform(self, entry):
"""
Transformation
This will be called for every entry that has not been filtered,
and allows you to change certain attributes, such as permissions,
ownership, or timestamps.
"""
logger.debug(f"transform {entry.path()}") logger.debug(f"transform {entry.path()}")
entry.set_permissions(entry.permissions() & 0o7555) entry.set_permissions(entry.permissions() & 0o7555)
return entry return entry
def order(self, inodes): def order(self, inodes):
"""
Inode Ordering
This will be called for every regular file inode, after all
entries have been scanned and files have been deduplicated.
"""
logger.info("order") logger.info("order")
for i in inodes: for i in inodes:
logger.debug(f"inode: {i.similarity_hash()} {i.size()} {i.refcount()}") logger.debug(f"inode: {i.similarity_hash()} {i.size()} {i.refcount()}")