Browse Source

Add ascii spamming module

dave/xdcc
dave 5 years ago
parent
commit
cc4e3fee72
  1. 33
      docs/api/modules/ascii.rst
  2. 5
      examples/data/config/ASCII.json
  3. 4950
      examples/data/data/ASCII/bigmatix.txt
  4. 16
      examples/data/data/ASCII/bird1.txt
  5. 4622
      examples/data/data/ASCII/locktronic.txt
  6. 93
      pyircbot/modules/ASCII.py

33
docs/api/modules/ascii.rst

@ -0,0 +1,33 @@
:mod:`ASCII` --- Ascii art database & spammer
=============================================
Prints ascii art to the channel
Setup
-----
Place .txt files in `datadir/ASCII/`. The file names must end in `.txt` and can contain alphanumerics, underscores,
and dashes. They must be UTF-8 decodable but will otherwise be transmitted verbatim.
Commands
--------
.. cmdoption:: .listascii
List available ascii arts.
.. cmdoption:: .ascii <name>
Begin printing the named ascii art
.. cmdoption:: .stopascii
Stop the currently running ascii art
Class Reference
---------------
.. automodule:: pyircbot.modules.ASCII
:members:
:undoc-members:
:show-inheritance:

5
examples/data/config/ASCII.json

@ -0,0 +1,5 @@
{
"line_delay": 1.1,
"allow_parallel": false,
"list_max": 15
}

4950
examples/data/data/ASCII/bigmatix.txt

File diff suppressed because it is too large Load Diff

16
examples/data/data/ASCII/bird1.txt

@ -0,0 +1,16 @@
_
__~a~_
~~; ~_
- -
(-----------------( )----------------)
'/'/'/'|'|'|'|(( ))|'|'|'|'\'\'\'\)
.(/./././, | | | |(/ \) | | | .\.\.\.\)
.(/././././ | | | ^(/ \) ^ | |.\.\.\.\.\)
.(/././././ ^ ^ ^ (/ \) ^ ^ .\.\.\.\.\)
.(/./././ ^ ./ (||)|.\ ^.\.\.\.\)
. ^././ ^ M ./||\. M ^.\.\ ^
.^ ^ ./||\. ^ ^
/./.||.\.\
.//||\\.
.//||\\.
'/||\'

4622
examples/data/data/ASCII/locktronic.txt

File diff suppressed because it is too large Load Diff

93
pyircbot/modules/ASCII.py

@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""
.. module::ASCII
:synopsis: Spam chat with awesome ascii texts
"""
from pyircbot.modulebase import ModuleBase, ModuleHook
from threading import Thread
from glob import iglob
from collections import defaultdict
from time import sleep
import re
import os
RE_ASCII_FNAME = re.compile(r'^[a-zA-Z0-9\-_]+$')
class ASCII(ModuleBase):
def __init__(self, bot, moduleName):
ModuleBase.__init__(self, bot, moduleName)
self.hooks.append(ModuleHook("PRIVMSG", self.listen_msg))
self.running_asciis = defaultdict(lambda: None)
self.killed_channels = defaultdict(lambda: False)
def listen_msg(self, msg):
"""
Handle commands
:param msg: Message object to inspect
"""
# Ignore PMs
if not msg.args[0].startswith("#"):
return
# provide a listing of available asciis
if self.bot.messageHasCommand(".listascii", msg.trailing):
fnames = [os.path.basename(f).split(".", 2)[0] for f in iglob(os.path.join(self.getFilePath(), "*.txt"))]
fnames.sort()
message = "Avalable asciis: {}".format(", ".join(fnames[0:self.config.get("list_max")]))
self.bot.act_PRIVMSG(msg.args[0], message)
if len(fnames) > self.config.get("list_max"):
self.bot.act_PRIVMSG(msg.args[0], "...and {} more".format(len(fnames) - self.config.get("list_max")))
return
# Send out an ascii
cmd = self.bot.messageHasCommand(".ascii", msg.trailing, requireArgs=True)
if self.bot.messageHasCommand(".ascii", msg.trailing):
# Prevent parallel spamming in same channel
if self.running_asciis[msg.args[0]]:
return
# Prevent parallel spamming in different channels
if not self.config.get("allow_parallel") and any(self.running_asciis.values()):
return
ascii_name = cmd.args.pop()
if not RE_ASCII_FNAME.match(ascii_name):
return
ascii_path = self.getFilePath(ascii_name + ".txt")
if os.path.exists(ascii_path):
self.running_asciis[msg.args[0]] = Thread(target=self.print_ascii, args=(ascii_path, msg.args[0]),
daemon=True)
self.running_asciis[msg.args[0]].start()
return
# stop running asciis
if self.bot.messageHasCommand(".stopascii", msg.trailing):
if self.running_asciis[msg.args[0]]:
self.killed_channels[msg.args[0]] = True
def print_ascii(self, ascii_path, channel):
"""
Print the contents of ascii_path to channel
:param ascii_path: file path to the ascii art file to read and print
:param channel: channel name to print to
"""
delay = self.config.get("line_delay")
with open(ascii_path, "rb") as f:
content = [i.rstrip() for i in f.read().decode("UTF-8", errors="ignore").split("\n")]
for line in content:
if self.killed_channels[channel]:
break
if not line:
line = " "
self.bot.act_PRIVMSG(channel, line)
if delay:
sleep(delay)
del self.running_asciis[channel]
del self.killed_channels[channel]
Loading…
Cancel
Save