Here are some of the features of the python plugin interface:
As of HexChat 2.9.6 the plugin supports both so which should you pick:
As a user most older scripts will not be updated for Python 3 so 2 is your best bet.
As a developer I would just recommend you make your scripts compatible for both but do note that the Python 2 plugin on Windows does not support threads while the Python 3 plugin does.
The Python plugin comes with a py command that takes these arguments.
load
<file>
¶Load a script with given filename. /load will also work.
unload
<filename|module name>
¶Unload module with given filename, or module name. /unload will also work.
reload
<filename|module name>
¶Reload module with given filename, or module name. /reload will also work.
list
¶List Python scripts loaded
exec
<command>
¶Execute given Python command interactively. For example:
/py exec import hexchat; print(hexchat.get_info('channel'))
console
¶Open the Python interactive console in a query
>>python<<
. Every message sent will be intercepted by the Python
plugin interface, and interpreted interactively. Notice that the
console and /py exec commands live in the same interpreter state.
about
¶Show some information about the Python plugin interface.
If you want some module to be autoloaded together with the Python plugin
interface (which usually loads at startup time), just make sure it has a
.py
extension and put it in the addons
subdir
of HexChat’s config directory.
Before starting to explain what the API offers, I’ll do a short introduction about the HexChat context concept. Not because it’s something hard to understand, but because you’ll understand better the API explanations if you know what I’m talking about.
You can think about a context as an HexChat channel, server, or query tab. Each of these tabs, has its own context, and is related to a given server and channel (queries are a special kind of channel).
The current context is the one where HexChat passes control to the module. For example, when HexChat receives a command in a specific channel, and you have asked HexChat to tell you about this event, the current context will be set to this channel before your module is called.
'\002'
'\003'
'\010'
'\037'
'\017'
'\026'
'\007'
'\035'
(2.10.0+)For example this will print underlined red text:
print('\037\00304Text!')
Some lists return bit fields which many Python scripters may not be familair with so here is an example of how to use one:
...
# We know its the 15th bit field we want, this will get that value
text_strip = 1 << 15
text_strip_unset = 1 << 16 # If this is set use the global option
def get_chanopt (channel, option):
for chan in hexchat.get_list('channels'):
if chan.channel == channel:
return bool(chan.flags & option)
if get_chanopt('#hexchat', text_strip_unset):
stripped = bool(hexchat.get_prefs('text_stripcolor_msg'))
else:
stripped = get_chanopt ('#hexchat', text_strip)
print('Color stripping in #hexchat is: {}'.format(stripped))
Here is the traditional hello world example.
__module_name__ = "helloworld"
__module_version__ = "1.0"
__module_description__ = "Python module example"
print("Hello world!")
This module will print “Hello world!” in the HexChat console, and sleep forever until it’s unloaded. It’s a simple module, but already introduces some concepts. Notice how the module information is set. This information is obligatory, and will be shown when listing the loaded HexChat modules.
The hexchat module is your passport to every HexChat functionality offered by the Python plugin interface. Here’s a simple example:
import hexchat
hexchat.prnt("Hi everyone!")
The following functions are available in the hexchat module.
hexchat.
PRI_HIGHEST
¶hexchat.
PRI_HIGH
¶hexchat.
PRI_NORM
¶hexchat.
PRI_LOW
¶hexchat.
PRI_LOWEST
¶Priority given to hooks.
hexchat.
EAT_PLUGIN
¶hexchat.
EAT_HEXCHAT
¶hexchat.
EAT_ALL
¶hexchat.
EAT_NONE
¶Used as return values for callbacks.
hexchat.
__version__
¶Tuple of (MAJOR_VERSION, MINOR_VERSION)
hexchat.
prnt
(string)¶This function will print string in the current context. It’s mainly useful as a parameter to pass to some other function, since the usual print statement will have the same results. You have a usage example above.
This function is badly named because "print"
is a reserved keyword
of the Python language until Python 3.
hexchat.
emit_print
(event_name, *args)¶This function will generate a print event with the given arguments. To check which events are available, and the number and meaning of arguments, have a look at the
window. Here is one example:hexchat.emit_print("Channel Message", "John", "Hi there", "@")
With plugin version 1.0+ this function takes keywords for certain attributes such as time.
hexchat.
command
(string)¶Execute the given command in the current context. This has the same
results as executing a command in the HexChat window, but notice that
the /
prefix is not used. Here is an example:
hexchat.command("server irc.openprojects.net")
A list of commands is provided here: List of Commands.
hexchat.
nickcmp
(s1, s2)¶This function will do an RFC1459 compliant string comparison and is useful to compare channels and nicknames.
Returns: | Returns 0 if they match and less than or greater than 0 if s1 is less than or greather than s2 |
---|
if hexchat.nickcmp(nick, "mynick") == 0:
print("They are the same!")
hexchat.
strip
(text[, length=-1, flags=3])¶This function can strip colors and attributes from text.
Parameters: |
|
---|---|
Returns: | Stripped String |
text = '\00304\002test' # Bold red text
print(text)
print(hexchat.strip(text, len(text), 1)) # Bold uncolored text
hexchat.
get_info
(type)¶Retrieve the information specified by the type
string in the current
context. At the moment of this writing, the following information types
are available to be queried:
Example:
if hexchat.get_info("network") == 'freenode':
hexchat.prnt('connected!')
You can also get the format of Text Events by using event_text and the event:
print(hexchat.get_info("event_text Channel Message"))
hexchat.
get_prefs
(name)¶Retrieve the HexChat setting information specified by the name
string, as available by the /set
command.
print("Current preferred nick: " + hexchat.get_prefs("irc_nick1"))
A list of settings is provided here: List of Settings.
On top of that there are a few special preferences:
hexchat.
get_list
(type)¶With this function you may retrieve a list containing the selected information from the current context, like a DCC list, a channel list, a user list, etc. Each list item will have its attributes set dynamically depending on the information provided by the list type.
The example below is a rewrite of the example provided with HexChat’s plugin API documentation. It prints a list of every DCC transfer happening at the moment. Notice how similar the interface is to the C API provided by HexChat.
list = hexchat.get_list("dcc")
if list:
print("--- DCC LIST ------------------")
print("File To/From KB/s Position")
for i in list:
print("%6s %10s %.2f %d" % (i.file, i.nick, i.cps/1024, i.pos))
Below you will find what each list type has to offer.
The channels list type gives you access to the channels, queries and their servers. The following attributes are available in each list item:
The dcc list type gives you access to a list of DCC file transfers. The following attributes are available in each list item:
The users list type gives you access to a list of users in the current channel. The following attributes are available in each list item:
The ignore list type gives you access to the current ignored list. The following attributes are available in each list item:
The notify list shows users on your friends list and their status:
These functions allow one to hook into HexChat events.
A callback is the function that will be called when the event happens.
The callback supposed to return one of the EAT_* constants, it is able control how HexChat will proceed after the callback returns. These are the available constants, and their meanings:
EAT_PLUGIN
: Don’t let any other plugin receive this event.EAT_HEXCHAT
: Don’t let HexChat treat this event as usual.EAT_ALL
: Eat the event completely.EAT_NONE
: Let everything happen as usual.Note
Returning None
is the same as returning EAT_NONE
.
The parameter userdata, if given, allows you to pass a custom object to your callback.
If you create a hook with hook_server_attrs()
or hook_print_attrs()
the last
argument in the callback will be an Attribute object.
Attribute
Attribute.
time
¶The time the event occurred (from server-time) or 0
When a priority keyword parameter is accepted, it means that this
callback may be hooked with five different priorities which are
constants will define the
order in which your plugin will be called. Most of the time, you won’t
want to change its default value (PRI_NORM
).
These parameters, when available in a command or server callback, are lists of strings which contain the parameters the user entered for the particular command. For example, if you executed:
/command NICK Hi there!
command
NICK
Hi
there!
command NICK Hi there!
NICK Hi there!
Hi there!
there!
These parameters are also used in print events. When created by these events they have a completely different meaning though. Text events (
) have numbered arguments associated with them, these apply to the item in the word list. For example on a “Channel Message” event:[23:29:26] <@Nick> hello everyone
Nick
hello everyone
@
Nick hello everyone @
hello everyone @
@
hexchat.
hook_command
(name, callback[, userdata=None, priority=PRI_NORM, help=None])¶This function allows you to hook into the name HexChat command. It means
that everytime you type /name ...
, callback
will be called.
Parameters userdata
and priority
have their meanings explained
above, and the parameter help, if given, allows you to pass a help text
which will be shown when /help name
is executed.
You may also hook an empty string to capture every message a user sends,
either when they hit enter or use /say
. If you start the name with a
period it will not show up in /help
.
Returns: | New Hook Handler |
---|
def onotice_cb(word, word_eol, userdata):
if len(word) < 2:
print("Second arg must be the message!")
else:
hexchat.command("NOTICE @{} {}".format(hexchat.get_info("channel"), word_eol[1]))
return hexchat.EAT_ALL
hexchat.hook_command("ONOTICE", onotice_cb, help="/ONOTICE <message> Sends a notice to all ops")
You may return one of EAT_*
constants in the callback, to control
HexChat’s behavior, as explained above.
hexchat.
hook_print
(name, callback[, userdata=None, priority=PRI_NORM])¶This function allows you to register a callback to trap any print
events. The event names are available in the userdata
and priority
have their meanings explained
above.
Parameters: | name – event name (see | )
---|---|
Returns: | New Hook Handler |
def youpart_cb(word, word_eol, userdata):
print("You have left channel " + word[2])
return hexchat.EAT_HEXCHAT # Don't let HexChat do its normal printing
hexchat.hook_print("You Part", youpart_cb)
Along with Text Events there are a handfull of special events you can hook with this:
hexchat.
hook_print_attrs
(name, callback[, userdata=None, priority=PRI_NORM])¶This function is the same as hook_print()
except its callback will have a new
Attribute argument.
Returns: | New Hook Handler |
---|
New in version 1.0.
def youpart_cb(word, word_eol, userdata, attributes):
if attributes.time: # Time may be 0 if server-time is not enabled.
print("You have left channel {} at {}".format(word[2], attributes.time))
return hexchat.EAT_HEXCHAT
hexchat.hook_print_attrs("You Part", youpart_cb)
hexchat.
hook_server
(name, callback[, userdata=None, priority=PRI_NORM])¶This function allows you to register a callback to be called when a
certain server event occurs. You can use this to trap PRIVMSG
,
NOTICE
, PART
, a server numeric, etc. Parameters userdata
and
priority
have their meanings explained above.
You can hook the special event “RAW LINE” to capture all server events.
Returns: | New Hook Handler |
---|
def kick_cb(word, word_eol, userdata):
print('{} was kicked from {} ({})'.format(word[3], word[2], word_eol[4]))
# Don't eat this event, let other plugins and HexChat see it too
return hexchat.EAT_NONE
hexchat.hook_server("KICK", kick_cb)
hexchat.
hook_server_attrs
(name, callback[, userdata=None, priority=PRI_NORM])¶This function is the same as hook_server()
Except its callback will have a new
Attribute argument.
Returns: | New Hook Handler |
---|
New in version 1.0.
def kick_cb(word, word_eol, userdata, attributes):
if attributes.time: # Time may be 0 if server-time is not enabled.
print('He was kicked at {}'.format(attributes.time))
return hexchat.EAT_NONE
hexchat.hook_server_attrs("KICK", kick_cb)
hexchat.
hook_timer
(timeout, callback[, userdata=None])¶This function allows you to register a callback to be called every timeout milliseconds. Parameters userdata and priority have their meanings explained above.
Returns: | New Hook Handler |
---|
myhook = None
def stop_cb(word, word_eol, userdata):
global myhook
if myhook is not None:
hexchat.unhook(myhook)
myhook = None
print("Timeout removed!")
def timeout_cb(userdata):
print("Annoying message every 5 seconds! Type /STOP to stop it.")
return 1 # Keep the timeout going
myhook = hexchat.hook_timer(5000, timeout_cb)
hexchat.hook_command("STOP", stop_cb)
If you return a true value from the callback, the timer will be kept, otherwise it is removed.
hexchat.
hook_unload
(callback[, userdata=None])¶This function allows you to register a callback to be called when the
plugin is going to be unloaded. Parameters userdata
and priority
have their meanings explained above.
Returns: | New Hook Handler |
---|
def unload_cb(userdata):
print("We're being unloaded!")
hexchat.hook_unload(unload_cb)
hexchat.
unhook
(handler)¶Unhooks any hook registered with the hook functions above.
Parameters: | handler – Handler returned from hook_print() , hook_command() , hook_server() or hook_timer() |
---|
As of version 1.0 of the plugin hooks from hook_print()
and hook_command()
can be unhooked by their names.
You can use pluginpref to easily store and retrieve settings.
hexchat.
set_pluginpref
(name, value)¶Stores settings in addon_python.conf in the config dir.
Returns: |
|
---|
New in version 0.9.
Note
Until the plugin uses different a config file per script it’s recommened to use ‘scriptname_settingname’ to avoid conflicts.
hexchat.
get_pluginpref
(name)¶This will return the value of the variable of that name. If there is
none by this name it will return None
.
Returns: | String or Integer of stored setting or None if it does not exist. |
---|
Note
Strings of numbers and booleans are always returned as Integers.
New in version 0.9.
hexchat.
del_pluginpref
(name)¶Deletes the specified variable.
Returns: |
|
---|
New in version 0.9.
hexchat.
list_pluginpref
()¶Returns a list of all currently set preferences.
Return type: | List of Strings |
---|
New in version 0.9.
Below you will find information about how to work with contexts.
As explained in the Context theory session above, contexts give access to a specific channel/query/server tab of HexChat. Every function available in the xchat module will be evaluated in the current context, which will be specified by HexChat itself before passing control to the module. Sometimes you may want to work in a specific context, and that’s where context objects come into play.
You may create a context object using get_context()
or find_context()
functions as explained below, or trough the get_list()
function, as explained above.
hexchat.
get_context
()¶Return type: | context |
---|
hexchat.
find_context
(server=None, channel=None)¶Finds a context based on a channel and servername or if no parameters are given returns the current (front) context.
Parameters: |
|
---|---|
Return type: | context |
cnc = hexchat.find_context(channel='#conectiva')
cnc.command('whois niemeyer')
context
The context object returned by the functions listed above has these methods:
context.
set
()¶Changes the current context to be the one represented by this context object.
context.
emit_print
(event_name, *args)¶Does the same as the emit_print()
function but in the given context.
context.
get_info
(type)¶Does the same as the get_info()
function but in the given context.
context.
get_list
(type)¶Does the same as the get_list()
function but in the given context.
Maintained by: TingPing
Original Author: Gustavo Niemeyer gustavo@niemeyer.net