Writing a hook - Red-C0der/Azurite-Framework GitHub Wiki
Writing a hook
File structure
- Decide what identifier you want to use. Usually you use something like
com.myname.shortname
wherecom.myname
can be your domain if you have one, or myname can be a nickname. Finallyshortname
should be a short but descriptive name of your hook / module or what else. - Create an empty directory inside the
hooks
directory of azurite and use your identifier as the name. - Create a
hook.py
file inside the new directory. Note thathook.py
MUST be lowercase!
Your directory structure should look something like this now:
Azurite/ # Top level directory
hooks/ # Holds all hooks and the Hook template class
com.myname.shortname/ # Your hook
info.py # Holds information used for repos and to load the hook
uniqueshortname.py # The code of your hook
Hook.py # Hook template
...
modules/
...
main.py
...
Before you start coding
Before you begin to code your awesome hook, you should pay attention to this:
- Hooks can only hook into already existing methods (either from azurite or some modules)! So if you want to make bigger projects or use the built in shell you should write a module.
- You might not be able to hook into all methods from other people's modules, but for the most part it should work fine.
- Before continuing check if your identifier or hook name (define later) is not used by any other hook or module. (This tool might help you: Not available yet :( ).
So, you're still reading? Then let's start writing a hook. (I guess that at this point you already know what functionality / enhancements your hook will do).
Writing the hook
System things
After you have opened the hooks.py
file (not the template) insert this block of code at the top:
# coding: utf-8
import os,sys,inspect
sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))))
from Hook import Hook
This will allow you to use special characters, let you import the Hook.py
template and the import that.
Next up you should insert this block:
class CustomHook(Hook):
def __post_init__(self):
self.name = 'A unique name to describe your hook'
self.identifier = 'com.myname.shortname'
self.description = 'A short and snappy description of your hooks functionality'
self.version = '1.0.0'
self.target_version = '1.0.0'
self.target_os = ['osx', 'linux', 'windows', 'ios', 'android']
self.dependencies = {
'hooks': [],
'modules': [],
'python_modules': []
}
Here you can change some values. Here's a description of the more complicated ones:
self.target_version
- This sets the version of azurite your hook is made for and there for work fine with that version.
self.target_os
- Defines the supported operating systems. Just remove one from the list, if it doesn't support your hook.
self.dependencies
- Here you can add other hook / modules or python modules, which need to be installed in order for your hook to be loaded and work properly. To add a dependency, add the identifier as a string to the list corresponding to the correct type (So for a module, add the identifier to the modules
key inside the dict). Here is an example:
self.dependencies = {
'hooks': ['tk.red_c0der.logger'],
'modules': ['com.myname.shortname'],
'python_modules': ['termcolor', 'os', 'custompythonmodule']
}
Adding functionality
So, at this point if you did everything right, your hook should get loaded into the system without any errors.
If so, you can start adding some functionality by adding one or more of these methods to the CustomHook
class:
def hook_pre_all(self, *args, **kwargs)
- Gets called before every method with all arguments of the method.def hook_post_all(self, *args, **kwargs)
- Gets called after every method with all arguments of the method.def hook_pre_methodname(self, *args, **kwargs)
- Gets called before every call othe themethodname
method.def hook_post_methodname(self, *args, **kwargs)
- Same as above but gets called after the method has finished.
Inside these methods there is plenty of space for your code to rest, which can make use of the *args and **kwargs which are passed on by the original method.
Usually *args (which is a tuple) looks like this:
(azurite_instance, method args, ...)
So it's possible to make use of the azurite instance and call other methods if needed.