Example #1
0
'''
8ball: provide answers from the void beyond.
'''
import os.path
import random
import fortune
from tombot.registry import Command, get_easy_logger, Subscribe, BOT_START

LOGGER = get_easy_logger('plugins.fortune')
FORTUNE_FILES = []
SPECIALS = {}


@Command('fortune', 'fortune')
def fortune_cb(bot, *args, **kwargs):
    '''
    Return a random quote from one of the quote files.
    '''
    try:
        source = random.choice(FORTUNE_FILES)
        return fortune.get_random_fortune(source)
    except ValueError as ex:
        LOGGER.error('Fortune failed: %s', ex)
        return _('Be the quote you want to see on a wall.\n -- Error 20XX')


@Subscribe(BOT_START)
@Command('loadfortunes', 'fortune', hidden=True)
def load_fortunes_cb(bot, message=None, *args, **kwargs):
    '''
    (Re)load all fortune and specials files from their directories.
Example #2
0
'''
ABAS: Automated Birthday Announcement System
'''
from apscheduler.jobstores.base import JobLookupError
from tombot.registry import get_easy_logger, Subscribe, BOT_START, BOT_SHUTDOWN
from tombot.rpc import remote_send

LOGGER = get_easy_logger('plugins.abas')


def announce_bday(name, recipient):
    ''' Send a congratulation for name to recipient. '''
    LOGGER.info('Congratulating %s', name)
    body = 'Gefeliciteerd, {}!'.format(name)
    remote_send(body, recipient)


@Subscribe(BOT_START)
def abas_register_cb(bot, *args, **kwargs):
    ''' Add jobs to the scheduler for all birthdays. '''
    LOGGER.info('Registering ABAs.')
    try:
        bot.cursor.execute(
            'SELECT primary_nick,bday FROM users WHERE bday IS NOT NULL')
    except TypeError:
        LOGGER.error('Invalid date found, fix your database!')
        return
    results = bot.cursor.fetchall()
    for person in results:
        LOGGER.info('Scheduling ABA for %s', person[0])
        bot.scheduler.add_job(announce_bday,
Provides a command for scheduling reminders.

Never forget.
'''
import datetime

import dateutil.parser
from yowsup.layers.protocol_messages.protocolentities \
        import TextMessageProtocolEntity

from tombot.registry import Command, get_easy_logger
from tombot.helper_functions import extract_query, determine_sender, reply_directly
import tombot.datefinder as datefinder
import tombot.rpc as rpc

LOGGER = get_easy_logger('plugins.reminder')

@Command(['remind', 'remindme'])
@reply_directly
def addreminder_cb(bot, message, *args, **kwargs):
    ''' (Hopefully) sends user a message at the given time '''
    body = extract_query(message)
    timespec = body.split()[0]
    try:
        trytime = dateutil.parser.parse(body, parserinfo=datefinder.BPI, fuzzy=True)
    except ValueError:
        trytime = datetime.datetime(1970, 1, 1) # job is dropped if no other date is found
    delta = None
    if timespec in datefinder.DURATION_MARKERS or datefinder.STRICT_CLOCK_REGEX.match(timespec):
        try:
            delta = datetime.datetime.now() + datefinder.find_timedelta(body)
Example #4
0
Provides a command for scheduling reminders.

Never forget.
'''
import datetime

import dateutil.parser
from yowsup.layers.protocol_messages.protocolentities \
        import TextMessageProtocolEntity

from tombot.registry import Command, get_easy_logger
from tombot.helper_functions import extract_query, determine_sender, reply_directly
import tombot.datefinder as datefinder
import tombot.rpc as rpc

LOGGER = get_easy_logger('plugins.reminder')


@Command(['remind', 'remindme'])
@reply_directly
def addreminder_cb(bot, message, *args, **kwargs):
    ''' (Hopefully) sends user a message at the given time '''
    body = extract_query(message)
    timespec = body.split()[0]
    try:
        trytime = dateutil.parser.parse(body,
                                        parserinfo=datefinder.BPI,
                                        fuzzy=True)
    except ValueError:
        trytime = datetime.datetime(
            1970, 1, 1)  # job is dropped if no other date is found
'''
Provides the cookie command, which originally was a test for unicode and now
spouts cookie quotes.
'''
import fortune
from tombot.registry import Command, get_easy_logger
from .fortune_plugin import SPECIALS


LOGGER = get_easy_logger('plugins.cookie')

@Command(['cookie', 'koekje', '\xf0\x9f\x8d\xaa'], 'fortune')
def cookie_cb(bot, *args, **kwargs):
    '''
    Return a cookie-related quote.
    '''
    try:
        return fortune.get_random_fortune(SPECIALS['cookie.spc'])
    except KeyError:
        LOGGER.error('Specials file was not loaded!')
        return 'Error!\xf0\x9f\x8d\xaa'
Example #6
0
'''
Provides the cookie command, which originally was a test for unicode and now
spouts cookie quotes.
'''
import fortune
from tombot.registry import Command, get_easy_logger
from .fortune_plugin import SPECIALS

LOGGER = get_easy_logger('plugins.cookie')


@Command(['cookie', 'koekje', '\xf0\x9f\x8d\xaa'], 'fortune')
def cookie_cb(bot, *args, **kwargs):
    '''
    Return a cookie-related quote.
    '''
    try:
        return fortune.get_random_fortune(SPECIALS['cookie.spc'])
    except KeyError:
        LOGGER.error('Specials file was not loaded!')
        return 'Error!\xf0\x9f\x8d\xaa'
'''
Provides command for answering queries using the DuckDuckGo API.
'''
import duckduckgo
from tombot.registry import Command, get_easy_logger
from tombot.helper_functions import extract_query


LOGGER = get_easy_logger('plugins.duckduckgo')

@Command(['duckduckgo', 'ddg', 'define'], 'info')
def duckduckgo_cb(bot, message, *args, **kwargs):
    '''
    Answer query using DuckDuckGo.
    '''
    try:
        query = extract_query(message)
        return duckduckgo.get_zci(query)
    except ValueError:
        return 'Sorry, no results.'
    except AttributeError:
        return 'Sorry, no results.'
Example #8
0
'''
Provides commands to globally modify the bot's behaviour.
'''
import logging
import pydoc
from .users_plugin import isadmin
from tombot.registry import get_easy_logger, Command, Subscribe, BOT_START
from tombot.registry import COMMAND_DICT, COMMAND_CATEGORIES
from tombot.helper_functions import determine_sender, extract_query, reply_directly

LOGGER = get_easy_logger('plugins.system')
HELP_OVERVIEW = ''


@Command('ping', 'system')
def ping_cb(bot=None, message=None, *args, **kwargs):
    ''' Return 'pong' to indicate non-deadness. '''
    return 'Pong'


@Command('forcelog', 'system', hidden=True)
def forcelog_cb(bot, message, *args, **kwargs):
    ''' Write a message to the root logger. '''
    logging.info('Forcelog from %s: %s', message.getFrom(), message.getBody())
    return


@Command(['shutdown', 'halt'], 'system')
def shutdown_cb(bot, message, *args, **kwargs):
    ''' Shut down the bot. '''
    LOGGER.info('Stop message received from %s, content "%s"',
'''
Provides a command for answering queries using the WolframAlpha API.
'''
import os
import urllib

import wolframalpha

from tombot.helper_functions import extract_query
from tombot.registry import Command, get_easy_logger, Subscribe, BOT_START
from yowsup.layers.protocol_chatstate.protocolentities \
    import OutgoingChatstateProtocolEntity, ChatstateProtocolEntity


LOGGER = get_easy_logger('plugins.wolframalpha')
CLIENT = None

@Command(['calc', 'calculate', 'bereken'])
def wolfram_cb(bot, message, *args, **kwargs):
    '''
    (Attempt to) answer query using the WolframAlpha API.

    Results may not be interpreted as you'd expect, open link for explanation.
    '''
    if not CLIENT:
        return _('Not connected to WolframAlpha!')
    query = extract_query(message)
    LOGGER.debug('Query to WolframAlpha: %s', query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_TYPING, message.getFrom())
    bot.toLower(entity)
Example #10
0
'''
Provides user and nickname management.
'''
import datetime
import sqlite3
import operator
from tombot.helper_functions import determine_sender, extract_query, reply_directly
from tombot.registry import Command, get_easy_logger


LOGGER = get_easy_logger('plugins.users')
IS_ID = operator.methodcaller('isdigit')

# User
@Command(['mynicks', 'lsnicks'], 'users')
@reply_directly
def list_own_nicks_cb(bot, message, *args, **kwargs):
    '''
    List all your nicks and their id's.

    Nicks can be added using addnick, removed using rmnick.
    '''
    sender = determine_sender(message)
    bot.cursor.execute('SELECT id,primary_nick FROM users WHERE jid = ?',
                       (sender,))
    result = bot.cursor.fetchone()
    if result is None:
        return 'Wie ben jij'
    userid = result[0]
    username = result[1]
    bot.cursor.execute('SELECT id,name FROM nicks WHERE jid = ?',
Example #11
0
'''
Provides user and nickname management.
'''
import datetime
import sqlite3
import operator
from tombot.helper_functions import determine_sender, extract_query, reply_directly
from tombot.registry import Command, get_easy_logger

LOGGER = get_easy_logger('plugins.users')
IS_ID = operator.methodcaller('isdigit')


# User
@Command(['mynicks', 'lsnicks'], 'users')
@reply_directly
def list_own_nicks_cb(bot, message, *args, **kwargs):
    '''
    List all your nicks and their id's.

    Nicks can be added using addnick, removed using rmnick.
    '''
    sender = determine_sender(message)
    bot.cursor.execute('SELECT id,primary_nick FROM users WHERE jid = ?',
                       (sender, ))
    result = bot.cursor.fetchone()
    if result is None:
        return 'Wie ben jij'
    userid = result[0]
    username = result[1]
    bot.cursor.execute('SELECT id,name FROM nicks WHERE jid = ?', (sender, ))
'''
8ball: provide answers from the void beyond.
'''
import os.path
import random
import fortune
from tombot.registry import Command, get_easy_logger, Subscribe, BOT_START


LOGGER = get_easy_logger('plugins.fortune')
FORTUNE_FILES = []
SPECIALS = {}

@Command('fortune', 'fortune')
def fortune_cb(bot, *args, **kwargs):
    '''
    Return a random quote from one of the quote files.
    '''
    try:
        source = random.choice(FORTUNE_FILES)
        return fortune.get_random_fortune(source)
    except ValueError as ex:
        LOGGER.error('Fortune failed: %s', ex)
        return _('Be the quote you want to see on a wall.\n -- Error 20XX')

@Subscribe(BOT_START)
@Command('loadfortunes', 'fortune', hidden=True)
def load_fortunes_cb(bot, message=None, *args, **kwargs):
    '''
    (Re)load all fortune and specials files from their directories.
    '''
'''
Provides commands to globally modify the bot's behaviour.
'''
import logging
import pydoc
from .users_plugin import isadmin
from tombot.registry import get_easy_logger, Command, Subscribe, BOT_START
from tombot.registry import COMMAND_DICT, COMMAND_CATEGORIES
from tombot.helper_functions import determine_sender, extract_query, reply_directly


LOGGER = get_easy_logger('plugins.system')
HELP_OVERVIEW = ''

@Command('ping', 'system')
def ping_cb(bot=None, message=None, *args, **kwargs):
    ''' Return 'pong' to indicate non-deadness. '''
    return 'Pong'

@Command('forcelog', 'system', hidden=True)
def forcelog_cb(bot, message, *args, **kwargs):
    ''' Write a message to the root logger. '''
    logging.info('Forcelog from %s: %s', message.getFrom(), message.getBody())
    return

@Command(['shutdown', 'halt'], 'system')
def shutdown_cb(bot, message, *args, **kwargs):
    ''' Shut down the bot. '''
    LOGGER.info('Stop message received from %s, content "%s"',
                message.getFrom(), message.getBody())
    if not isadmin(bot, message):
Example #14
0
'''
Provides a command for answering queries using the WolframAlpha API.
'''
import os
import urllib

import wolframalpha

from tombot.helper_functions import extract_query
from tombot.registry import Command, get_easy_logger, Subscribe, BOT_START
from yowsup.layers.protocol_chatstate.protocolentities \
    import OutgoingChatstateProtocolEntity, ChatstateProtocolEntity

LOGGER = get_easy_logger('plugins.wolframalpha')
CLIENT = None


@Command(['calc', 'calculate', 'bereken'])
def wolfram_cb(bot, message, *args, **kwargs):
    '''
    (Attempt to) answer query using the WolframAlpha API.

    Results may not be interpreted as you'd expect, open link for explanation.
    '''
    if not CLIENT:
        return _('Not connected to WolframAlpha!')
    query = extract_query(message)
    LOGGER.debug('Query to WolframAlpha: %s', query)
    entity = OutgoingChatstateProtocolEntity(
        ChatstateProtocolEntity.STATE_TYPING, message.getFrom())
    bot.toLower(entity)
Example #15
0
time is compared to the time of the last seen message of the user. If the
last message is equal to or greather than their timeout, a copy of the
message is CC'd directly to the user.
This is useful for 'productive' chats with many messages.
'''
import re
import datetime
import operator

from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity

from tombot.helper_functions import determine_sender, extract_query
from tombot.registry import Command, Subscribe, get_easy_logger, BOT_MSG_RECEIVE
from .users_plugin import jid_to_nick, nick_to_jid, nick_to_id, isadmin

LOGGER = get_easy_logger('plugins.users.mentions')
MENTION_PATTERN = r'(?<!\w)@\s?([^ .:,]+)[ .:,]?'
MENTION_REGEX = re.compile(MENTION_PATTERN, re.IGNORECASE)


@Subscribe(BOT_MSG_RECEIVE)
def mention_handler_cb(bot, message, *args, **kwargs):
    '''
    Scans message text for @mentions and notifies user if appropriate.
    '''
    mentioned_sent = []
    for nick in MENTION_REGEX.findall(message.getBody()):
        LOGGER.debug('Nick detected: %s', nick)

        # Who sent the message?
        senderjid = determine_sender(message)
last message is equal to or greather than their timeout, a copy of the
message is CC'd directly to the user.
This is useful for 'productive' chats with many messages.
'''
import re
import datetime
import operator

from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity

from tombot.helper_functions import determine_sender, extract_query
from tombot.registry import Command, Subscribe, get_easy_logger, BOT_MSG_RECEIVE
from .users_plugin import jid_to_nick, nick_to_jid, nick_to_id, isadmin


LOGGER = get_easy_logger('plugins.users.mentions')
MENTION_PATTERN = r'(?<!\w)@\s?([^ .:,]+)[ .:,]?'
MENTION_REGEX = re.compile(MENTION_PATTERN, re.IGNORECASE)

@Subscribe(BOT_MSG_RECEIVE)
def mention_handler_cb(bot, message, *args, **kwargs):
    '''
    Scans message text for @mentions and notifies user if appropriate.
    '''
    mentioned_sent = []
    for nick in MENTION_REGEX.findall(message.getBody()):
        LOGGER.debug('Nick detected: %s', nick)

        # Who sent the message?
        senderjid = determine_sender(message)
        LOGGER.debug('Resolving sender %s', senderjid)
Example #17
0
'''
Provides the plugin infrastructure and some helper functions for plugins.
'''
import os.path
import importlib
from tombot.registry import get_easy_logger

LOGGER = get_easy_logger('moduleloader')


def load_plugins():
    '''
    Import all plugins.
    '''
    root = os.path.dirname(__file__)
    LOGGER.info('Loading plugins from %s', root)
    for dummy, dummy, files in os.walk(root):
        for ffile in files:
            if ffile.endswith('_plugin.py'):
                modulename = ffile.strip('.py')
                LOGGER.info('Initializing plugin %s', modulename)
                try:
                    importlib.import_module('.' + modulename, package=__name__)
                    LOGGER.debug('%s loaded.', modulename)
                except (NameError, SyntaxError) as ex:
                    LOGGER.error('Module %s cannot be loaded!', modulename)
                    LOGGER.error(ex)
Example #18
0
'''
from __future__ import print_function
from collections import namedtuple
import datetime
from datetime import date

from dateutil.relativedelta import relativedelta
import dateutil.rrule
from dateutil.rrule import rrule
from apscheduler.jobstores.base import JobLookupError

import tombot.rpc
from tombot.registry import Command, get_easy_logger, Subscribe, BOT_START, BOT_SHUTDOWN


LOGGER = get_easy_logger('plugins.doekoe')
Rule = namedtuple('rule', 'name rule relocator')

def doekoe_neo(relative_to=datetime.datetime.today()):
    '''
    Bereken wanneer de uitbetalingen in RULES gebeuren.

    Vraag uw specialist en/of gebruik uw ogen om de inhoud van RULES te achterhalen.
    '''
    result = ''

    relative_to.replace(hour=0, minute=0, second=0, microsecond=0)

    LOGGER.debug('relative_to %s', relative_to)
    for item in next_occurrences(relative_to):
        LOGGER.debug('%s %s', item[0], item[1])
Example #19
0
'''
ABAS: Automated Birthday Announcement System
'''
from apscheduler.jobstores.base import JobLookupError
from tombot.registry import get_easy_logger, Subscribe, BOT_START, BOT_SHUTDOWN
from tombot.rpc import remote_send


LOGGER = get_easy_logger('plugins.abas')

def announce_bday(name, recipient):
    ''' Send a congratulation for name to recipient. '''
    LOGGER.info('Congratulating %s', name)
    body = 'Gefeliciteerd, {}!'.format(name)
    remote_send(body, recipient)

@Subscribe(BOT_START)
def abas_register_cb(bot, *args, **kwargs):
    ''' Add jobs to the scheduler for all birthdays. '''
    LOGGER.info('Registering ABAs.')
    try:
        bot.cursor.execute('SELECT primary_nick,bday FROM users WHERE bday IS NOT NULL')
    except TypeError:
        LOGGER.error('Invalid date found, fix your database!')
        return
    results = bot.cursor.fetchall()
    for person in results:
        LOGGER.info('Scheduling ABA for %s', person[0])
        bot.scheduler.add_job(
            announce_bday,
            'cron', month=person[1].month, day=person[1].day,