Exemplo n.º 1
0
#--depends-on commands
#--depends-on config

import re, traceback
from src import ModuleManager, utils

REGEX_SPLIT = re.compile("(?<!\\\\)/")
REGEX_SED = re.compile("^(?:(\\S+)[:,] )?s/")
SED_AMPERSAND = re.compile(r"((?:^|[^\\])(?:\\\\)*)&")


@utils.export("channelset",
              utils.BoolSetting("sed", "Disable/Enable sed in a channel"))
@utils.export(
    "channelset",
    utils.BoolSetting(
        "sed-sender-only",
        "Disable/Enable sed only looking at the messages sent by the user"))
class Module(ModuleManager.BaseModule):
    def _closest_setting(self, event, setting, default):
        return event["target"].get_setting(
            setting, event["server"].get_setting(setting, default))

    @utils.hook("command.regex")
    @utils.kwarg("command", "sed")
    @utils.kwarg("pattern", REGEX_SED)
    def channel_message(self, event):
        sed_split = re.split(REGEX_SPLIT, event["message"], 3)
        if len(sed_split) > 2:
            if not self._closest_setting(event, "sed", False):
                return
Exemplo n.º 2
0
#--depends-on config

from src import ModuleManager, utils

DELAY = 5

rejoin_setting = utils.BoolSetting(
    "kick-rejoin", "Whether or not I should rejoin channels I get kicked from")
delay_setting = utils.IntSetting(
    "kick-rejoin-delay",
    "Amount of seconds to wait before rejoining a channel")


@utils.export("serverset", rejoin_setting)
@utils.export("serverset", delay_setting)
@utils.export("channelset", rejoin_setting)
@utils.export("channelset", delay_setting)
class Module(ModuleManager.BaseModule):
    def _should_rejoin(self, server, channel):
        return channel.get_setting("kick-rejoin",
                                   server.get_setting("kick-rejoin", False))

    def _get_delay(self, server, channel):
        return channel.get_setting(
            "kick-rejoin-delay", server.get_setting("kick-rejoin-delay",
                                                    DELAY))

    @utils.hook("self.kick")
    def on_kick(self, event):
        if self._should_rejoin(event["server"], event["channel"]):
            delay = self._get_delay(event["server"], event["channel"])
Exemplo n.º 3
0
#--depends-on config

from src import ModuleManager, utils

DELAY = 30  # 30 seconds


@utils.export("channelset",
              utils.BoolSetting(
                  "slowvoice",
                  "Enable/disable giving +v to new users after a delay"))
@utils.export("channelset",
              utils.IntSetting("slowvoice-delay",
                               "Set delay for slowvoice in seconds"))
class Module(ModuleManager.BaseModule):
    @utils.hook("timer.slowvoice")
    def timer(self, event):
        event["channel"].send_mode("+v", [event["user"].nickname])

    @utils.hook("new.channel")
    def new_channel(self, event):
        event["channel"]._slowvoice_timers = {}

    @utils.hook("received.join")
    def on_join(self, event):
        if event["channel"].get_setting("slowvoice", False):
            delay = event["channel"].get_setting("slowvoice-delay", DELAY)
            timer = self.timers.add("slowvoice",
                                    delay,
                                    channel=event["channel"],
                                    user=event["user"])
Exemplo n.º 4
0
#--depends-on commands
#--depends-on format_activity
#--depends-on permissions

from src import EventManager, ModuleManager, utils

@utils.export("channelset", utils.BoolSetting("relay-extras",
    "Whether or not to relay joins/parts/quits/modes/etc"))
class Module(ModuleManager.BaseModule):
    @utils.hook("new.server")
    def new_server(self, event):
        event["server"]._relay_ignore = []

    def _get_relays(self, channel):
        return channel.get_setting("channel-relays", [])

    def _relay(self, event, channel):
        if ("parsed_line" in event and
                event["parsed_line"].id in event["server"]._relay_ignore):
            event["server"]._relay_ignore.remove(event["parsed_line"].id)
            return

        relays = {}
        for relay_group in channel.get_setting("relay-groups", []):
            targets = self.bot.get_setting("relay-group-%s" % relay_group, [])
            for server_id, channel_name in targets:
                server = self.bot.get_server_by_id(server_id)
                if server and channel_name in server.channels:
                    relay_channel = server.channels.get(channel_name)
                    if not channel.id == relay_channel.id:
                        if not server in relays:
Exemplo n.º 5
0
#--depends-on channel_access
#--depends-on check_mode
#--depends-on commands
#--depends-on shorturl

import itertools, json, re, urllib.parse
from src import ModuleManager, utils
from . import colors, gitea, github

FORM_ENCODED = "application/x-www-form-urlencoded"

DEFAULT_EVENT_CATEGORIES = [
    "ping", "code", "pr", "issue", "repo"
]

@utils.export("channelset", utils.BoolSetting("git-prevent-highlight",
    "Enable/disable preventing highlights"))
@utils.export("channelset", utils.BoolSetting("git-hide-organisation",
    "Hide/show organisation in repository names"))
@utils.export("channelset", utils.BoolSetting("git-hide-prefix",
    "Hide/show command-like prefix on git webhook outputs"))
class Module(ModuleManager.BaseModule):
    _name = "Webhooks"

    def on_load(self):
        self._github = github.GitHub(self.log)
        self._gitea = gitea.Gitea()

    @utils.hook("api.post.github")
    def _api_github_webhook(self, event):
        return self._webhook("github", "GitHub", self._github,
            event["data"], event["headers"])
Exemplo n.º 6
0
#--depends-on config
#--depends-on format_activity

import datetime, os.path
from src import ModuleManager, utils

ROOT_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
LOGS_DIRECTORY = os.path.join(ROOT_DIRECTORY, "logs")


@utils.export("channelset",
              utils.BoolSetting("log", "Enable/disable channel logging"))
class Module(ModuleManager.BaseModule):
    def _log_file(self, server_name, channel_name):
        return open(
            os.path.join(LOGS_DIRECTORY,
                         "%s%s.log" % (server_name, channel_name)), "a")

    def _log(self, event, channel):
        if channel.get_setting("log", False):
            with self._log_file(str(event["server"]), str(channel)) as log:
                timestamp = datetime.datetime.now().strftime("%x %X")
                log.write("%s %s\n" % (timestamp, event["line"]))

    @utils.hook("formatted.message.channel")
    @utils.hook("formatted.notice.channel")
    @utils.hook("formatted.join")
    @utils.hook("formatted.part")
    @utils.hook("formatted.nick")
    @utils.hook("formatted.invite")
    @utils.hook("formatted.mode.channel")
Exemplo n.º 7
0
#--depends-on config
#--depends-on format_activity

import datetime
from src import EventManager, ModuleManager, utils

@utils.export("botset",
    utils.BoolSetting("print-motd", "Set whether I print /motd"))
class Module(ModuleManager.BaseModule):
    def _print(self, event):
        self.bot.log.info("%s%s | %s", [
            str(event["server"]), event["context"] or "",
            utils.irc.parse_format(event["line"])])

    @utils.hook("formatted.message.channel")
    @utils.hook("formatted.notice.channel")
    @utils.hook("formatted.notice.private")
    @utils.hook("formatted.join")
    @utils.hook("formatted.part")
    @utils.hook("formatted.nick")
    @utils.hook("formatted.server-notice")
    @utils.hook("formatted.invite")
    @utils.hook("formatted.mode.channel")
    @utils.hook("formatted.topic")
    @utils.hook("formatted.topic-timestamp")
    @utils.hook("formatted.kick")
    @utils.hook("formatted.quit")
    @utils.hook("formatted.rename")
    @utils.hook("formatted.chghost")
    def formatted(self, event):
        self._print(event)
Exemplo n.º 8
0
            f"There were {len(relays)} relays found for "
            f"this query. {URL_RELAY_SEARCH_SEARCH}{search}")
    if not relays:
        raise utils.EventError("There were no relays found for this query.")
    details = relays[0]
    nickname = details["nickname"]
    consensus_weight = details["consensus_weight"]
    flags = " ".join(details["flags"])
    url = URL_RELAY_SEARCH_DETAILS + details["fingerprint"]
    return f"{nickname} - CW: {consensus_weight} [{flags}] {url}"


@utils.export(
    "channelset",
    utils.BoolSetting(
        "auto-torrelay",
        "Disable/Enable automatically getting Tor relay info from fingerprints"
    ))
class Module(ModuleManager.BaseModule):
    _name = "Onionoo"

    @utils.hook("command.regex")
    @utils.kwarg("ignore_action", False)
    @utils.kwarg("priority", EventManager.PRIORITY_MONITOR)
    @utils.kwarg("command", "torrelay")
    @utils.kwarg("pattern", REGEX_SHA1_HEX)
    def channel_message(self, event):
        if event["target"].get_setting("auto-torrelay", False):
            event.eat()
            search = event["match"].group(0)
            try:
                relays = _get_relays_details(search)
Exemplo n.º 9
0
import binascii, enum, os, uuid
from src import ModuleManager, utils

STR_NOVOTE = "Unknown vote '%s'"


class VoteCastResult(enum.Enum):
    Cast = 1
    Changed = 2
    Unchanged = 3


@utils.export("channelset",
              utils.BoolSetting(
                  "votes-start-restricted",
                  "Whether starting a vote should be restricted to ops"))
@utils.export(
    "channelset",
    utils.BoolSetting(
        "votes-cast-restricted",
        "Whether casting a vote should be restricted to voiced-and-above users"
    ))
class Module(ModuleManager.BaseModule):
    def _get_vote(self, channel, vote_id):
        return channel.get_setting("vote-%s" % vote_id, None)

    def _set_vote(self, channel, vote_id, vote):
        channel.set_setting("vote-%s" % vote_id, vote)

    def _random_id(self, channel):
Exemplo n.º 10
0
REGEX_YOUTUBE = re.compile("https?://(?:www.)?(?:youtu.be/|youtube.com/)\\S+", re.I)
REGEX_ISO8601 = re.compile("PT(\d+H)?(\d+M)?(\d+S)?", re.I)

URL_YOUTUBESEARCH = "https://www.googleapis.com/youtube/v3/search"
URL_YOUTUBEVIDEO = "https://www.googleapis.com/youtube/v3/videos"
URL_YOUTUBEPLAYLIST = "https://www.googleapis.com/youtube/v3/playlists"

URL_YOUTUBESHORT = "https://youtu.be/%s"
URL_VIDEO = "https://www.youtube.com/watch?v=%s"
URL_PLAYLIST = "https://www.youtube.com/playlist?list=%s"

ARROW_UP = "↑"
ARROW_DOWN = "↓"

@utils.export("channelset", utils.BoolSetting("auto-youtube",
    "Disable/Enable automatically getting info from youtube URLs"))
@utils.export("channelset", utils.BoolSetting("youtube-safesearch",
    "Turn safe search off/on"))
class Module(ModuleManager.BaseModule):
    def on_load(self):
        self.exports.add("search-youtube", self._search_youtube)

    def get_video_page(self, video_id, part):
        return utils.http.request(URL_YOUTUBEVIDEO, get_params={"part": part,
            "id": video_id, "key": self.bot.config["google-api-key"]},
            json=True)
    def video_details(self, video_id):
        snippet = self.get_video_page(video_id, "snippet")
        if snippet.data["items"]:
            snippet = snippet.data["items"][0]["snippet"]
            statistics = self.get_video_page(video_id, "statistics").data[
Exemplo n.º 11
0
#--depends-on commands

import random, time
from src import ModuleManager, utils

@utils.export("channelset", utils.BoolSetting("channel-quotes",
    "Whether or not quotes added from this channel are kept in this channel"))
class Module(ModuleManager.BaseModule):
    def category_and_quote(self, s):
        category, sep, quote = s.partition("=")
        category = category.strip()

        if not sep:
            return category, None
        return category, quote.strip()

    def _get_quotes(self, server, category):
        return server.get_setting("quotes-%s" % category, [])
    def _set_quotes(self, server, category, quotes):
        server.set_setting("quotes-%s" % category, quotes)

    @utils.hook("received.command.qadd", alias_of="quoteadd")
    @utils.hook("received.command.quoteadd", min_args=1)
    def quote_add(self, event):
        """
        :help: Add a quote to a category
        :usage: <category> = <quote>
        """
        category, quote = self.category_and_quote(event["args"])
        if category and quote:
            target = event["server"]
Exemplo n.º 12
0
#--depends-on commands
#--depends-on config

import random, re, time
from src import EventManager, ModuleManager, utils

DUCK = "・゜゜・。。・゜゜\_o< QUACK!"
NO_DUCK = "There was no duck!"

DEFAULT_MIN_MESSAGES = 100


@utils.export("channelset",
              utils.BoolSetting("ducks-enabled",
                                "Whether or not to spawn ducks"))
@utils.export("channelset",
              utils.IntRangeSetting(50, 200, "ducks-min-messages",
                                    "Minimum messages between ducks spawning"))
@utils.export(
    "channelset",
    utils.BoolSetting(
        "ducks-kick",
        "Whether or not to kick someone talking to non-existent ducks"))
class Module(ModuleManager.BaseModule):
    @utils.hook("new.channel")
    def new_channel(self, event):
        self.bootstrap_channel(event["channel"])

    def bootstrap_channel(self, channel):
        if not hasattr(channel, "duck_active"):
            channel.duck_active = None
Exemplo n.º 13
0
                    server = _bot.get_server_by_id(server_id)
                    if server and channel_name in server.channels:
                        follows.append(
                            [server, server.channels.get(channel_name)])

        for server, channel in follows:
            tweet = format._tweet(_exports, server, status)
            _events.on("send.stdout").call(target=channel,
                                           module_name="Tweets",
                                           server=server,
                                           message=tweet)


@utils.export("channelset",
              utils.BoolSetting(
                  "auto-tweet",
                  "Enable/disable automatically getting tweet info"))
class Module(ModuleManager.BaseModule):
    _stream = None

    def on_load(self):
        self._thread = None

        global _bot
        global _events
        global _exports
        global _log
        _bot = self.bot
        _events = self.events
        _exports = self.exports
        _log = self.log
Exemplo n.º 14
0

def _parse(value):
    mechanism, _, arguments = value.partition(" ")
    mechanism = mechanism.upper()

    if mechanism in ALL_MECHANISMS:
        return {"mechanism": mechanism.upper(), "args": arguments}
    else:
        raise utils.SettingParseException("Unknown SASL mechanism '%s'" %
                                          mechanism)


SASL_TIMEOUT = 15  # 15 seconds

HARDFAIL = utils.BoolSetting(
    "sasl-hard-fail", "Set whether a SASL failure should cause a disconnect")


@utils.export("serverset",
              utils.FunctionSetting(
                  _parse,
                  "sasl",
                  "Set the sasl username/password for this server",
                  example="PLAIN BitBot:hunter2",
                  format=utils.sensitive_format))
@utils.export("serverset", HARDFAIL)
@utils.export("botset", HARDFAIL)
class Module(ModuleManager.BaseModule):
    @utils.hook("new.server")
    def new_server(self, event):
        event["server"]._sasl_timeout = None
Exemplo n.º 15
0
URL_GEOIP = "http://ip-api.com/json/%s"
REGEX_IPv6 = r"(?:(?:[a-f0-9]{1,4}:){2,}|[a-f0-9:]*::)[a-f0-9:]*"
REGEX_IPv4 = r"(?:\d{1,3}\.){3}\d{1,3}"
REGEX_IP = re.compile("%s|%s" % (REGEX_IPv4, REGEX_IPv6), re.I)


def _parse(value):
    if utils.is_ip(value):
        return value
    return None


@utils.export("botset",
              utils.BoolSetting(
                  "configurable-nameservers",
                  "Whether or not users can configure their own nameservers"))
@utils.export("serverset",
              utils.FunctionSetting(_parse,
                                    "dns-nameserver",
                                    "Set DNS nameserver",
                                    example="8.8.8.8"))
@utils.export("channelset",
              utils.FunctionSetting(_parse,
                                    "dns-nameserver",
                                    "Set DNS nameserver",
                                    example="8.8.8.8"))
class Module(ModuleManager.BaseModule):
    @utils.hook("received.command.dns", min_args=1)
    def dns(self, event):
        """
Exemplo n.º 16
0
import binascii, enum, os, uuid
from src import ModuleManager, utils

STR_NOVOTE = "Unknown vote '%s'"


class VoteCastResult(enum.Enum):
    Cast = 1
    Changed = 2
    Unchanged = 3


@utils.export("channelset",
              utils.BoolSetting(
                  "votes-start-restricted",
                  "Whether starting a vote should be restricted to ops"))
class Module(ModuleManager.BaseModule):
    def _get_vote(self, channel, vote_id):
        return channel.get_setting("vote-%s" % vote_id, None)

    def _set_vote(self, channel, vote_id, vote):
        channel.set_setting("vote-%s" % vote_id, vote)

    def _random_id(self, channel):
        while True:
            vote_id = binascii.hexlify(os.urandom(3)).decode("ascii")
            if self._get_vote(channel, vote_id) == None:
                return vote_id

    def _close_vote(self, channel, vote_id):
Exemplo n.º 17
0
        upper = value.upper()
        if upper in COMMAND_METHODS:
            return upper
        return None

@utils.export("channelset", utils.Setting("command-prefix",
    "Set the command prefix used in this channel", example="!"))
@utils.export("serverset", utils.Setting("command-prefix",
    "Set the command prefix used on this server", example="!"))
@utils.export("serverset", CommandMethodSetting("command-method",
    "Set the method used to respond to commands"))
@utils.export("channelset", CommandMethodSetting("command-method",
    "Set the method used to respond to commands"))
@utils.export("botset", CommandMethodSetting("command-method",
    "Set the method used to respond to commands"))
@utils.export("channelset", utils.BoolSetting("hide-prefix",
    "Disable/enable hiding prefix in command reponses"))
@utils.export("channelset", utils.BoolSetting("commands",
    "Disable/enable responding to commands in-channel"))
@utils.export("channelset", utils.BoolSetting("prefixed-commands",
    "Disable/enable responding to prefixed commands in-channel"))
class Module(ModuleManager.BaseModule):
    @utils.hook("new.user")
    @utils.hook("new.channel")
    def new(self, event):
        if "user" in event:
            target = event["user"]
        else:
            target = event["channel"]
        target.last_stdout = None
        target.last_stderr = None
Exemplo n.º 18
0
REGEX_PR_OR_ISSUE = re.compile(
    r"https?://github.com/([^/]+)/([^/]+)/(pull|issues)/(\d+)", re.I)
REGEX_REF = re.compile(r"(?:\S+(?:\/\S+)?)?#\d+")

API_ISSUE_URL = "https://api.github.com/repos/%s/%s/issues/%s"
API_PULL_URL = "https://api.github.com/repos/%s/%s/pulls/%s"


@utils.export("channelset",
              utils.Setting(
                  "github-default-repo",
                  "Set the default github repo for the current channel",
                  example="jesopo/bitbot"))
@utils.export("channelset",
              utils.BoolSetting(
                  "auto-github",
                  "Enable/disable automatically getting github issue/PR info"))
@utils.export("channelset",
              utils.IntSetting(
                  "auto-github-cooldown",
                  "Set amount of seconds between auto-github duplicates",
                  example="300"))
class Module(ModuleManager.BaseModule):
    def _parse_ref(self, channel, ref):
        repo, _, number = ref.rpartition("#")
        org, _, repo = repo.partition("/")

        default_repo = channel.get_setting("github-default-repo", "")
        default_org, _, default_repo = default_repo.partition("/")

        if org and not repo:
Exemplo n.º 19
0
#--depends-on check_mode
#--depends-on commands
#--depends-on shorturl

import itertools, json, re, urllib.parse
from src import ModuleManager, utils
from . import colors, gitea, gogs, github, gitlab

FORM_ENCODED = "application/x-www-form-urlencoded"

DEFAULT_EVENT_CATEGORIES = [
    "ping", "code", "pr", "issue", "repo"
]

PRIVATE_SETTING_NAME = "git-show-private"
PRIVATE_SETTING = utils.BoolSetting(PRIVATE_SETTING_NAME,
    "Whether or not to show git activity for private repositories")

@utils.export("channelset", utils.BoolSetting("git-prevent-highlight",
    "Enable/disable preventing highlights"))
@utils.export("channelset", utils.BoolSetting("git-hide-organisation",
    "Hide/show organisation in repository names"))
@utils.export("channelset", utils.BoolSetting("git-hide-prefix",
    "Hide/show command-like prefix on git webhook outputs"))
@utils.export("channelset", utils.BoolSetting("git-shorten-urls",
    "Weather or not git webhook URLs should be shortened"))
@utils.export("botset", PRIVATE_SETTING)
@utils.export("channelset", PRIVATE_SETTING)
class Module(ModuleManager.BaseModule):
    _name = "Webhooks"

    def on_load(self):
Exemplo n.º 20
0
from src import ModuleManager, utils

REASON = "User is banned from this channel"


@utils.export("channelset",
              utils.BoolSetting(
                  "ban-enforce",
                  "Whether or not to parse new bans and kick who they affect"))
class Module(ModuleManager.BaseModule):
    @utils.hook("received.mode.channel")
    def on_mode(self, event):
        if event["channel"].get_setting("ban-enforce", False):
            bans = []
            kicks = set([])
            for mode, arg in event["modes"]:
                if mode[0] == "+" and mode[1] == "b":
                    bans.append(arg)

            if bans:
                umasks = {u.hostmask(): u for u in event["channel"].users}
                for ban in bans:
                    mask = utils.irc.hostmask_parse(ban)
                    matches = list(
                        utils.irc.hostmask_match_many(umasks.keys(), mask))
                    for match in matches:
                        kicks.add(umasks[match])
            if kicks:
                nicks = [u.nickname for u in kicks]
                event["channel"].send_kicks(sorted(nicks), REASON)
Exemplo n.º 21
0
#--depends-on commands
#--depends-on format_activity
#--depends-on permissions

from src import EventManager, ModuleManager, utils


@utils.export("channelset",
              utils.BoolSetting(
                  "relay-extras",
                  "Whether or not to relay joins/parts/quits/modes/etc"))
class Module(ModuleManager.BaseModule):
    @utils.hook("new.server")
    def new_server(self, event):
        event["server"]._relay_ignore = []

    def _get_relays(self, channel):
        return channel.get_setting("channel-relays", [])

    def _relay(self, event, channel):
        if ("parsed_line" in event
                and event["parsed_line"].id in event["server"]._relay_ignore):
            event["server"]._relay_ignore.remove(event["parsed_line"].id)
            return

        relays = {}
        for relay_group in channel.get_setting("relay-groups", []):
            targets = self.bot.get_setting("relay-group-%s" % relay_group, [])
            for server_id, channel_name in targets:
                server = self.bot.get_server_by_id(server_id)
                if server and channel_name in server.channels:
Exemplo n.º 22
0
REGEX_IMAGE = re.compile("https?://(?:i\.)?imgur.com/(\w+)")
REGEX_GALLERY = re.compile("https?://imgur.com/gallery/(\w+)")

GALLERY_FORMAT = "%s%s%sA gallery with %s image%s, %s views, posted %s (%s%s)%s"
IMAGE_FORMAT = "%s%s%sA %s image, %sx%s, with %s views, posted %s%s"

URL_IMAGE = "https://api.imgur.com/3/image/%s"
URL_GALLERY = "https://api.imgur.com/3/gallery/%s"

NSFW_TEXT = "(NSFW)"


@utils.export("channelset",
              utils.BoolSetting(
                  "auto-imgur",
                  "Disable/Enable automatically getting info from Imgur URLs"))
class Module(ModuleManager.BaseModule):
    def _prefix(self, data):
        text = "%s: " % data["id"]
        if data["nsfw"]:
            text += "[NSFW] "
        if data["account_url"]:
            text += "%s " % data["account_url"]
        return text

    @utils.hook("command.regex")
    @utils.kwarg("ignore_action", False)
    @utils.kwarg("command", "imgur")
    @utils.kwarg("pattern", REGEX_IMAGE)
    def _regex_image(self, event):
Exemplo n.º 23
0
#--depends-on channel_access
#--depends-on check_mode
#--depends-on commands
#--depends-on config

from src import ModuleManager, utils

class UserNotFoundException(Exception):
    pass
class InvalidTimeoutException(Exception):
    pass

@utils.export("channelset", utils.IntSetting("highlight-spam-threshold",
    "Set the number of nicknames in a message that qualifies as spam"))
@utils.export("channelset", utils.BoolSetting("highlight-spam-protection",
    "Enable/Disable highlight spam protection"))
@utils.export("channelset", utils.BoolSetting("highlight-spam-ban",
    "Enable/Disable banning highlight spammers instead of just kicking"))
@utils.export("channelset", utils.Setting("ban-format",
    "Set ban format ($n = nick, $u = username, $h = hostname)",
    example="*!$u@$h"))
@utils.export("serverset", utils.OptionsSetting("mute-method",
    ["qmode", "insp", "unreal", "none"],
    "Set this server's method of muting users"))
class Module(ModuleManager.BaseModule):
    _name = "ChanOp"

    @utils.hook("timer.unban")
    def _timer_unban(self, event):
        server = self.bot.get_server_by_id(event["server_id"])
        if server and event["channel_name"] in server.channels:
Exemplo n.º 24
0
URL_YOUTUBESEARCH = "https://www.googleapis.com/youtube/v3/search"
URL_YOUTUBEVIDEO = "https://www.googleapis.com/youtube/v3/videos"
URL_YOUTUBEPLAYLIST = "https://www.googleapis.com/youtube/v3/playlists"

URL_YOUTUBESHORT = "https://youtu.be/%s"
URL_VIDEO = "https://www.youtube.com/watch?v=%s"
URL_PLAYLIST = "https://www.youtube.com/playlist?list=%s"

ARROW_UP = "↑"
ARROW_DOWN = "↓"


@utils.export(
    "channelset",
    utils.BoolSetting(
        "auto-youtube",
        "Disable/Enable automatically getting info from youtube URLs"))
@utils.export("channelset",
              utils.BoolSetting("youtube-safesearch",
                                "Turn safe search off/on"))
class Module(ModuleManager.BaseModule):
    def on_load(self):
        self.exports.add("search-youtube", self._search_youtube)

    def get_video_page(self, video_id, part):
        return utils.http.request(URL_YOUTUBEVIDEO,
                                  get_params={
                                      "part": part,
                                      "id": video_id,
                                      "key": self.bot.config["google-api-key"]
                                  },
Exemplo n.º 25
0
#--depends-on commands
#--depends-on config
#--require-config virustotal-api-key
# ^ get API key from https://www.virustotal.com/en/documentation/public-api/

import re
from src import ModuleManager, utils

URL_VIRUSTOTAL = "https://www.virustotal.com/vtapi/v2/url/report"
RE_URL = re.compile(r"https?://\S+", re.I)


@utils.export("channelset",
              utils.BoolSetting(
                  "check-urls",
                  "Enable/Disable automatically checking for malicious URLs"))
@utils.export("serverset",
              utils.BoolSetting(
                  "check-urls",
                  "Enable/Disable automatically checking for malicious URLs"))
@utils.export(
    "channelset",
    utils.BoolSetting(
        "check-urls-kick",
        "Enable/Disable automatically kicking users that send malicious URLs"))
class Module(ModuleManager.BaseModule):
    _name = "CheckURL"

    @utils.hook("command.regex")
    @utils.kwarg("ignore_action", False)
    @utils.kwarg("command", "check-url")
Exemplo n.º 26
0
#--depends-on commands
#--depends-on config
#--depends-on shorturl

import hashlib, re, urllib.parse
from src import EventManager, ModuleManager, utils

@utils.export("channelset", utils.BoolSetting("auto-title",
    "Disable/Enable automatically getting info titles from URLs"))
@utils.export("channelset", utils.BoolSetting("title-shorten",
    "Enable/disable shortening URLs when getting their title"))
@utils.export("channelset", utils.BoolSetting("auto-title-first",
    "Enable/disable showing who first posted a URL that was auto-titled"))
class Module(ModuleManager.BaseModule):
    def _url_hash(self, url):
        return "sha256:%s" % hashlib.sha256(url.lower().encode("utf8")
            ).hexdigest()

    def _get_title(self, server, channel, url):
        if not urllib.parse.urlparse(url).scheme:
            url = "http://%s" % url

        hostname = urllib.parse.urlparse(url).hostname
        if utils.http.is_localhost(hostname):
            self.log.warn("tried to get title of localhost: %s", [url])
            return None

        try:
            page = utils.http.request(url, soup=True)
        except utils.http.HTTPWrongContentTypeException:
            return None
Exemplo n.º 27
0
class UserNotFoundException(Exception):
    pass


class InvalidTimeoutException(Exception):
    pass


@utils.export(
    "channelset",
    utils.IntSetting(
        "highlight-spam-threshold",
        "Set the number of nicknames in a message that qualifies as spam"))
@utils.export("channelset",
              utils.BoolSetting("highlight-spam-protection",
                                "Enable/Disable highlight spam protection"))
@utils.export(
    "channelset",
    utils.BoolSetting(
        "highlight-spam-ban",
        "Enable/Disable banning highlight spammers instead of just kicking"))
@utils.export("channelset",
              utils.Setting(
                  "ban-format",
                  "Set ban format ($n = nick, $u = username, $h = hostname)",
                  example="*!$u@$h"))
@utils.export("serverset",
              utils.OptionsSetting("mute-method",
                                   ["qmode", "insp", "unreal", "none"],
                                   "Set this server's method of muting users"))
class Module(ModuleManager.BaseModule):
Exemplo n.º 28
0
#--depends-on commands
#--depends-on config
#--depends-on permissions

import re, time
from src import EventManager, ModuleManager, utils

WORD_STOP = [",", ":"]
KARMA_DELAY_SECONDS = 3

REGEX_KARMA = re.compile(r"^(.*)(\+{2}|\-{2})$")

@utils.export("channelset", utils.BoolSetting("karma-verbose",
    "Enable/disable automatically responding to karma changes"))
@utils.export("serverset", utils.BoolSetting("karma-nickname-only",
    "Enable/disable karma being for nicknames only"))
class Module(ModuleManager.BaseModule):
    def _karma_str(self, karma):
        karma_str = str(karma)
        if karma < 0:
            return utils.irc.color(str(karma), utils.consts.RED)
        elif karma > 0:
            return utils.irc.color(str(karma), utils.consts.LIGHTGREEN)
        return str(karma)

    @utils.hook("new.user")
    def new_user(self, event):
        event["user"]._last_positive_karma = None
        event["user"]._last_negative_karma = None

    def _check_throttle(self, user, positive):
Exemplo n.º 29
0
#--depends-on config
#--depends-on shorturl

import time
from src import ModuleManager, utils
import feedparser

RSS_INTERVAL = 60  # 1 minute


@utils.export("botset",
              utils.IntSetting("rss-interval",
                               "Interval (in seconds) between RSS polls",
                               example="120"))
@utils.export("channelset",
              utils.BoolSetting("rss-shorten",
                                "Whether or not to shorten RSS urls"))
class Module(ModuleManager.BaseModule):
    _name = "RSS"

    def on_load(self):
        self.timers.add("rss",
                        self.bot.get_setting("rss-interval", RSS_INTERVAL))

    def _format_entry(self, server, feed_title, entry, shorten):
        title = entry["title"]

        author = entry.get("author", None)
        author = " by %s" % author if author else ""

        link = entry.get("link", None)
        if shorten:
Exemplo n.º 30
0
        _log.debug(
            "[HTTP] finishing _handle for %s from %s:%d (%d)",
            [method, self.client_address[0], self.client_address[1], code])

    def do_GET(self):
        self._handle("GET")

    def do_POST(self):
        self._handle("POST")

    def log_message(self, format, *args):
        return


@utils.export("botset", utils.BoolSetting("rest-api",
                                          "Enable/disable REST API"))
@utils.export("botset",
              utils.BoolSetting("rest-api",
                                "Enable/disable REST API minifying"))
class Module(ModuleManager.BaseModule):
    def on_load(self):
        global _bot
        _bot = self.bot

        global _events
        _events = self.events

        global _log
        _log = self.log

        self.httpd = None