Welcome to pmxbot documentation!#

For Enterprise

Professional support for pmxbot is available as part of the Tidelift Subscription. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools.

Learn more Request a Demo

class pmxbot.commands.Insult#

Bases: str

A specialized string that has a type.

with_type(type)#
pmxbot.commands.acit(rest)#

Look up an acronym

pmxbot.commands.annoy()#

Annoy everyone with meaningless banter

pmxbot.commands.bitchingisuseless(channel, rest)#

It really is, ya know…

pmxbot.commands.blame(channel, rest, nick)#

Pass the buck!

pmxbot.commands.bless(rest)#

Bless the day!

pmxbot.commands.boo(rest)#

Boo someone

pmxbot.commands.calc(rest)#

Perform a basic calculation

pmxbot.commands.chain(rest, nick)#

Chain some(one|thing) down.

pmxbot.commands.cheer(rest)#

Cheer for something

pmxbot.commands.compliment(rest)#

Generate a random compliment from http://www.madsci.org/cgi-bin/cgiwrap/~lynn/jardin/SCG

pmxbot.commands.curse(rest)#

Curse the day!

pmxbot.commands.dance()#

Do a little dance

pmxbot.commands.deal(nick)#

Deal or No Deal?

pmxbot.commands.define(rest)#

Define a word

pmxbot.commands.demotivate(channel, rest)#

Demotivate someone

pmxbot.commands.disembowel(rest)#

Disembowel some(one|thing)!

pmxbot.commands.duck()#

Display a helpful duck

pmxbot.commands.eball(rest)#

Ask the magic 8ball a question

pmxbot.commands.embowel(rest)#

Embowel some(one|thing)!

pmxbot.commands.emer_comp(rest)#

Return a random compliment from http://emergencycompliment.com/

pmxbot.commands.featurecreep()#

Generate feature creep (P+C http://www.dack.com/web/bullshit.html)

pmxbot.commands.fight(nick, rest)#

Pit two sworn enemies against each other (separate with ‘vs.’)

pmxbot.commands.flip(nick)#

Flip a coin

pmxbot.commands.fml(rest)#

A SFW version of fml.

pmxbot.commands.get_insult()#

Load a random insult from autoinsult.

pmxbot.commands.gettowork(channel, nick, rest)#

You really ought to, ya know…

pmxbot.commands.golfclap(rest)#

Clap for something

pmxbot.commands.google(rest)#

Look up a phrase on google

pmxbot.commands.hire()#

When all else fails, pmxbot delivers the perfect employee.

pmxbot.commands.imotivate(channel, rest)#

Ironically “Motivate” someone

pmxbot.commands.insult(rest)#

Generate a random insult

pmxbot.commands.job()#

Generate a job title, http://www.cubefigures.com/job.html

pmxbot.commands.keelhaul(rest)#

Inflict great pain and embarassment on some(one|thing)

pmxbot.commands.klingon()#

Ask the magic klingon a question

pmxbot.commands.lunch(rest)#

Pick where to go to lunch

pmxbot.commands.meaculpa(nick, rest)#

Sincerely apologize

pmxbot.commands.motivate(channel, rest)#

Motivate someone

pmxbot.commands.murphy(rest)#

Look up one of Murphy’s laws

pmxbot.commands.nailedit(rest)#

Nail that interview

pmxbot.commands.nastygram(nick, rest)#

A random passive-agressive comment, optionally directed toward some(one|thing).

pmxbot.commands.oregontrail(channel, nick, rest)#

It’s edutainment!

pmxbot.commands.panic()#

Panic!

pmxbot.commands.password(rest)#

Generate a random password, similar to http://www.pctools.com/guides/password

pmxbot.commands.pick(rest)#

Pick between a few options

pmxbot.commands.plaintext(html)#

Extract the text from HTML.

pmxbot.commands.progress(rest)#

Display the progress of something: start|end|percent

pmxbot.commands.rand_bot(channel, nick, rest)#
pmxbot.commands.roll(rest, nick)#

Roll a die, default = 100.

pmxbot.commands.rubberstamp(rest)#

Approve something

pmxbot.commands.stab(nick, rest)#

Stab, shank or shiv some(one|thing)!

pmxbot.commands.storytime(rest)#

A story is about to be told.

pmxbot.commands.strategy()#

Social Media Strategy, courtsey of http://whatthefuckismysocialmediastrategy.com/

pmxbot.commands.suppress_exceptions(callables, exceptions=Exception)#

Suppress supplied exceptions (tuple or single exception) encountered when a callable is invoked. >>> five_over_n = lambda n: 5//n >>> import functools >>> callables = (functools.partial(five_over_n, n) for n in range(-3,3)) >>> safe_results = suppress_exceptions(callables, ZeroDivisionError) >>> tuple(safe_results) (-2, -3, -5, 5, 2)

pmxbot.commands.tgif(rest)#

Thanks for the words of wisdow, Mike.

pmxbot.commands.therethere(rest)#

Sympathy for you.

pmxbot.commands.ticker(rest)#

Look up a ticker symbol’s current trading value

pmxbot.commands.timezone(rest)#

Convert date between timezones.

Example: > !tz 11:00am UTC in PDT 11:00 UTC -> 4:00 PDT

UTC is implicit

> !tz 11:00am in PDT 11:00 UTC -> 4:00 PDT

> !tz 11:00am PDT 11:00 PDT -> 18:00 UTC

pmxbot.commands.tinytear(rest)#

I cry a tiny tear for you.

pmxbot.commands.troutslap(rest)#

Slap some(one|thing) with a fish

pmxbot.commands.urbandict(rest)#

Define a word with Urban Dictionary

pmxbot.commands.version(rest)#

Get the version of pmxbot or one of its plugins

pmxbot.commands.yay_sor(rest)#
pmxbot.commands.zinger(rest)#

ZING!

class pmxbot.core.AliasHandler(**kwargs)#

Bases: CommandHandler

class_priority = 2#

priority of this class relative to other classes, precedence to higher

property doc#
class pmxbot.core.AtHandler(*args, **kwargs)#

Bases: Scheduled

as_cmd()#
class pmxbot.core.AugmentableMessage(other, **kwargs)#

Bases: str

A text string which may be augmented with attributes

>>> msg = AugmentableMessage('foo', bar='baz')
>>> msg == 'foo'
True
>>> msg.bar == 'baz'
True
class pmxbot.core.Bot#

Bases: object

The abstract interface for the bot.

allow(channel, message)#

Allow plugins to filter content.

handle_action(channel, nick, msg)#

Core message parser and dispatcher

handle_scheduled(target)#

target is a Handler or simple callable

init_schedule(scheduler)#
out(channel, s, log=True)#
abstract transmit(channel, message)#

Transmit message using channel. If message looks like an action, transmit it as such. Suppress all exceptions (but log warnings for each). Return the message as sent.

class pmxbot.core.CommandHandler(**kwargs)#

Bases: Handler

property alias_names#
aliases = ()#
class_priority = 3#

priority of this class relative to other classes, precedence to higher

decorate(func)#

Decorate a handler function. The handler should accept keyword parameters for values supplied by the bot, a subset of: - client - connection (alias for client) - event - channel - nick - rest

match(message, channel)#

Return True if the message is matched by this handler.

process(message)#
class pmxbot.core.ConfigMergeAction(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)#

Bases: Action

class pmxbot.core.ContainsHandler(**kwargs)#

Bases: Handler

channels = ()#
class_priority = 1#

priority of this class relative to other classes, precedence to higher

doc = None#
exclude = ()#
match(message, channel)#

Return True if the message is matched by this handler.

rate = 1.0#

rate to invoke handler

class pmxbot.core.ContentHandler(**kwargs)#

Bases: ContainsHandler

A custom handler that by default handles all messages.

allow_chain = True#

allow subsequent handlers to also process the same message

class_priority = 5#

priority of this class relative to other classes, precedence to higher

name = ''#
class pmxbot.core.DelayHandler(**kwargs)#

Bases: Scheduled

as_cmd()#
class pmxbot.core.FinalRegistry#

Bases: object

A list of callbacks to run at exit.

classmethod at_exit(finalizer)#
classmethod finalize()#
class pmxbot.core.Handler(**kwargs)#

Bases: object

allow_chain = False#

allow subsequent handlers to also process the same message

attach(params)#

Attach relevant params to func, returning a callable that takes no parameters.

class_priority = 1#

priority of this class relative to other classes, precedence to higher

decorate(func)#

Decorate a handler function. The handler should accept keyword parameters for values supplied by the bot, a subset of: - client - connection (alias for client) - event - channel - nick - rest

classmethod find_matching(message, channel)#

Yield cls subclasses that match message and channel

match(message, channel)#

Return True if the message is matched by this handler.

priority = 1#

priority relative to other handlers of this class, precedence to higher

process(message)#
register()#
property sort_key#
class pmxbot.core.JoinHandler(**kwargs)#

Bases: Handler

class pmxbot.core.LeaveHandler(**kwargs)#

Bases: Handler

Handles quits and parts.

class pmxbot.core.NoLog#

Bases: Sentinel

A sentinel indicating that subsequent items should not be logged.

property properties#
class pmxbot.core.RegexpHandler(*args, **kwargs)#

Bases: ContainsHandler

class_priority = 4#

priority of this class relative to other classes, precedence to higher

match(message, channel)#

Return True if the message is matched by this handler.

process(message)#
class pmxbot.core.Scheduled(**kwargs)#

Bases: Handler

class pmxbot.core.Sentinel#

Bases: object

A base Sentinel object which can be injected into a series of messages to alter the properties of subsequent messages.

classmethod augment_items(items, **defaults)#

Iterate over the items, keeping a adding properties as supplied by Sentinel objects encountered.

>>> from more_itertools.recipes import consume
>>> res = Sentinel.augment_items(['a', 'b', NoLog, 'c'], secret=False)
>>> res = tuple(res)
>>> consume(map(print, res))
a
b
c
>>> [msg.secret for msg in res]
[False, False, True]
>>> msgs = ['a', NoLog, 'b', SwitchChannel('#foo'), 'c']
>>> res = Sentinel.augment_items(msgs, secret=False, channel=None)
>>> res = tuple(res)
>>> consume(map(print, res))
a
b
c
>>> [msg.channel for msg in res] == [None, None, '#foo']
True
>>> [msg.secret for msg in res]
[False, True, True]
>>> res = Sentinel.augment_items(msgs, channel='#default', secret=False)
>>> consume(map(print, [msg.channel for msg in res]))
#default
#default
#foo
class pmxbot.core.SwitchChannel#

Bases: str, Sentinel

A sentinel indicating a new channel for subsequent messages.

property properties#
pmxbot.core.attach(func, params)#

Given a function and a namespace of possible parameters, bind any params matching the signature of the function to that function.

pmxbot.core.command(name=None, aliases=None, doc=None)#
pmxbot.core.contains(name, channels=(), exclude=(), rate=1.0, priority=1, doc=None, **kwargs)#
pmxbot.core.execat(name, channel, when, doc=None)#
pmxbot.core.execdelay(name, channel, howlong, doc=None, repeat=False)#
pmxbot.core.get_args(*args, **kwargs)#
pmxbot.core.init_config(overrides)#

Install the config dict as pmxbot.config, setting overrides, and return the result.

pmxbot.core.initialize(config)#

Initialize the bot with a dictionary of config items

pmxbot.core.on_join(doc=None)#
pmxbot.core.on_leave(doc=None)#
pmxbot.core.regexp(name, regexp, doc=None, **kwargs)#
pmxbot.core.run()#
exception pmxbot.karma.AlreadyLinked#

Bases: ValueError

class pmxbot.karma.Karma#

Bases: SelectableStorage

classmethod finalize()#

Delete the various persistence objects

classmethod initialize()#

Link thing1 and thing2, adding the karma of each into a single entry. If any thing does not exist, it is created.

class pmxbot.karma.MongoDBKarma(host_uri)#

Bases: Karma, MongoDBStorage

change(thing, change)#
collection_name = 'karma'#
import_(item)#
list(select=0)#
lookup(thing)#
repair_duplicate_names()#

Prior to 1101.1.1, pmxbot would incorrectly create new karma records for individuals with multiple names. This routine corrects those records.

search(term)#
set(thing, value)#
class pmxbot.karma.SQLiteKarma(uri)#

Bases: Karma, SQLiteStorage

change(thing, change)#
export_all()#
init_tables()#
list(select=0)#
lookup(thing)#
search(term)#
set(thing, value)#
exception pmxbot.karma.SameName#

Bases: ValueError

pmxbot.karma.bottom10(rest)#

Return the bottom n (default 10) lowest entities by Karmic value. Use negative numbers for the bottom N.

pmxbot.karma.karma(nick, rest)#

Return or change the karma value for some(one|thing)

pmxbot.karma.top10(rest)#

Return the top n (default 10) highest entities by Karmic value. Use negative numbers for the bottom N.

class pmxbot.logging.FullTextMongoDBLogger(host_uri)#

Bases: MongoDBLogger

search(*terms)#
classmethod uri_matches(uri)#

override ‘uri_matches’ to disallow this logger if full text searching is not available.

class pmxbot.logging.LegacyFullTextMongoDBLogger(host_uri)#

Bases: FullTextMongoDBLogger

search(*terms)#
classmethod uri_matches(uri)#

override ‘uri_matches’ to prefer this logger when the server version doesn’t support $text (MongoDB 2.4 only).

class pmxbot.logging.LoggedChannels#

Bases: object

class pmxbot.logging.Logger#

Bases: SelectableStorage

Base Logger class

clear()#

Remove all messages from the database.

classmethod finalize()#

Delete the various persistence objects

classmethod initialize()#
list_channels()#
message(channel, nick, msg)#
class pmxbot.logging.MongoDBLogger(host_uri)#

Bases: Logger, MongoDBStorage

all_messages()#
clear()#

Remove all messages from the database.

collection_name = 'logs'#
static extract_legacy_id(oid)#

Given a special OID which includes the legacy sqlite ID, extract the sqlite ID.

get_channel_days(channel)#
get_day_logs(channel, day)#
get_random_logs(limit)#
import_(message)#
last_message(channel)#
last_seen(nick)#
list_channels()#
search(*terms)#
strike(channel, nick, count)#
class pmxbot.logging.SQLiteLogger(uri)#

Bases: Logger, SQLiteStorage

clear()#

Remove all messages from the database.

export_all()#
get_channel_days(channel)#
get_day_logs(channel, day)#
get_random_logs(limit)#
init_tables()#
last_message(channel)#
last_seen(nick)#
search(*terms)#
strike(channel, nick, count)#
class pmxbot.logging.UnloggedChannels#

Bases: object

pmxbot.logging.log(channel, rest)#

Enable or disable logging for a channel; use ‘please’ to start logging and ‘stop please’ to stop.

pmxbot.logging.log_message(channel, nick, rest)#
pmxbot.logging.logs(channel)#

Where can one find the logs?

pmxbot.logging.parse_date(record)#

Parse a date from sqlite. Assumes the date is in US/Pacific time zone.

pmxbot.logging.strike(channel, nick, rest)#

Strike last <n> statements from the record

pmxbot.logging.where(channel, nick, rest)#

When did pmxbot last see <nick> speak?

class pmxbot.slack.Bot(server, port, nickname, channels, password=None)#

Bases: Bot

handle_message(msg)#
run_scheduler_loop()#
static search_dicts(key, dicts)#

Return the value for the first dict in dicts that has key.

start()#
transmit(channel, message)#

Send the message to Slack.

Parameters:
  • channel – channel, user or email to whom the message should be sent. If a thread attribute is present, that thread ID is used.

  • message (str) – message to send.

pmxbot.slack.iter_cursor(callable, cursor=None)#

Iterate a slack endpoint callable that uses paginated results.

System commands

pmxbot.system.ctlaltdel(rest)#

Quits pmxbot. A supervisor should automatically restart it.

pmxbot.system.help(rest)#

Help (this command)

The pmxbot logo in ascii art. Fixed-width font recommended!

>>> from more_itertools import consume
>>> consume(map(print, logo()))
                                                MI=7+MM .M:
                                             M=..        .M M
...
class pmxbot.storage.MongoDBStorage(host_uri)#

Bases: Storage

scheme = 'mongodb'#
classmethod uri_matches(uri)#
class pmxbot.storage.SQLiteStorage(uri)#

Bases: Storage, _local

close()#
init_tables()#
scheme = 'sqlite'#
classmethod uri_matches(uri)#
class pmxbot.storage.SelectableStorage#

Bases: object

A mix-in for storage classes which will construct a suitable subclass based on the URI.

classmethod finalize()#

Delete the various persistence objects

classmethod from_URI(URI=None)#
classmethod migrate(source_uri, dest_uri)#
classmethod uri_matches(uri)#
class pmxbot.storage.Storage#

Bases: object

close()#
abstract classmethod uri_matches(uri)#
pmxbot.storage.migrate_all(source, dest)#
class pmxbot.notify.MongoDBNotify(host_uri)#

Bases: Notify, MongoDBStorage

collection_name = 'notify'#
lookup(nick)#
notify(fromnick, tonick, message)#
class pmxbot.notify.Notify#

Bases: SelectableStorage

classmethod finalize()#

Delete the various persistence objects

classmethod init()#
class pmxbot.notify.SQLiteNotify(uri)#

Bases: Notify, SQLiteStorage

init_tables()#
lookup(nick)#
notify(fromnick, tonick, message)#
pmxbot.notify.donotify(nick, rest)#

notify <nick> <message>

pmxbot.notify.notifier(client, nick)#

Indices and tables#