Example #1
0
def process_message(payload):
    print("Message received!")
    if len(payload) == 0:
        print("Unprocessable message. Ignoring.")
        return
    message = payload.get("text")

    if not message:
        # sometimes we'll get an object without text; just discard it.
        print("Unprocessable message. Ignoring.")
        return

    try:
        user_who_sent_message = users_list[payload["user"]]
    except KeyError:
        # This will trigger if an app posts, like the RSS feeds.
        return

    if _is_from_us(user_who_sent_message):
        return

    print(f"I received: {message} from {user_who_sent_message}")

    # search all the loaded plugins to see if any of the regex's match
    plugin = PluginManager.get_plugin(message)
    if plugin:
        plugin(payload)

    else:
        # we don't know what they were trying to do, so we fall through to here.
        # Let's only limit responses to things that look like they're trying
        # to use regular command syntax, though.
        # For example, trigger on "!hello" but not for "isn't bubbles great".
        if PluginManager.has_beginning_command_prefix(message):
            payload['extras']['say'](f"Unknown command: `{message}`")

    # If a command needs to be able to see all traffic for historical reasons,
    # register a separate callback function in a class for the command. See
    # bubbles.commands.yell for an example implementation.
    PluginManager.process_plugin_callbacks(payload)
Example #2
0
def isup(payload):
    say = payload['extras']['say']
    text = payload.get("cleaned_text").split()
    if len(text) == 1:
        say("What service should I be checking on?")
        say("Valid choices: {}".format(", ".join(SERVICES)))
        return

    def _check(name):
        try:
            subprocess.check_call(
                ["systemctl", "is-active", "--quiet",
                 get_service_name(name)])
            say(f"Yep, {name} is up!")
        except subprocess.CalledProcessError:
            say(f"...something might be wrong; {name} doesn't look like it's up."
                )

    service = text[1]

    if service == "all":
        for system in [_ for _ in SERVICES if _ != "all"]:
            _check(system)
    else:
        _check(service)


PluginManager.register_plugin(isup,
                              r"isup([ a-zA-Z]+)?",
                              help="!isup [service_name]")
    hours, minutes = calculate_hours_and_minutes_timedelta_from_diffs(
        *get_time_diffs(ten_post_window))

    posts_per_day_count = get_total_count_of_posts_per_day(all_posts)
    posts_per_last_24h_count = get_total_count_of_posts_in_24_hours(all_posts)

    suggested_value_window = estimate_filter_value(upvote_list_window,
                                                   posts_per_day_count)
    suggested_value_all = estimate_filter_value(upvote_list_all_posts,
                                                posts_per_day_count)

    say(f"Stats for r/{sub} over the last 10 submissions:\n"
        f"\n"
        f"* karma distribution: {min_karma} | {max_karma}\n"
        f"* time spread: {hours}h {minutes}m\n"
        f"\n"
        f"Number of submissions in the last 24h: {posts_per_last_24h_count}\n"
        f"Average new submissions per day: {posts_per_day_count}\n"
        f"\n"
        f"Suggested threshold based on the window: {suggested_value_window}\n"
        f"Suggested threshold from last 1k posts: {suggested_value_all}\n")


PluginManager.register_plugin(
    suggest_filter,
    SUGGEST_FILTER_RE,
    help=
    ("!suggest filter {subreddit} - have me guess at an appropriate filter value"
     " for a given subreddit. Usage: @bubbles suggest filter r/thathappened"),
)
Example #4
0
import os
import subprocess

from bubbles.config import PluginManager


def update(payload) -> None:
    payload['extras']['say']("Preparing update...")
    # print the results so that it shows up in the system logs if something goes wrong
    print(
        subprocess.Popen(
            [
                os.path.join(os.getcwd(), ".venv", "bin", "python"),
                os.path.join(os.getcwd(), "update.py"),
            ],
            text=True,
        ))


PluginManager.register_plugin(
    update, r"update$", help="!update - pull changes from github and restart!")
Example #5
0
    say = payload["extras"]["say"]

    if len(args) > 1:
        if args[0] in COMMAND_PREFIXES:
            args.pop(0)

    if len(args) == 1:
        say("Need a service to deploy to production. Usage: @bubbles deploy [service]"
            " -- example: `@bubbles deploy tor`")
        return

    service = args[1].lower().strip()
    if service not in SERVICES:
        say(f"Received a request to deploy {args[1]}, but I'm not sure what that is.\n\n"
            f"Available options: {', '.join(SERVICES)}")
        return

    if service == "all":
        for system in [_ for _ in SERVICES if _ != "all"]:
            _deploy_service(system, say)
    else:
        _deploy_service(service, say)


PluginManager.register_plugin(
    deploy,
    r"deploy ?(.+)",
    help=
    f"!deploy [{', '.join(SERVICES)}] - deploys the code currently on github to the staging server.",
)
Example #6
0
# note: this command requires setting up sudoers access

COMMAND = "journalctl -u {} -n 50"
VALID = "Valid choices: {}".format(", ".join(SERVICES))


def logs(payload):
    say = payload['extras']['say']
    text = payload['cleaned_text'].split()

    if len(text) == 1:
        say("What service should I return the logs for?")
        say(VALID)
        return

    service = text[1]
    if service == "all":
        say("Sorry, that's a lot of logs. Please specify the service you want."
            )
        say(VALID)
    result = subprocess.check_output(
        COMMAND.format(get_service_name(service)).split())

    for block in break_large_message(result.decode().strip(), break_at=3800):
        say(f"```{block}```")


PluginManager.register_plugin(logs,
                              r"logs([ a-zA-Z]+)?",
                              help="!logs [service_name]")
Example #7
0
            response = idk
        elif payload["channel"] in self.previous_message_dict:
            previous_message = self.previous_message_dict[payload["channel"]]
            response = f"<@{payload['user']}>: {previous_message['text'].upper()}"
        else:
            response = idk

        payload['extras']['say'](response)

    def yell_callback(self, message):
        if message["user"] == ME:
            return
        # back up the last message sent that doesn't match the patterns.
        # Keep a running dict based on the channel it came from.
        if not hasattr(self, "previous_message_dict"):
            self.previous_message_dict = dict()

        if not re.match(compiled_pattern, message["text"]):
            self.previous_message_dict[message["channel"]] = message


instance = Yell()
PluginManager.register_plugin(
    instance.yell,
    raw_pattern,
    flags=re.IGNORECASE | re.MULTILINE | re.VERBOSE,
    callback=instance.yell_callback,
    ignore_prefix=True,
    help="WHAT?!",
)
Example #8
0
from bubbles.config import PluginManager


def ping(payload):
    payload['extras']['say']("PONG!")


PluginManager.register_plugin(ping, r"ping$", help="!ping - PONG")
        # if "user" in message.keys():
        #     userWhoSentMessage = usersList[message["user"]]
        #
        if not re.search(r"^<https://reddit.com/u", message["text"]
                         ):  # Remove all messages who are not given by the bot
            continue
        welcomed_username = message["text"].split(">")[0]
        welcomed_username = welcomed_username.split("|")[-1]
        author = extract_author(message, GOOD_REACTIONS)
        count_reactions_people[author] = count_reactions_people.get(author,
                                                                    0) + 1
        list_volunteers_per_person[author] = list_volunteers_per_person.get(
            author, []) + [welcomed_username]
    count_reactions_people = dict(sorted(count_reactions_people.items()))
    say(f"{str(len(response['messages']))} messages retrieved."
        f" Numerical data: {count_reactions_people}")

    keys_dict = list(sorted(list_volunteers_per_person.keys()))
    for key in keys_dict:
        say(f"Volunteers welcomed by {key}: {list_volunteers_per_person[key]}")


PluginManager.register_plugin(
    plot_comments_historylist,
    r"(?!.*who)listmodsTEST ([0-9 ]+)?",
    help=(
        "!historylist [number of posts] - shows the number of new comments in"
        " #new-volunteers in function of the mod having welcomed them. `number"
        "of posts` must be an integer between 1 and 1000 inclusive."),
)
Example #10
0
            "Conflict",
            "Abandoned",
            "Banned",
    ]:
        if name in count_reactions_people.keys():
            plt.plot(dates,
                     cumsum(flip(posts_hist[:, i])),
                     label=name,
                     color=colours[i])
            i = i + 1
    # plt.bar(posts_hist, maxDay+1, stacked='True')
    plt.xlabel("Day")
    plt.ylabel("Number of new volunteers")
    plt.grid(True, "both")
    plt.legend()
    plt.savefig("plotHourMods.png")
    plt.close()
    client.files_upload(
        channels=payload.get("channel"),
        file="plotHourMods.png",
        title="Just vibing.",
        as_user=True,
    )


PluginManager.register_plugin(
    plot_comments_historywho,
    r"historywho([ \"a-zA-Z]+)?",
    help=HELP_MESSAGE,
)
Example #11
0
import random
import re

from bubbles.config import PluginManager, USERNAME

pattern = r"""f+u+c+k+(\ )?(?:(y+o+u+|u+|o+f+))?[,\ ]+?{}""".format(USERNAME)


def fuck_off(payload):
    responses = [
        "https://i.pinimg.com/564x/7f/de/1a/7fde1a18fd553ec5a1b7c7c3cdeeeda8.jpg",
        "https://i.pinimg.com/originals/d8/72/7a/d8727aafdb389f99e4643e39aaf4ed7b.jpg",
        "https://qph.fs.quoracdn.net/main-qimg-5a89ed1c82a593ef813050046005c970",
        "https://lh3.googleusercontent.com/proxy/qBD1V0_Un3mTzqb-mYuo5radVtHg2SKT5dt4GGuyvScTDMFqdKTWsjLXnUOGNA0pEeoj3sxzeyTgSmzyEdUOeHjOxX_hcwcrDJjlPRdV6yIy7S9B1y0kfRanw4LoS-olv8i2Q-kGNOItJ8pMzQh7HCO0TSDRoJ_xhns",
        "+:crying_bubbles:",
        "https://mrwgifs.com/wp-content/uploads/2014/02/Bubbles-Sad-Crying-In-The-Rain-With-Puppy-Eyes-On-Powerpuff-Girlfs_408x408.jpg",
        "https://media2.giphy.com/media/j9COtyaa3nnAQ/200w.gif",
    ]
    payload['extras']['say'](random.choice(responses))


PluginManager.register_plugin(fuck_off, pattern, flags=re.IGNORECASE)
Example #12
0
        args.pop(0)

    say = data["extras"]["say"]
    animal = None
    unknown = False

    if len(args) > 1:
        animal = animals.get(args[1])
        if not animal:
            unknown = True

    if not animal:
        # if we get here, we either didn't have args or we didn't pass the
        # right args. Just pick an animal at random.
        animal = animals.get(random.choice([*animals.keys()]))

    animal_name, pic = get_pic(random.choice(animal))
    if unknown:
        say(f"I'm not sure what you asked for, so here's a {animal_name}!")

    say(pic)


PluginManager.register_plugin(
    cute,
    r"cute",
    help=(
        f"!cute [{', '.join([k for k in animals.keys()])}] - Specify an animal"
        f" for a cute picture! Or just !cute for a random one."),
)
Example #13
0
import requests

from bubbles.config import PluginManager, PAYMENT_KEY, PAYMENT_VALUE


def ping_payment(payload):
    result = requests.post(
        "https://payments.grafeas.org/ping", json={PAYMENT_KEY: PAYMENT_VALUE}
    )
    try:
        result.raise_for_status()
    except:
        payload['extras']['say']("I... I don't see anything out there...")


PluginManager.register_plugin(
    ping_payment,
    r"ping payment",
    help="!ping payment - make sure that Gringotts is still accepting coin.",
)
Example #14
0
        commands.append(f"\n- {item}\n\t{data[item]}")
    return template.format("".join(commands))


def help(payload):
    plugins_with_help = dict()
    for plugin in PluginManager.plugins:
        if plugin["help"] is not None:
            # grab the name of the command and the help string.
            plugin_split = str(plugin["callable"]).split()
            if len(plugin_split) == 4:
                # we're looking at a function.
                # <function myfunc at 0x7f28aa33e8b0>
                plugin_name = plugin_split[1]
            else:
                # we're looking at a class.
                # <bound method MyPlugin.myfunc of <__main__.MyPlugin object at 0x7f28aa408070>>
                plugin_name = plugin_split[2].split(".")[1]
            plugins_with_help[plugin_name] = plugin["help"]
    # sort that sucker alphabetically
    plugins_with_help = {
        key: value
        for key, value in sorted(plugins_with_help.items())
    }
    payload['extras']['say'](format_text(plugins_with_help))


PluginManager.register_plugin(help,
                              r"help$",
                              help="!help - Lists out all available commands!")