Esempio n. 1
0
    def run(self):
        irc = IRC()
        # Will log all events to stdout
        for event in all_events:
            self._set_print_handler(irc, event)
        server = irc.server()
        if self._config.get('ssl'):
            factory = Factory(wrapper=ssl.wrap_socket)
        else:
            factory = Factory()
        server.connect(self._config['network'],
                       self._config['port'],
                       self._config['nick'],
                       ircname=self._config['name'],
                       connect_factory=factory,
                       password=self._config.get('password'))
        server.join(self._config['channel'],
                    key=self._config.get('channel_password', ''))
        self._load_plugins(irc, server)
        while True:
            try:
                # Signals makes the select to exit
                irc.process_forever()
            except select.error:
                pass

        # handle private messages, to see if there's a need for
        # authentification requests
        irc.add_global_handler('privnotice', self._event_notice)
Esempio n. 2
0
    def __init__(
        self,
        server: str,
        port: int,
        nickname: str,
        alias: str,
        channels: Iterable[str],
        response_timeout: Optional[float],
        dcc_file_transfer_timeout: Optional[float],
        dcc_accept_timeout: Optional[float],
        dcc_downloads_dir: str,
        realname: Optional[str] = None,
        password: Optional[str] = None,
        ssl: bool = False,
        ipv6: bool = False,
        stop_message: Optional[str] = None,
        dcc_ip_whitelist: Optional[Sequence[str]] = None,
        dcc_ip_blacklist: Optional[Sequence[str]] = None,
        dcc_nick_whitelist: Optional[Sequence[str]] = None,
        dcc_nick_blacklist: Optional[Sequence[str]] = None,
        dcc_max_connections: Optional[int] = None,
    ):
        connection_factory = ConnectionFactory()
        if ssl:
            connection_factory.wrapper = _ssl.wrap_socket
        if ipv6:
            connection_factory.family = socket.AF_INET6

        super().__init__(server_list=[(server, port)],
                         nickname=nickname,
                         realname=realname,
                         connect_factory=connection_factory)

        self.server = server
        self.port = port
        self.alias = alias
        self._password = password
        self.channels.update({channel: None for channel in channels})
        self._stop_message = stop_message
        self.dcc_ip_whitelist = set(dcc_ip_whitelist or [])
        self.dcc_ip_blacklist = set(dcc_ip_blacklist or [])
        self.dcc_nick_whitelist = set(dcc_nick_whitelist or [])
        self.dcc_nick_blacklist = set(dcc_nick_blacklist or [])
        self.dcc_downloads_dir = dcc_downloads_dir
        self.response_timeout = response_timeout
        self.dcc_file_transfer_timeout = dcc_file_transfer_timeout
        self.dcc_accept_timeout = dcc_accept_timeout
        self.dcc_max_connections = dcc_max_connections
        self._dcc_send_procs: Dict[Tuple[str, int],
                                   multiprocessing.Process] = {}
        self._dcc_recv_procs: Dict[Tuple[str, int],
                                   multiprocessing.Process] = {}
        self._dcc_proc_completion_queue = multiprocessing.Queue()
        self._dcc_processor: Optional[multiprocessing.Process] = None
        self.logger = logging.getLogger(f'irc@{server}')
        # Maps <matching_event_type> -> <response_queue>
        self._pending_requests: Dict[str, multiprocessing.Queue] = {}
Esempio n. 3
0
 def __init__(self, server, port, nickname, password=None, ssl=False):
     """
     初期化処理
     """
     server_obj = irc.bot.ServerSpec(server, port, password)
     connection_factory = Factory()
     if ssl:
         connection_factory.from_legacy_params(ssl=True)
     irc.bot.SingleServerIRCBot.__init__(self, [server_obj], nickname, nickname, 60, connect_factory=connection_factory)
     self.channel = IRC_CHANNELS
     self.queue = []
Esempio n. 4
0
def _create_bot(server: IrcServer, nickname: str, realname: str) -> Bot:
    """Create a bot."""
    server_spec = ServerSpec(server.host, server.port, server.password)
    factory = Factory(wrapper=ssl.wrap_socket) if server.ssl else Factory()

    bot = Bot([server_spec], nickname, realname, connect_factory=factory)

    _set_rate_limit(bot.connection, server.rate_limit)

    # Avoid `UnicodeDecodeError` on non-UTF-8 messages.
    bot.connection.buffer_class = LenientDecodingLineBuffer

    return bot
Esempio n. 5
0
 def __init__(self, password):
     """Create a VoidBot."""
     factory = Factory(wrapper=ssl.wrap_socket)  # SSL support
     super().__init__([ServerSpec('irc.libera.chat', 6697)],
                      'Void-bot',
                      'VoidBot',
                      connect_factory=factory)
     self.connection.buffer_class.errors = "replace"  # Encoded colors cause errors with utf-8
     self.account = 'Void-bot'
     self.dev = 'miraheze/Void'
     self.__password = password
     self.path = Path(os.path.dirname(os.path.abspath(sys.argv[0])))
     self.saves = {}
     self.trusted = {}
     self.banlist = {}
     self.channel_list = []
     self.load()
     self.apis = {
         'meta': Api('miraheze', 'meta.miraheze.org'),
         'cvt': Api('miraheze', 'cvt.miraheze.org'),
         'testadminwiki': Api('testadminwiki',
                              'testwiki.wiki',
                              script_path=''),
         'botwiki': Api('miraheze', 'wiki.fossbots.org')
     }
     self.probably_connected = True
     self.reactor.scheduler.execute_every(600, self.check_connection)
     self.reactor.scheduler.execute_every(1200, self.save)
     self.handlers = handlers.load_handlers(self)
     self.reactor.add_global_handler('all_events', self.run_handlers, 10)
Esempio n. 6
0
    def __init__(self,
                 hostname,
                 port,
                 nickname,
                 realname,
                 channel,
                 password,
                 mpd_client,
                 admins,
                 nickserv_nick=None,
                 ssl=False):
        server = (hostname, port)
        if ssl:
            super().__init__(
                [server],
                nickname,
                realname,
                recon=self.strategy,
                connect_factory=Factory(wrapper=ssllib.wrap_socket))
        else:
            super().__init__([server], nickname, realname, recon=self.strategy)
        self.channel = channel
        self.votes = 0
        self.voters = {}
        self.poll_remaining = -1
        self.poll_time = config['poll'].getint('poll time')
        self.previous_track = None
        self.previous_topic = None
        self.admins = admins
        self.nickserv_password = password
        self.nickserv_nick = nickserv_nick or nickname
        self.mpd = mpd_client

        self.connection.set_rate_limit(100)
Esempio n. 7
0
    def __init__(self):
        ssl_factory = Factory(
            wrapper=ssl.wrap_socket) if config['tls'] else None
        self.loaded_plugins = PluginLoader().get_plugins()

        super().__init__(server_list=[
            (config['server'], config['port']),
        ],
                         nickname=config['nickname'],
                         realname=config['realname'])
Esempio n. 8
0
 def __init__(self, server_address, name, channel, ignore=None):
     super(Bot, self).__init__(
         [server_address],
         name,
         name,
         recon=ExponentialBackoff(min_interval=RECONNECT_TIMEOUT,
                                  max_interval=2 * RECONNECT_TIMEOUT),
         connect_factory=Factory(wrapper=ssl.wrap_socket))
     self.name = name
     self.channel = channel
     self.ignore = ignore or []
Esempio n. 9
0
 def __init__(self, name: str, conf: Dict, msg_handler: Callable[[message],
                                                                 None]):
     self.name = name
     self.nickname = conf['nick']
     self.channel = conf['channel']
     self.host = conf['host']
     irc.bot.SingleServerIRCBot.__init__(
         self, [(conf['host'], conf['port'])],
         self.nickname,
         self.nickname,
         connect_factory=Factory(wrapper=ssl.wrap_socket))
     self.msg_handler = msg_handler
Esempio n. 10
0
    def __init__(self, host, port, channel, name):
        if channel[0] != '#':
            channel = "#" + channel

        super(Bot, self).__init__(
            [(host, port)],
            name,
            name,
            recon=ExponentialBackoff(min_interval=RECONNECT_TIMEOUT,
                                     max_interval=2 * RECONNECT_TIMEOUT),
            connect_factory=Factory(wrapper=ssl.wrap_socket))
        self.name = name
        self.channel = channel
        self.log_channel = Channel(self.name)
Esempio n. 11
0
    def _make_new_connection(self):
        self.conn = Connection(self.bot.reactor)
        with self.bot.reactor.mutex:
            self.bot.reactor.connections.append(self.conn)
        self.conn.connect(
            "irc.chat.twitch.tv",
            6697,
            self.bot.nickname,
            self.bot.password,
            self.bot.nickname,
            connect_factory=Factory(wrapper=ssl.wrap_socket),
        )
        self.conn.cap("REQ", "twitch.tv/commands", "twitch.tv/tags")

        self.ping_task = ScheduleManager.execute_every(30, lambda: self.bot.execute_now(self._send_ping))
Esempio n. 12
0
    def make_new_connection(self):
        ip = self.host
        port = self.port

        try:
            ssl_factory = Factory(wrapper=ssl.wrap_socket)
            self.main_conn = Connection(self.reactor)
            with self.reactor.mutex:
                self.reactor.connections.append(self.main_conn)
            self.main_conn.connect(
                ip, port, self.bot.nickname, self.bot.password, self.bot.nickname, connect_factory=ssl_factory
            )
            self.main_conn.cap("REQ", "twitch.tv/commands", "twitch.tv/tags")
        except irc.client.ServerConnectionError:
            return False
Esempio n. 13
0
    def __init__(
        self,
        notifications: List[str],
        server: str,
        nickname: str,
        port: int,
        channel: str,
        password: Optional[str] = None,
        use_ssl: bool = True,
    ) -> None:
        self.notifications = notifications
        self.channel = channel

        ssl_factory = None
        if use_ssl:
            ssl_factory = Factory(wrapper=ssl.wrap_socket)
        reactor = Reactor()
        try:
            s = reactor.server()
            c = s.connect(server,
                          port,
                          nickname,
                          password=password,
                          connect_factory=ssl_factory)
        except ServerConnectionError as e:
            print(f"error sending irc notification {e}")
            return

        c.add_global_handler("welcome", self.on_connect)
        c.add_global_handler("join", self.on_join)
        c.add_global_handler("disconnect", self.on_disconnect)

        try:
            reactor.process_forever()
        except Exit:
            pass
Esempio n. 14
0
    def __init__(self, botconfig):
        """Setup everything.

        | Setup the handler.
        | Setup the server.
        | Connect to the server.
        """
        atexit.register(self.do_shutdown)
        self.handler = handler.BotHandler(botconfig)
        self.config = botconfig
        serverinfo = ServerSpec(botconfig['core']['host'], int(botconfig['core']['ircport']), botconfig['auth']['serverpass'])
        nick = botconfig['core']['nick']
        if botconfig['core'].getboolean('ssl'):
            SingleServerIRCBot.__init__(self, [serverinfo], nick, nick, connect_factory=Factory(wrapper=ssl.wrap_socket))
        else:
            SingleServerIRCBot.__init__(self, [serverinfo], nick, nick)
        # properly log quits.
        self.connection.add_global_handler("quit", self.handle_quit, -21)
        # fix unicode problems
        self.connection.buffer_class.errors = 'replace'
Esempio n. 15
0
    def __init__(self, uri=None, **kwargs):
        """Initialize the socket and initialize pdb."""
        params = DEFAULT_PARAMS.copy()
        params.update(parse_irc_uri(uri))
        params.update(kwargs)

        # Backup stdin and stdout before replacing them by the socket handle
        self.old_stdout = sys.stdout
        self.old_stdin = sys.stdin
        self.read_timeout = 0.1

        if not params.get('limit_access_to'):
            raise NoAllowedNicknamesSelected(
                "You must specify a list of nicknames that are allowed "
                "to interact with the debugger using the "
                "`limit_access_to` keyword argument.")
        elif isinstance(params.get('limit_access_to'), six.string_types):
            params['limit_access_to'] = [params.get('limit_access_to')]

        connect_params = {}
        if not params.get('nickname'):
            params['nickname'] = socket.gethostname().split('.')[0]
        if not params.get('channel'):
            raise NoChannelSelected(
                "You must specify a channel to connect to using the "
                "`channel` keyword argument.")
        if params.get('ssl'):
            connect_params['connect_factory'] = (Factory(
                wrapper=ssllib.wrap_socket))

        # Writes to stdout are forbidden in mod_wsgi environments
        try:
            logger.info("ircpdb has connected to %s:%s on %s\n",
                        params.get('server'), params.get('port'),
                        params.get('channel'))
        except IOError:
            pass

        r_pipe, w_pipe = os.pipe()
        # The A pipe is from the bot to pdb
        self.p_A_pipe = os.fdopen(r_pipe, 'r')
        self.b_A_pipe = os.fdopen(w_pipe, 'w')

        r_pipe, w_pipe = os.pipe()
        # The B pipe is from pdb to the bot
        self.b_B_pipe = os.fdopen(r_pipe, 'r')
        self.p_B_pipe = os.fdopen(w_pipe, 'w')

        pdb.Pdb.__init__(
            self,
            stdin=self.p_A_pipe,
            stdout=self.p_B_pipe,
        )

        paste_backend = paste_backends.GistBackend()
        self.bot = IrcpdbBot(
            channel=params.get('channel'),
            nickname=params.get('nickname'),
            server=params.get('server'),
            port=params.get('port'),
            password=params.get('password'),
            limit_access_to=params.get('limit_access_to'),
            message_wait_seconds=params.get('message_wait_seconds'),
            paste_minimum_response_length=(
                params.get('paste_minimum_response_length')),
            paste_backend=paste_backend,
            activation_timeout=params.get('activation_timeout'),
            **connect_params)
Esempio n. 16
0
 def handle_connect(self, serverinfo, nick, botconfig):
     ipv6 = botconfig.getboolean('ipv6')
     if botconfig.getboolean('ssl'):
         SingleServerIRCBot.__init__(self, [serverinfo], nick, nick, connect_factory=Factory(wrapper=ssl.wrap_socket, ipv6=ipv6))
     else:
         SingleServerIRCBot.__init__(self, [serverinfo], nick, nick, connect_factory=Factory(ipv6=ipv6))
Esempio n. 17
0
    def __init__(self):
        self.logger = LOGGER
        self.dir = HERMES_DIR
        self.logger.info("-> Loading Hermes ({})".format(get_version_string()))
        if not os.path.isdir(HERMES_DIR):
            os.makedirs(HERMES_DIR, exist_ok=True)
        self.config = load_config(os.path.join(HERMES_DIR, "config.yml"))
        self.logger.info("-> Loaded Config")
        self.nick = self.config.nick
        self.name = self.config.name if 'name' in self.config else self.nick

        self.logger.info("-> Loading Modules")
        self.modules = load_modules()
        self.logger.info("-> Modules Loaded")

        if 'persist' in self.config and 'path' in self.config.persist:
            persist_path = self.config.persist.path.replace(
                '!HERMES!', self.dir)
        else:
            persist_path = os.path.join(self.dir, 'persist.dat')

        self.storage = PersistentStorage(persist_path)

        self.logger.info("-> Loaded Storage ({0} keys)".format(
            len(self.storage)))
        if 'cache' not in self.storage:
            self.storage['cache'] = DotDict()

        self.cache = Cache(self.storage['cache'])

        self.logger.info("-> Loaded Cache ({0} keys)".format(len(self.cache)))

        self.listener = None
        self.database = None

        if 'socket' in self.config:
            self.listener = Listener(self.config['socket']['host'],
                                     self.config['socket']['port'])

        if 'database' in self.config:
            self.database = GazelleDB(self.config.database.host,
                                      self.config.database.dbname,
                                      self.config.database.username,
                                      self.config.database.password)
        elif 'api' in self.config:
            self.database = GazelleAPI(self.config.site.url,
                                       self.config.api.id, self.config.api.key,
                                       self.cache)

        self.logger.info("-> Loaded DB")

        for name, mod in self.modules.items():
            # noinspection PyBroadException
            try:
                if hasattr(mod, 'setup'):
                    mod.setup(self)
                self.logger.info("Loaded module: {}".format(name))
            except BaseException:
                self.logger.exception("Error Module: {}".format(name))

        if 'ssl' in self.config.irc and self.config.irc.ssl is True:
            factory = Factory(wrapper=ssl.wrap_socket)
        else:
            factory = Factory()

        super().__init__([(self.config.irc.host, self.config.irc.port)],
                         '{}{}'.format(self.nick, random.randint(1, 1000)),
                         self.name,
                         connect_factory=factory)
        for attr in ("on_pubmsg", "on_privmsg"):
            setattr(self, attr, self._dispatch)
        self.logger.info("-> Loaded IRC")
Esempio n. 18
0
def establish_connection(term, session):
    """
    Establish a connection to the IRC server.

    Returns IRCChat instance or False depending on whether it was successful.
    """
    scrollback = collections.deque(maxlen=MAX_SCROLLBACK)
    kwargs = dict()
    if ENABLE_SSL:
        from ssl import wrap_socket
        from irc.connection import Factory
        kwargs['connect_factory'] = Factory(wrapper=wrap_socket)
    if PASSWORD is not None:
        kwargs['password'] = PASSWORD

    echo(u'Connecting to {server}:{port} for channel {chan}.\r\n\r\n'
         'press [{key_q}] to abort ... '.format(server=SERVER,
                                                port=PORT,
                                                chan=CHANNEL,
                                                key_q=term.bold(u'q')))

    client = IRCChat(term, session)
    irc_handle = session.user.handle.replace(' ', '_')
    try:
        # pylint: disable=W0142
        client.connect(SERVER, PORT, irc_handle, **kwargs)
    except irc.client.ServerConnectionError:
        echo(term.bold_red(u'Connection error!'))
        term.inkey(3)
        raise EOFError()

    while True:
        client.reactor.process_once()
        event, data = session.read_events(
            ('irc', 'irc-quit', 'irc-connected', 'input'), timeout=0.02)
        if event == 'irc':
            # show on-connect motd data if any received
            echo(u'\r\n{0}'.format(data[0]))
            scrollback.append(data[0])
        elif event == 'irc-connected':
            break
        elif event == 'input':
            session.buffer_input(data, pushback=True)
            inp = term.inkey(0)
            while inp is not None:
                if inp.lower() == u'q' or inp.code == term.KEY_ESCAPE:
                    echo(u'Canceled!')
                    raise EOFError()
                inp = term.inkey(0)
        elif event == 'irc-quit':
            echo(term.bold_red(u'\r\nConnection failed: {0}!'.format(data)))
            term.inkey(3)
            raise EOFError()

    while True:
        client.reactor.process_once()
        event, data = session.read_events(
            ('irc', 'irc-welcome', 'irc-quit', 'input'), timeout=0.2)
        if event == 'irc':
            # show on-connect motd data if any received
            echo(u'\r\n{0}'.format(data[0]))
            scrollback.append(data[0])
        if event == 'irc-quit':
            echo(term.bold_red(u'\r\nConnection lost: {0}!'.format(data)))
            term.inkey(3)
            raise EOFError()
        elif event == 'input':
            session.buffer_input(data, pushback=True)
            inp = term.inkey(0)
            while inp is not None:
                if inp.lower() == u'q' or inp.code == term.KEY_ESCAPE:
                    echo(u'Canceled!')
                    raise EOFError()
                inp = term.inkey(0)
        elif event == 'irc-welcome':
            return client, scrollback