<commit_before># coding: utf-8

import httplib
import random
import time
import traceback
import urllib
import xmlrpclib

from jabberbot import JabberBot, botcmd
from markov import MarkovChain

class MUCJabberBot(JabberBot):

    # Enable ping
    PING_FREQUENCY = 30

    def __init__(self, *args, **kwargs):
        self.room_nicknames = {}
        self.prefix = "!"
        self.room_logger = kwargs.pop("room_logger")
        self.markov = MarkovChain(kwargs.pop("markov_file"))
        self.last_join = time.time()
        super(MUCJabberBot, self).__init__(*args, **kwargs)

    def callback_message(self, conn, msg):
        # Delayed messages are those that come from groupchat history.
        # Avoid reacting on history messages.
        if msg.getTag("delay", namespace="urn:xmpp:delay"):
            return

        message = msg.getBody()
        if not message:
            return

        if (msg.getFrom().getStripped() in self.room_nicknames and
                msg.getType() == "groupchat"):
            # One logger for all rooms, oh no!
            self.room_logger.write_message(msg.getFrom().getResource(),
                    message)
            self.markov.add(message)

        if message.startswith(self.prefix):
            msg.setBody(message[len(self.prefix):])
        else:
            room = msg.getFrom().getStripped()
            if room in self.room_nicknames:
                # Only process messages started with bot's nickname
                nickname = self.room_nicknames[room]
                if message.startswith(nickname) and msg.getFrom().getResource() != nickname:
                    msg.setBody(message[len(nickname)+1:].strip())
                    markov = self.markov.get()
                    if markov:
                        self.send_simple_reply(msg, markov)
                else:
                    return
        return super(MUCJabberBot, self).callback_message(conn, msg)

    def callback_presence(self, conn, pr):
        if pr.getFrom().getStripped() in self.room_nicknames:
            if pr.getType() == "unavailable":
                text = "left the room"
            elif pr.getShow() is None:
                text = "is online"
            else:
                text = "is %s" % pr.getShow()
            if pr.getStatus() is not None:
                text += ": " + pr.getStatus()
            self.room_logger.write_notification(pr.getFrom().getResource(),
                    text)
        return super(MUCJabberBot, self).callback_presence(conn, pr)

    def join_room(self, chatroom, nickname, *args, **kwargs):
        # Store nickname in each room to fetch direct replies
        self.room_nicknames[chatroom] = nickname
        return super(MUCJabberBot, self).join_room(chatroom, nickname)

    def build_reply(self, msg, text, private=False):
        # Prepend text with sender's nickname if in a groupchat
        if not private:
            text = "%s: %s" % (msg.getFrom().getResource(), text)
        return super(MUCJabberBot, self).build_reply(msg, text, private)

    def idle_proc(self):
        if time.time() - self.last_join > 60 * 60 * 2:
            # Every 2 hours make sure we're in all rooms - important for logging
            for room, nick in self.room_nicknames.iteritems():
                self.join_room(room, nick)
            self.last_join = time.time()
        return super(MUCJabberBot, self).idle_proc()

    TEXT_LIMIT_PER_MESSAGE = 1000
    TEXT_LIMIT_SUFFIX = ' [...]'
    TEXT_LIMIT_WAIT_SECONDS = 5

    def send(self, user, text, in_reply_to=None, message_type='chat'):
        if text:<commit_msg>Improve room ping and install systemd watchdog<commit_after># coding: utf-8

import httplib
import random
import sdnotify
import time
import traceback
import urllib
import xmlrpclib
import xmpp

from jabberbot import JabberBot, botcmd
from markov import MarkovChain

class MUCJabberBot(JabberBot):

    # Enable ping
    PING_FREQUENCY = 30

    def __init__(self, *args, **kwargs):
        self.room_nicknames = {}
        self.prefix = "!"
        self.room_logger = kwargs.pop("room_logger")
        self.markov = MarkovChain(kwargs.pop("markov_file"))
        self.last_ping = time.time()
        self._sdnotify = sdnotify.SystemdNotifier()
        super(MUCJabberBot, self).__init__(*args, **kwargs)

    def callback_message(self, conn, msg):
        # Delayed messages are those that come from groupchat history.
        # Avoid reacting on history messages.
        if msg.getTag("delay", namespace="urn:xmpp:delay"):
            return

        message = msg.getBody()
        if not message:
            return

        if (msg.getFrom().getStripped() in self.room_nicknames and
                msg.getType() == "groupchat"):
            # One logger for all rooms, oh no!
            self.room_logger.write_message(msg.getFrom().getResource(),
                    message)
            self.markov.add(message)

        if message.startswith(self.prefix):
            msg.setBody(message[len(self.prefix):])
        else:
            room = msg.getFrom().getStripped()
            if room in self.room_nicknames:
                # Only process messages started with bot's nickname
                nickname = self.room_nicknames[room]
                if message.startswith(nickname) and msg.getFrom().getResource() != nickname:
                    msg.setBody(message[len(nickname)+1:].strip())
                    markov = self.markov.get()
                    if markov:
                        self.send_simple_reply(msg, markov)
                else:
                    return
        return super(MUCJabberBot, self).callback_message(conn, msg)

    def callback_presence(self, conn, pr):
        if pr.getFrom().getStripped() in self.room_nicknames:
            if pr.getType() == "unavailable":
                text = "left the room"
            elif pr.getShow() is None:
                text = "is online"
            else:
                text = "is %s" % pr.getShow()
            if pr.getStatus() is not None:
                text += ": " + pr.getStatus()
            self.room_logger.write_notification(pr.getFrom().getResource(),
                    text)
        return super(MUCJabberBot, self).callback_presence(conn, pr)

    def join_room(self, chatroom, nickname, *args, **kwargs):
        # Store nickname in each room to fetch direct replies
        self.room_nicknames[chatroom] = nickname
        return super(MUCJabberBot, self).join_room(chatroom, nickname)

    def build_reply(self, msg, text, private=False):
        # Prepend text with sender's nickname if in a groupchat
        if not private:
            text = "%s: %s" % (msg.getFrom().getResource(), text)
        return super(MUCJabberBot, self).build_reply(msg, text, private)

    def idle_proc(self):
        if time.time() - self.last_ping > 30:
            # TODO: use WATCHDOG_USEC environment to check this timer
            self.last_ping = time.time()
            try:
                for room, nick in self.room_nicknames.iteritems():
                    if not self.room_ping(room):
                        self.join_room(room, nick)
                self._sdnotify.notify('WATCHDOG=1')
            except:
                traceback.print_exc()
        return super(MUCJabberBot, self).idle_proc()

    def room_ping(self, room):
        item = xmpp.simplexml.Node('item')
        item.setAttr('nick', self.room_nicknames[room])
        item.setAttr('role', "none")
        NS_MUCADMIN = 'http://jabber.org/protocol/muc#admin'
        iq = xmpp.Iq(typ='set', queryNS=NS_MUCADMIN, xmlns=None, to=room,
                payload=set([item]))
        item.setTagData('reason', "ping")
        outcome = self.connect().WaitForResponse(self.connect().send(iq))
        if outcome:
            tag = outcome.getTag('error')
            if tag:
                # not-allowed
                return tag.getAttr('code') == '405'
            return True
        return False

    TEXT_LIMIT_PER_MESSAGE = 1000
    TEXT_LIMIT_SUFFIX = ' [...]'
    TEXT_LIMIT_WAIT_SECONDS = 5

    def send(self, user, text, in_reply_to=None, message_type='chat'):
        if text:
{'fraction_non_alphanumeric': 0.10660954712362301, 'fraction_numerical': 0.0036719706242350062, 'mean_word_length': 2.089224952741021, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2674607', 'n_tokens_mistral': 2471, 'n_tokens_neox': 2358, 'n_words': 567}