|
2 | 2 | import concurrent.futures |
3 | 3 | import enum |
4 | 4 | import logging |
| 5 | +import warnings |
| 6 | +from functools import partial |
| 7 | + |
| 8 | +import sys |
| 9 | + |
| 10 | +from cloudbot.util.parsers.irc import Message |
5 | 11 |
|
6 | 12 | logger = logging.getLogger("cloudbot") |
7 | 13 |
|
@@ -153,7 +159,7 @@ def prepare(self): |
153 | 159 | # we're running a coroutine hook with a db, so initialise an executor pool |
154 | 160 | self.db_executor = concurrent.futures.ThreadPoolExecutor(1) |
155 | 161 | # be sure to initialize the db in the database executor, so it will be accessible in that thread. |
156 | | - self.db = yield from self.async(self.bot.db_session) |
| 162 | + self.db = yield from self.async_call(self.bot.db_session) |
157 | 163 |
|
158 | 164 | def prepare_threaded(self): |
159 | 165 | """ |
@@ -189,7 +195,7 @@ def close(self): |
189 | 195 | if self.db is not None: |
190 | 196 | #logger.debug("Closing database session for {}:threaded=False".format(self.hook.description)) |
191 | 197 | # be sure the close the database in the database executor, as it is only accessable in that one thread |
192 | | - yield from self.async(self.db.close) |
| 198 | + yield from self.async_call(self.db.close) |
193 | 199 | self.db = None |
194 | 200 |
|
195 | 201 | def close_threaded(self): |
@@ -310,17 +316,42 @@ def has_permission(self, permission, notice=True): |
310 | 316 | return self.conn.permissions.has_perm_mask(self.mask, permission, notice=notice) |
311 | 317 |
|
312 | 318 | @asyncio.coroutine |
313 | | - def async(self, function, *args, **kwargs): |
| 319 | + def async_call(self, func, *args, **kwargs): |
314 | 320 | if self.db_executor is not None: |
315 | 321 | executor = self.db_executor |
316 | 322 | else: |
317 | 323 | executor = None |
318 | | - if kwargs: |
319 | | - result = yield from self.loop.run_in_executor(executor, function, *args) |
320 | | - else: |
321 | | - result = yield from self.loop.run_in_executor(executor, lambda: function(*args, **kwargs)) |
| 324 | + |
| 325 | + part = partial(func, *args, **kwargs) |
| 326 | + result = yield from self.loop.run_in_executor(executor, part) |
322 | 327 | return result |
323 | 328 |
|
| 329 | + def is_nick_valid(self, nick): |
| 330 | + """ |
| 331 | + Returns whether a nick is valid for a given connection |
| 332 | + :param nick: The nick to check |
| 333 | + :return: Whether or not it is valid |
| 334 | + """ |
| 335 | + return self.conn.is_nick_valid(nick) |
| 336 | + |
| 337 | + if sys.version_info < (3, 7, 0): |
| 338 | + # noinspection PyCompatibility |
| 339 | + @asyncio.coroutine |
| 340 | + def async_(self, function, *args, **kwargs): |
| 341 | + warnings.warn( |
| 342 | + "event.async() is deprecated, use event.async_call() instead.", |
| 343 | + DeprecationWarning, stacklevel=2 |
| 344 | + ) |
| 345 | + result = yield from self.async_call(function, *args, **kwargs) |
| 346 | + return result |
| 347 | + |
| 348 | + |
| 349 | +# Silence deprecation warnings about use of the 'async' name as a function |
| 350 | +try: |
| 351 | + setattr(Event, 'async', getattr(Event, 'async_')) |
| 352 | +except AttributeError: |
| 353 | + pass |
| 354 | + |
324 | 355 |
|
325 | 356 | class CommandEvent(Event): |
326 | 357 | """ |
@@ -390,3 +421,43 @@ def __init__(self, *args, cap, cap_param=None, **kwargs): |
390 | 421 | super().__init__(*args, **kwargs) |
391 | 422 | self.cap = cap |
392 | 423 | self.cap_param = cap_param |
| 424 | + |
| 425 | + |
| 426 | +class IrcOutEvent(Event): |
| 427 | + def __init__(self, *args, **kwargs): |
| 428 | + super().__init__(*args, **kwargs) |
| 429 | + self.parsed_line = None |
| 430 | + |
| 431 | + @asyncio.coroutine |
| 432 | + def prepare(self): |
| 433 | + yield from super().prepare() |
| 434 | + |
| 435 | + if "parsed_line" in self.hook.required_args: |
| 436 | + try: |
| 437 | + self.parsed_line = Message.parse(self.line) |
| 438 | + except Exception: |
| 439 | + logger.exception("Unable to parse line requested by hook %s", self.hook) |
| 440 | + self.parsed_line = None |
| 441 | + |
| 442 | + def prepare_threaded(self): |
| 443 | + super().prepare_threaded() |
| 444 | + |
| 445 | + if "parsed_line" in self.hook.required_args: |
| 446 | + try: |
| 447 | + self.parsed_line = Message.parse(self.line) |
| 448 | + except Exception: |
| 449 | + logger.exception("Unable to parse line requested by hook %s", self.hook) |
| 450 | + self.parsed_line = None |
| 451 | + |
| 452 | + @property |
| 453 | + def line(self): |
| 454 | + return str(self.irc_raw) |
| 455 | + |
| 456 | + |
| 457 | +class PostHookEvent(Event): |
| 458 | + def __init__(self, *args, launched_hook=None, launched_event=None, result=None, error=None, **kwargs): |
| 459 | + super().__init__(*args, **kwargs) |
| 460 | + self.launched_hook = launched_hook |
| 461 | + self.launched_event = launched_event |
| 462 | + self.result = result |
| 463 | + self.error = error |
0 commit comments