Skip to content

Commit

Permalink
fix odd merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardslabs committed Jan 5, 2018
2 parents 640429f + 931caf7 commit 4c68e10
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 84 deletions.
9 changes: 7 additions & 2 deletions cloudbot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from watchdog.observers import Observer

from cloudbot.client import Client, CLIENTS
from cloudbot.clients.irc import IrcClient, irc_clean
from cloudbot.clients.irc import irc_clean
from cloudbot.config import Config
from cloudbot.event import Event, CommandEvent, RegexEvent, EventType
from cloudbot.hook import Action
Expand Down Expand Up @@ -277,6 +277,8 @@ def add_hook(hook, _event, _run_before=False):
# The hook has an action of Action.HALT* so stop adding new tasks
break

matched_command = False

if event.type is EventType.message:
# Commands
if event.chan.lower() == event.nick.lower(): # private message, no command prefix
Expand All @@ -297,12 +299,14 @@ def add_hook(hook, _event, _run_before=False):
command_event = CommandEvent(hook=command_hook, text=text,
triggered_command=command, base_event=event)
add_hook(command_hook, command_event)
matched_command = True
else:
potential_matches = []
for potential_match, plugin in self.plugin_manager.commands.items():
if potential_match.startswith(command):
potential_matches.append((potential_match, plugin))
if potential_matches:
matched_command = True
if len(potential_matches) == 1:
command_hook = potential_matches[0][1]
command_event = CommandEvent(hook=command_hook, text=text,
Expand All @@ -312,10 +316,11 @@ def add_hook(hook, _event, _run_before=False):
event.notice("Possible matches: {}".format(
formatting.get_text_list([command for command, plugin in potential_matches])))

if event.type in (EventType.message, EventType.action):
# Regex hooks
regex_matched = False
for regex, regex_hook in self.plugin_manager.regex_hooks:
if not regex_hook.run_on_cmd and cmd_match:
if not regex_hook.run_on_cmd and matched_command:
continue

if regex_hook.only_no_match and regex_matched:
Expand Down
2 changes: 1 addition & 1 deletion config.default.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
},
"logging": {
"console_debug": false,
"file_debug": true,
"file_debug": false,
"show_plugin_loading": true,
"show_motd": true,
"show_server_info": true,
Expand Down
4 changes: 2 additions & 2 deletions plugins/cryptocurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def get_request(ticker, currency):


def alias_wrapper(alias):
def func(text):
return crypto_command(" ".join((alias.name, text)))
def func(text, reply):
return crypto_command(" ".join((alias.name, text)), reply)

func.__doc__ = """- Returns the current {} value""".format(alias.name)
func.__name__ = alias.name + "_alias"
Expand Down
3 changes: 1 addition & 2 deletions plugins/duckhunt.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from time import time

from sqlalchemy import Table, Column, String, Integer, PrimaryKeyConstraint, desc, Boolean
from sqlalchemy.exc import DatabaseError
from sqlalchemy.sql import select

from cloudbot import hook
Expand Down Expand Up @@ -108,7 +107,7 @@ def save_status(db):
if not res.rowcount:
db.execute(status_table.insert().values(network=network, chan=chan, active=active, duck_kick=duck_kick))

db.commit()
db.commit()


@hook.event([EventType.message, EventType.action], singlethread=True)
Expand Down
31 changes: 17 additions & 14 deletions plugins/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import time
from collections import deque

from sqlalchemy import Table, Column, String, PrimaryKeyConstraint, Float
from sqlalchemy import Table, Column, String, PrimaryKeyConstraint, Float, select

from cloudbot import hook
from cloudbot.event import EventType
Expand All @@ -27,11 +27,19 @@ def track_seen(event, db):
:type db: sqlalchemy.orm.Session
"""
# keep private messages private
now = time.time()
if event.chan[:1] == "#" and not re.findall('^s/.*/.*/$', event.content.lower()):
db.execute(
"insert or replace into seen_user(name, time, quote, chan, host) values(:name,:time,:quote,:chan,:host)",
{'name': event.nick.lower(), 'time': time.time(), 'quote': event.content, 'chan': event.chan,
'host': event.mask})
res = db.execute(
table.update().values(time=now, quote=event.content, host=str(event.mask))
.where(table.c.name == event.nick.lower()).where(table.c.chan == event.chan)
)
if res.rowcount == 0:
db.execute(
table.insert().values(
name=event.nick.lower(), time=now, quote=event.content, chan=event.chan, host=str(event.mask)
)
)

db.commit()


Expand Down Expand Up @@ -98,18 +106,13 @@ def seen(text, nick, chan, db, event, is_nick_valid):
if not is_nick_valid(text):
return "I can't look up that name, its impossible to use!"

if '_' in text:
text = text.replace("_", "/_")

last_seen = db.execute("SELECT name, time, quote FROM seen_user WHERE name LIKE :name ESCAPE '/' AND chan = :chan",
{'name': text, 'chan': chan}).fetchone()

text = text.replace("/", "")
last_seen = db.execute(
select([table.c.name, table.c.time, table.c.quote])
.where(table.c.name == text.lower()).where(table.c.chan == chan)
).fetchone()

if last_seen:
reltime = timeformat.time_since(last_seen[1])
if last_seen[0] != text.lower(): # for glob matching
text = last_seen[0]
if last_seen[2][0:1] == "\x01":
return '{} was last seen {} ago: * {} {}'.format(text, reltime, text, last_seen[2][8:-1])
else:
Expand Down
119 changes: 119 additions & 0 deletions plugins/hook_stats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
"""
Tracks successful and errored launches of all hooks, allowing users to query the stats
Author:
- linuxdaemon <https://github.com/linuxdaemon>
"""

from collections import defaultdict

from cloudbot import hook
from cloudbot.hook import Priority
from cloudbot.util import web
from cloudbot.util.formatting import gen_markdown_table


def default_hook_counter():
return {'success': 0, 'failure': 0}


def hook_sorter(n):
def _sorter(data):
return sum(data[n].values())

return _sorter


def get_stats(bot):
try:
stats = bot.memory["hook_stats"]
except LookupError:
bot.memory["hook_stats"] = stats = {
'global': defaultdict(default_hook_counter),
'network': defaultdict(lambda: defaultdict(default_hook_counter)),
'channel': defaultdict(lambda: defaultdict(lambda: defaultdict(default_hook_counter))),
}

return stats


@hook.post_hook(priority=Priority.HIGHEST)
def stats_sieve(launched_event, error, bot, launched_hook):
chan = launched_event.chan
conn = launched_event.conn
status = 'success' if error is None else 'failure'
stats = get_stats(bot)
name = launched_hook.plugin.title + '.' + launched_hook.function_name
stats['global'][name][status] += 1
if conn:
stats['network'][conn.name.casefold()][name][status] += 1

if chan:
stats['channel'][conn.name.casefold()][chan.casefold()][name][status] += 1


def do_basic_stats(data):
table = [
(hook_name, str(count['success']), str(count['failure']))
for hook_name, count in sorted(data.items(), key=hook_sorter(1), reverse=True)
]
return ("Hook", "Uses - Success", "Uses - Errored"), table


def do_global_stats(data):
return do_basic_stats(data['global'])


def do_network_stats(data, network):
return do_basic_stats(data['network'][network.casefold()])


def do_channel_stats(data, network, channel):
return do_basic_stats(data['channel'][network.casefold()][channel.casefold()])


def do_hook_stats(data, hook_name):
table = [
(net, chan, hooks[hook_name]) for net, chans in data['network'].items() for chan, hooks in chans.items()
]
return ("Network", "Channel", "Uses - Success", "Uses - Errored"), \
[
(net, chan, str(count['success']), str(count['failure']))
for net, chan, count in sorted(table, key=hook_sorter(2), reverse=True)
]


stats_funcs = {
'global': (do_global_stats, 0),
'network': (do_network_stats, 1),
'channel': (do_channel_stats, 2),
'hook': (do_hook_stats, 1),
}


@hook.command(permissions=["snoonetstaff", "botcontrol"])
def hookstats(text, bot, notice_doc):
"""{global|network <name>|channel <network> <channel>|hook <hook>} - Get hook usage statistics"""
args = text.split()
stats_type = args.pop(0).lower()

data = get_stats(bot)

try:
handler, arg_count = stats_funcs[stats_type]
except LookupError:
notice_doc()
return

if len(args) < arg_count:
notice_doc()
return

headers, data = handler(data, *args[:arg_count])

if not data:
return "No stats available."

table = gen_markdown_table(headers, data)

return web.paste(table, 'md', 'hastebin')
28 changes: 21 additions & 7 deletions plugins/horoscope.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import requests
from bs4 import BeautifulSoup
from sqlalchemy import Table, String, Column
from sqlalchemy import Table, String, Column, select

from cloudbot import hook
from cloudbot.util import database
Expand All @@ -15,6 +15,22 @@
)


def get_sign(db, nick):
row = db.execute(select([table.c.sign]).where(table.c.nick == nick.lower())).fetchone()
if not row:
return None

return row[0]


def set_sign(db, nick, sign):
res = db.execute(table.update().values(sign=sign.lower()).where(table.c.nick == nick.lower()))
if res.rowcount == 0:
db.execute(table.insert().values(nick=nick.lower(), sign=sign.lower()))

db.commit()


@hook.command(autohelp=False)
def horoscope(text, db, bot, nick, notice, notice_doc, reply, message):
"""[sign] - get your horoscope"""
Expand Down Expand Up @@ -43,11 +59,11 @@ def horoscope(text, db, bot, nick, notice, notice_doc, reply, message):
sign = text.strip().lower()

if not sign:
sign = db.execute("SELECT sign FROM horoscope WHERE "
"nick=lower(:nick)", {'nick': nick}).fetchone()
sign = get_sign(db, nick)
if not sign:
notice_doc()
return

sign = sign[0].strip().lower()

if sign not in signs:
Expand All @@ -70,11 +86,9 @@ def horoscope(text, db, bot, nick, notice, notice_doc, reply, message):
soup = BeautifulSoup(request.text)

horoscope_text = soup.find("div", class_="horoscope-content").find("p").text
result = "\x02{}\x02 {}".format(text, horoscope_text)
result = "\x02{}\x02 {}".format(sign, horoscope_text)

if text and not dontsave:
db.execute("insert or replace into horoscope(nick, sign) values (:nick, :sign)",
{'nick': nick.lower(), 'sign': sign})
db.commit()
set_sign(db, nick, sign)

message(result)
Loading

0 comments on commit 4c68e10

Please sign in to comment.