Skip to content

Commit 14cd827

Browse files
documentation wheeee
1 parent 6f6c6ca commit 14cd827

File tree

1 file changed

+261
-0
lines changed

1 file changed

+261
-0
lines changed

doc/doc.rst

+261
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
Introduction to asyncirc
2+
========================
3+
4+
Asyncirc is an IRC library based on Python's asyncio. It is designed to be easy
5+
to use, to provide a nice way of processing IRC events, and to provide a Good
6+
Enough(TM) abstraction of the IRC protocol. It is *not* designed to be a ready-
7+
made bot framework, or to be used without some knowledge of how IRC works.
8+
9+
Installation
10+
------------
11+
You can install asyncirc from PyPI, using whatever method you prefer. The
12+
package name is ``asyncio-irc``.
13+
14+
Signals
15+
-------
16+
Instead of using callback-style event handler registration, asyncirc uses
17+
*signals*. Signals are provided by the excellent
18+
`Blinker<https://pythonhosted.org/blinker/>`_ library. It would be advisable
19+
to read that page for more information on signals, but the tl;dr is::
20+
21+
# register a signal handler
22+
signal("signal-name").connect(signal_handler_function)
23+
24+
# send a signal
25+
signal("signal-name").send(sender, some="keyword", argu="ments")
26+
27+
Asyncirc defines a lot of signals, which are covered in detail below.
28+
29+
Usage
30+
=====
31+
32+
Actually using asyncirc is pretty simple. First you need to import it::
33+
34+
from asyncirc import irc
35+
36+
Then you need to create a connection::
37+
38+
conn = irc.connect("chat.freenode.net", 6697, use_ssl=True)
39+
40+
You'll need to register with the server::
41+
42+
conn.register("nickname", "ident", "realname (can contain spaces)")
43+
44+
Once you're registered and connected, you'll want to join some channels::
45+
46+
@conn.on("irc-001")
47+
def autojoin_channels():
48+
conn.join(["#channel1", "#channel2"])
49+
50+
Maybe you want to connect some event handlers::
51+
52+
@conn.on("join")
53+
def on_join(message, user, channel):
54+
conn.say(channel, "Hi {}! You're connecting from {}.".format(user.nick, user.host))
55+
56+
Once you're done with that, you need to run the event loop::
57+
58+
import asyncio
59+
asyncio.get_event_loop().run_forever()
60+
61+
Your shiny new IRC client should now connect and do what you told it to!
62+
Congratulations!
63+
64+
Using plugins
65+
-------------
66+
Plugins let you do new stuff with your connection. To use them, you import them
67+
before you initially make the connection::
68+
69+
from asyncirc import irc
70+
import asyncirc.plugins.addressed
71+
72+
conn = irc.connect(...)
73+
...
74+
75+
Plugins usually send new signals, so you want to handle those::
76+
77+
@conn.on("addressed")
78+
def on_addressed(message, user, target, text):
79+
# triggers on "bot_nickname: " or similar
80+
bot.say(target, "{}: You said {} to me!".format(user.nick, text))
81+
82+
Fundamental types
83+
=================
84+
85+
There are a few arguments to your handlers that are instances of specific
86+
classes. Here are those:
87+
88+
``user`` is usually an instance of the ``User`` class, which has some important
89+
attributes:
90+
91+
``User.nick`` contains the nickname of the user
92+
93+
``User.user`` contains the ident of the user
94+
95+
``User.host`` contains the host of the user
96+
97+
``User.hostmask`` contains the full hostmask of the user
98+
99+
Events you can handle
100+
=====================
101+
102+
There are a lot of things that can happen on IRC. As such, there are a lot of
103+
signals that asyncirc generates. Here's a list of some useful ones, with event
104+
handler signatures::
105+
106+
@conn.on("private-message")
107+
def on_private_message(message, user, target, text):
108+
...
109+
110+
@conn.on("public-message")
111+
def on_public_message(message, user, target, text):
112+
...
113+
114+
@conn.on("message")
115+
def on_any_message(message, user, target, text):
116+
...
117+
118+
@conn.on("private-notice")
119+
def on_private_notice(message, user, target, text):
120+
...
121+
122+
@conn.on("public-notice")
123+
def on_public_notice(message, user, target, text):
124+
...
125+
126+
@conn.on("notice")
127+
def on_any_notice(message, user, target, text):
128+
...
129+
130+
@conn.on("join")
131+
def on_join(message, user, channel):
132+
...
133+
134+
@conn.on("part")
135+
def on_join(message, user, channel, reason):
136+
# reason defaults to None if there is no reason
137+
...
138+
139+
@conn.on("quit")
140+
def on_quit(message, user, reason):
141+
...
142+
143+
@conn.on("kick")
144+
def on_kick(message, kicker, kickee, channel, reason):
145+
# kicker is a User object
146+
# kickee is just a nickname
147+
...
148+
149+
@conn.on("nick")
150+
def on_nick_change(message, user, new_nick):
151+
...
152+
153+
These signals are actually sent by the ``core`` plugin, so that's pretty neat.
154+
155+
Just what is that ``message`` handler argument, anyway?
156+
-------------------------------------------------------
157+
158+
``message`` is a special argument. It contains the parsed commands from the IRC
159+
server. It has a few useful attributes:
160+
161+
``message.params`` has the arguments of the command
162+
163+
``message.verb`` has the actual IRC verb
164+
165+
``message.sender`` has the hostmask of the sender
166+
167+
``message`` is especially useful when you want to take care of events that don't
168+
already have a signal attached to them. You can hook into the ``irc`` event, or
169+
the ``irc-verb`` event to handle specific verbs. Handlers for that will take a
170+
single argument ``message``.
171+
172+
Plugins
173+
=======
174+
175+
There are a few plugins packaged with asyncirc. These are documented here.
176+
177+
``asyncirc.plugins.nickserv``
178+
-----------------------------
179+
Sends events when authentication to NickServ succeeds or fails. Automatically
180+
tries to regain your nickname when it is not available (usually doesn't work
181+
unless you've authenticated with SASL).
182+
183+
Events::
184+
185+
@conn.on("nickserv-auth-success")
186+
def auth_success(message_text):
187+
# yay! you're authed to nickserv now.
188+
...
189+
190+
@conn.on("nickserv-auth-fail")
191+
def auth_fail(message_text):
192+
# oh no, you had the wrong password!
193+
# try again or exit!
194+
...
195+
196+
``asyncirc.plugins.sasl``
197+
-------------------------
198+
Handles IRCv3 SASL authentication. After importing, there's a single method call
199+
you need to worry about::
200+
201+
asyncirc.plugins.sasl.auth(account_name, password)
202+
203+
And a single event::
204+
205+
@conn.on("sasl-auth-complete")
206+
def sasl_auth_complete(message):
207+
# yay, you've authenticated with SASL.
208+
...
209+
210+
You probably don't even have to worry about the event. This plugin talks to the
211+
core plugin so that registration is delayed until SASL authentication is done.
212+
213+
``asyncirc.plugins.cap``
214+
------------------------
215+
Handles IRCv3 capability negotiation. There's only one method you need to call
216+
to request a capability once you've imported this plugin::
217+
218+
asyncirc.plugins.cap.request_capability("extended-join") # or whatever
219+
220+
The ``caps-acknowledged`` event will be fired when the server has acknowledged
221+
our request for capabilities. As soon as we know what set of capabilities the
222+
server supports, the ``caps-known`` event is fired.
223+
224+
``asyncirc.plugins.tracking``
225+
-----------------------------
226+
Full state tracking. Some methods::
227+
228+
user = asyncirc.plugins.tracking.get_user(hostmask_or_nick)
229+
chan = asyncirc.plugins.tracking.get_channel(channel_name)
230+
231+
Based on that, here's some stuff you can do::
232+
233+
chan.users # a list of nicknames in the channel
234+
user.channels # a list of channels that the user is in
235+
user.account # the user's services account name. works best if you've
236+
# requested the extended-join and account-notify capabilities
237+
chan.mode # return the channel's mode string
238+
user.previous_nicks # return the user's previous nicknames that we know of
239+
240+
How it actually works is really complicated. Don't even ask.
241+
242+
``asyncirc.plugins.addressed``
243+
------------------------------
244+
It has an event that fires when someone mentions your bot by name in IRC::
245+
246+
@conn.on("addressed")
247+
def on_me_addressed(message, user, target, text):
248+
# text contains the text without the "your_bot: " part
249+
...
250+
251+
You can also register command characters that can be used instead of your bot's
252+
nickname::
253+
254+
asyncirc.plugins.addressed.register_command_character(";;")
255+
256+
Questions? Issues? Just want to chat?
257+
=====================================
258+
259+
I'm fwilson on freenode, if you have any questions. I hang out in
260+
``#watchtower`` along with the rest of the Watchtower dev team. Feel free to
261+
join us!

0 commit comments

Comments
 (0)