Browse Source

Removed earwigbot.rules; moved its contents to config.yml

tags/v0.1^2
Ben Kurtovic 12 years ago
parent
commit
65a01c66b5
4 changed files with 39 additions and 93 deletions
  1. +1
    -1
      earwigbot/__init__.py
  2. +5
    -0
      earwigbot/config.py
  3. +33
    -7
      earwigbot/irc/watcher.py
  4. +0
    -85
      earwigbot/rules.py

+ 1
- 1
earwigbot/__init__.py View File

@@ -32,5 +32,5 @@ __version__ = "0.1.dev"
__email__ = "ben.kurtovic@verizon.net" __email__ = "ben.kurtovic@verizon.net"


from earwigbot import ( from earwigbot import (
blowfish, commands, config, irc, main, rules, runner, tasks, tests, wiki
blowfish, commands, config, irc, main, runner, tasks, tests, wiki
) )

+ 5
- 0
earwigbot/config.py View File

@@ -182,6 +182,11 @@ class _BotConfig(object):
@property @property
def log_dir(self): def log_dir(self):
return self._log_dir return self._log_dir
@property
def data(self):
"""The entire config file."""
return self._data


@property @property
def components(self): def components(self):


+ 33
- 7
earwigbot/irc/watcher.py View File

@@ -22,7 +22,6 @@


import logging import logging


from earwigbot import rules
from earwigbot.irc import IRCConnection, RC, BrokenSocketException from earwigbot.irc import IRCConnection, RC, BrokenSocketException
from earwigbot.config import config from earwigbot.config import config


@@ -34,7 +33,7 @@ class Watcher(IRCConnection):


The IRC watcher runs on a wiki recent-changes server and listens for The IRC watcher runs on a wiki recent-changes server and listens for
edits. Users cannot interact with this part of the bot. When an event edits. Users cannot interact with this part of the bot. When an event
occurs, we run it through rules.py's process() function, which can result
occurs, we run it through some rules stored in our config, which can result
in wiki bot tasks being started (located in tasks/) or messages being sent in wiki bot tasks being started (located in tasks/) or messages being sent
to channels on the IRC frontend. to channels on the IRC frontend.
""" """
@@ -46,6 +45,7 @@ class Watcher(IRCConnection):
base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"], base.__init__(cf["host"], cf["port"], cf["nick"], cf["ident"],
cf["realname"], self.logger) cf["realname"], self.logger)
self.frontend = frontend self.frontend = frontend
self._prepare_process_hook()
self._connect() self._connect()


def _process_message(self, line): def _process_message(self, line):
@@ -63,7 +63,7 @@ class Watcher(IRCConnection):
msg = " ".join(line[3:])[1:] msg = " ".join(line[3:])[1:]
rc = RC(msg) # New RC object to store this event's data rc = RC(msg) # New RC object to store this event's data
rc.parse() # Parse a message into pagenames, usernames, etc. rc.parse() # Parse a message into pagenames, usernames, etc.
self._process_rc(rc) # Report to frontend channels or start tasks
self._process_rc_event(rc)


# If we are pinged, pong back: # If we are pinged, pong back:
elif line[0] == "PING": elif line[0] == "PING":
@@ -74,14 +74,40 @@ class Watcher(IRCConnection):
for chan in config.irc["watcher"]["channels"]: for chan in config.irc["watcher"]["channels"]:
self.join(chan) self.join(chan)


def _process_rc(self, rc):
def _prepare_process_hook(self):
"""Create our RC event process hook from information in config.

This will get put in the function self._process_hook, which takes an RC
object and returns a list of frontend channels to report this event to.
"""
# Default RC process hook does nothing:
self._process_hook = lambda rc: ()
try:
rules = config.data["rules"]
except KeyError:
return
try:
module = compile(rules, config.config_path, "exec")
except Exception:
e = "Could not compile config file's RC event rules"
self.logger.exception(e)
return
try:
self._process_hook = module.process
except AttributeError:
e = "RC event rules compiled correctly, but no process(rc) function was found"
self.logger.error(e)
return

def _process_rc_event(self, rc):
"""Process a recent change event from IRC (or, an RC object). """Process a recent change event from IRC (or, an RC object).


The actual processing is configurable, so we don't have that hard-coded The actual processing is configurable, so we don't have that hard-coded
here. We simply call rules's process() function and expect a list of
channels back, which we report the event data to.
here. We simply call our process hook (self._process_hook), created by
self._prepare_process_hook() from information in the "rules" section of
our config.
""" """
chans = rules.process(rc)
chans = self._process_hook(rc)
if chans and self.frontend: if chans and self.frontend:
pretty = rc.prettify() pretty = rc.prettify()
for chan in chans: for chan in chans:


+ 0
- 85
earwigbot/rules.py View File

@@ -1,85 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009-2012 by Ben Kurtovic <ben.kurtovic@verizon.net>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
EarwigBot's IRC Watcher Rules

This file contains (configurable!) rules that EarwigBot's watcher uses after it
recieves an event from IRC.
"""

import re

from earwigbot.tasks import task_manager

afc_prefix = "wikipedia( talk)?:(wikiproject )?articles for creation"

# compile some regexps used when finding specific events
r_page = re.compile(afc_prefix)
r_ffu = re.compile("wikipedia( talk)?:files for upload")
r_move1 = re.compile("moved \[\[{}".format(afc_prefix))
r_move2 = re.compile("moved \[\[(.*?)\]\] to \[\[{}".format(afc_prefix))
r_moved_pages = re.compile("^moved \[\[(.*?)\]\] to \[\[(.*?)\]\]")
r_delete = re.compile("deleted \"\[\[{}".format(afc_prefix))
r_deleted_page = re.compile("^deleted \"\[\[(.*?)\]\]")
r_restore = re.compile("restored \"\[\[{}".format(afc_prefix))
r_restored_page = re.compile("^restored \"\[\[(.*?)\]\]")
r_protect = re.compile("protected \"\[\[{}".format(afc_prefix))

def process(rc):
"""Given an RC() object, return a list of channels to report this event to.
Also, start any wiki bot tasks within this function if necessary."""
chans = set() # channels to report this message to
page_name = rc.page.lower()
comment = rc.comment.lower()

if "!earwigbot" in rc.msg.lower():
chans.update(("##earwigbot", "#wikipedia-en-afc-feed"))

if r_page.search(page_name):
#task_manager.start("afc_copyvios", page=rc.page)
chans.add("#wikipedia-en-afc-feed")

elif r_ffu.match(page_name):
chans.add("#wikipedia-en-afc-feed")

elif page_name.startswith("template:afc submission"):
chans.add("#wikipedia-en-afc-feed")

elif rc.flags == "move" and (r_move1.match(comment) or
r_move2.match(comment)):
p = r_moved_pages.findall(rc.comment)[0]
chans.add("#wikipedia-en-afc-feed")

elif rc.flags == "delete" and r_delete.match(comment):
p = r_deleted_page.findall(rc.comment)[0]
chans.add("#wikipedia-en-afc-feed")

elif rc.flags == "restore" and r_restore.match(comment):
p = r_restored_page.findall(rc.comment)[0]
#task_manager.start("afc_copyvios", page=p)
chans.add("#wikipedia-en-afc-feed")

elif rc.flags == "protect" and r_protect.match(comment):
chans.add("#wikipedia-en-afc-feed")

return chans

Loading…
Cancel
Save