Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
abra3607 committed Oct 26, 2015
1 parent 1bfbfff commit 6813b5b
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
3 changes: 3 additions & 0 deletions cloudbot/clients/irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class IrcClient(Client):
:type port: int
:type _connected: bool
:type _ignore_cert_errors: bool
:type capabilities: set[str]
"""

def __init__(self, bot, name, nick, *, channels=None, config=None,
Expand Down Expand Up @@ -93,6 +94,8 @@ def __init__(self, bot, name, nick, *, channels=None, config=None,
self._transport = None
self._protocol = None

self.capabilities = set(self.config.get('capabilities', []))

def describe_server(self):
if self.use_ssl:
return "+{}:{}".format(self.server, self.port)
Expand Down
7 changes: 6 additions & 1 deletion config.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@
}
},
"plugins": {},
"command_prefix": "."
"command_prefix": ".",
"capabilities": [
"multi-prefix",
"extended-join",
"account-notify"
]
}
],
"api_keys": {
Expand Down
82 changes: 82 additions & 0 deletions plugins/cap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import asyncio
from cloudbot import hook
from cloudbot.bot import CloudBot
from cloudbot.clients.irc import IrcClient
from cloudbot.event import Event


@asyncio.coroutine
@hook.irc_raw('004')
def on_connect(bot, conn):
"""
:type bot: CloudBot
:type conn: IrcClient
"""

if not conn.capabilities:
return

while not conn.ready:
yield from asyncio.sleep(3)

m = conn.memory
if 'CAP_lock' not in m:
m['CAP_lock'] = asyncio.Lock()

with (yield from m['CAP_lock']):
m['CAP_LS_future'] = asyncio.Future()
conn.send('CAP LS')
server_accepts = yield from m['CAP_LS_future']

m['CAP_LIST_future'] = asyncio.Future()
conn.send('CAP LIST')
we_have = yield from m['CAP_LIST_future']

we_want = conn.capabilities

rejected = we_want - we_have - server_accepts
if rejected:
bot.logger.warning('[{}|CAP] Server rejected: {}'.format(conn.name, rejected))

missing = (we_want - we_have) & server_accepts
conn.send('CAP REQ :{}'.format(' '.join(missing)))

m['CAP_ACK_future'] = asyncio.Future()
accepted = yield from m['CAP_ACK_future']
if accepted is None:
bot.logger.warning('[{}|CAP] Failed to negotiate with the server')

if accepted:
bot.logger.info('[{}|CAP] Successfully negotiated for: {}'.format(conn.name, accepted))

conn.send('CAP END')


@asyncio.coroutine
@hook.irc_raw('CAP')
def on_cap(conn, event):
"""
:type conn: Client | IrcClient
:type event: Event
"""

type = event.irc_paramlist[1].upper()
if type == 'LS':
caps = set(event.irc_paramlist[2][1:].split())
future = conn.memory.get('CAP_LS_future')
if future and not future.done():
future.set_result(caps)
elif type == 'LIST':
caps = set(event.irc_paramlist[2][1:].split())
future = conn.memory.get('CAP_LIST_future')
if future and not future.done():
future.set_result(caps)
elif type == 'ACK':
caps = set(event.irc_paramlist[2][1:].split())
future = conn.memory.get('CAP_ACK_future')
if future and not future.done():
future.set_result(caps)
elif type == 'NAK':
future = conn.memory.get('CAP_ACK_future')
if future and not future.done():
future.set_result(None)

0 comments on commit 6813b5b

Please sign in to comment.