Example #1
0
 def cobed(line, weights):
     print("Cobedising. In: %s" % line)
     line = requests.get("http://cobed.gefjun.rfw.name/", params={"q": ircstrip(line.lower())}, headers={"X-Cobed-Auth": "kobun:nowbunbun"}).text.upper()
     print("           Out: %s" % line)
     line = re.sub(r"^\S+:\s*", "", line)
     weights["cobedise"] += 1
     return line
Example #2
0
def hl_match(pattern, text):
    if pattern.startswith("/") and pattern.endswith("/") and len(pattern) > 1:
        try:
            return re.match(pattern[1:-1], text, flags=re.IGNORECASE)
        except:
            return False
    else:
        return pattern.lower() in ircstrip(text.lower())
Example #3
0
        def passiveCorrector(self, server, line) -> "privmsg":
            msg = Message(line)
            nick = msg.address.nick
            if not self.dictionary.check(nick):
                self.dictionary.add(nick)
            nick = server.lower(nick)
            if msg.text and msg.text[0] in "@!.:`~/":
                return
            if msg.text.startswith("\x01ACTION") and msg.text.endswith("\x01"):
                data = self.spellcheck(msg.text[8:-1])
            else:
                data = self.spellcheck(msg.text)

            user = self.users.setdefault(nick, [0, 0])
            user[0] += len(data) if data else 0
            user[1] += len(line.split(" ")) - 3
            if user[1] > self.reset_at:
                user[0] /= self.reset_to
                user[1] /= self.reset_to

            if data:
                with sqlite3.connect(self.db) as typos:
                    for i in data:
                        typos.execute(
                            "INSERT INTO typos VALUES (?, ?, ?, ?, ?)",
                            (time.time(), nick, msg.context, self.name, i))

                threshhold_context = self.getSettings(msg.context)
                threshhold_user = self.getSettings(nick)
                if threshhold_user == threshhold_context == None:
                    return

                threshhold = min(threshhold_context,
                                 threshhold_user,
                                 key=lambda x: float("inf")
                                 if x is None else x)

                if user[1] and 1000 * user[0] / user[1] > threshhold:
                    sentence_substitute = ircstrip(msg.text)
                    if sentence_substitute.startswith(
                            "\x01ACTION") and sentence_substitute.endswith(
                                "\x01"):
                        sentence_substitute = "%s %s" % (
                            msg.address.nick, sentence_substitute[8:-1])
                    for word, sub in data.items():
                        sentence_substitute = sentence_substitute.replace(
                            word, "\x02%s\x02" %
                            sub[0] if sub else strikethrough(word))
                    server.message(
                        ("%s: " % msg.address.nick) + sentence_substitute,
                        msg.context)
                    if len(data) == 1:
                        self.last = list(data.keys())[0]
                    else:
                        self.last = None
Example #4
0
 def log(self, data):
     if self.verbosity != self.QUIET:
         # TODO: Turn this into an event callback.
         if self.verbosity & (self.FULL_MESSAGE | self.TYPE_ONLY):
             if self.verbosity & self.TYPE_ONLY:
                 output = data.split()[0]
             else:
                 output = ircstrip(data)
             sys.stdout.write("%s ← %s" % (self.servername, output))
         if self.work.qsize() and self.verbosity & self.QUEUE_STATE:
             sys.stdout.write(" ⬩ %d messages queued." % self.work.qsize())
         print()
Example #5
0
        def spellcheck(self, sentence):
            sentence = ircstrip(sentence)
            if self.isLiteral(sentence): return
            words = set(sentence.split())

            sentence = [self.stripContractions(i) for i in words if self.isWord(i)]
            errors = [i for i in sentence if i and not (self.dictionary.check(i) or self.alternate.check(i))]
            suggestions = [set(self.alternate.suggest(i)) | set(self.dictionary.suggest(i)) for i in errors]
            # reduce the suggestions
            suggestions = [{"".join(z for z in i if z.isalpha() or z in "'").lower() for i in x} for x in suggestions]
            wrong = []
            append = {}
            for i, word in enumerate(errors):
                suffixless = {word.rstrip(suffix) for suffix in self.suffixes} - {word}
                if all(self.spellcheck(i) for i in suffixless):
                    continue
                elif "".join(i for i in word if i.isalpha()).lower() not in suggestions[i]:
                
                    token = set(word) & set(self.wordsep)
                    if token:
                        token = token.pop()
                        words = word.split(token)
                        suggested = [self.spellcheck(i) for i in words]
                        suggested = [list(i.values())[0] if i else None for i in suggested]
                        if all(suggested):
                            wrong.append(word)
                        elif any(suggested):
                            if suggested[0]:
                                suggested = suggested[0]
                                suggested = [i + token + words[1] for i in suggested]
                            else:
                                suggested = suggested[1]
                                suggested = [words[0] + token + i for i in suggested]
                            append[word] = suggested
                    else:
                        # Repetition for emphasis is allowed over a threshhold
                        string = re.escape(word)
                        pattern = re.sub(r"(.+?)\1\1+", r"(\1)+", string, flags=re.IGNORECASE)
                        truncated = re.sub(r"(.+?)\1\1+", r"\1\1", word, flags=re.IGNORECASE)
                        truncated2 = re.sub(r"(.+?)\1\1+", r"\1", word, flags=re.IGNORECASE)
                        suggestions[i] |= set(self.alternate.suggest(truncated) 
                                              + self.dictionary.suggest(truncated) 
                                              + self.alternate.suggest(truncated2) 
                                              + self.dictionary.suggest(truncated2))
                        if not any(re.match(pattern, x) for x in suggestions[i]):
                            wrong.append(word)

            if wrong or append: 
                wrong = {i: self.alternate.suggest(i) for i in wrong}
                wrong.update(append)
                # wrong = {k: [i for i in v if difflib.SequenceMatcher(None, k, i).quick_ratio() > 0.6] for k, v in wrong.items()}
                return wrong # Give a dictionary of words : [suggestions]
Example #6
0
        def passiveCorrector(self, server, line) -> "privmsg":
            msg = Message(line)
            nick = msg.address.nick
            if not self.dictionary.check(nick):
                self.dictionary.add(nick)
            nick = server.lower(nick)
            if msg.text and msg.text[0] in "@!.:`~/": 
                return
            if msg.text.startswith("\x01ACTION") and msg.text.endswith("\x01"):
                data = self.spellcheck(msg.text[8:-1])
            else:
                data = self.spellcheck(msg.text)

            user = self.users.setdefault(nick, [0, 0])
            user[0] += len(data) if data else 0
            user[1] += len(line.split(" ")) - 3
            if user[1] > self.reset_at:
                user[0] /= self.reset_to
                user[1] /= self.reset_to

            if data:
                with sqlite3.connect(self.db) as typos:
                    for i in data:
                        typos.execute("INSERT INTO typos VALUES (?, ?, ?, ?, ?)", (time.time(), nick, msg.context, self.name, i))

                threshhold_context = self.getSettings(msg.context)
                threshhold_user = self.getSettings(nick)
                if threshhold_user == threshhold_context == None:
                    return
                
                threshhold = min(threshhold_context, threshhold_user, key=lambda x: float("inf") if x is None else x)

                if user[1] and 1000*user[0]/user[1] > threshhold:
                    sentence_substitute = ircstrip(msg.text)
                    if sentence_substitute.startswith("\x01ACTION") and sentence_substitute.endswith("\x01"):
                        sentence_substitute = "%s %s" % (msg.address.nick, sentence_substitute[8:-1])
                    for word, sub in data.items():
                        sentence_substitute = sentence_substitute.replace(word, "\x02%s\x02" % sub[0] if sub else strikethrough(word))
                    server.message(("%s: " % msg.address.nick) + sentence_substitute, msg.context)
                    if len(data) == 1:
                        self.last = list(data.keys())[0]
                    else:
                        self.last = None
Example #7
0
def linesize(font, text):
    return font.getsize(ircstrip(text))
Example #8
0
def strip(x):
    return "".join(i for i in ircstrip(x.strip()) 
                     if not unicodedata.category(i).startswith("C"))
Example #9
0
def strip(x):
    return "".join(i for i in ircstrip(x.strip())
                   if not unicodedata.category(i).startswith("C"))
Example #10
0
        def spellcheck(self, sentence):
            sentence = ircstrip(sentence)
            if self.isLiteral(sentence): return
            words = set(sentence.split())

            sentence = [
                self.stripContractions(i) for i in words if self.isWord(i)
            ]
            errors = [
                i for i in sentence if i
                and not (self.dictionary.check(i) or self.alternate.check(i))
            ]
            suggestions = [
                set(self.alternate.suggest(i))
                | set(self.dictionary.suggest(i)) for i in errors
            ]
            # reduce the suggestions
            suggestions = [{
                "".join(z for z in i if z.isalpha() or z in "'").lower()
                for i in x
            } for x in suggestions]
            wrong = []
            append = {}
            for i, word in enumerate(errors):
                suffixless = {word.rstrip(suffix)
                              for suffix in self.suffixes} - {word}
                if all(self.spellcheck(i) for i in suffixless):
                    continue
                elif "".join(i for i in word
                             if i.isalpha()).lower() not in suggestions[i]:

                    token = set(word) & set(self.wordsep)
                    if token:
                        token = token.pop()
                        words = word.split(token)
                        suggested = [self.spellcheck(i) for i in words]
                        suggested = [
                            list(i.values())[0] if i else None
                            for i in suggested
                        ]
                        if all(suggested):
                            wrong.append(word)
                        elif any(suggested):
                            if suggested[0]:
                                suggested = suggested[0]
                                suggested = [
                                    i + token + words[1] for i in suggested
                                ]
                            else:
                                suggested = suggested[1]
                                suggested = [
                                    words[0] + token + i for i in suggested
                                ]
                            append[word] = suggested
                    else:
                        # Repetition for emphasis is allowed over a threshhold
                        string = re.escape(word)
                        pattern = re.sub(r"(.+?)\1\1+",
                                         r"(\1)+",
                                         string,
                                         flags=re.IGNORECASE)
                        truncated = re.sub(r"(.+?)\1\1+",
                                           r"\1\1",
                                           word,
                                           flags=re.IGNORECASE)
                        truncated2 = re.sub(r"(.+?)\1\1+",
                                            r"\1",
                                            word,
                                            flags=re.IGNORECASE)
                        suggestions[i] |= set(
                            self.alternate.suggest(truncated) +
                            self.dictionary.suggest(truncated) +
                            self.alternate.suggest(truncated2) +
                            self.dictionary.suggest(truncated2))
                        if not any(
                                re.match(pattern, x) for x in suggestions[i]):
                            wrong.append(word)

            if wrong or append:
                wrong = {i: self.alternate.suggest(i) for i in wrong}
                wrong.update(append)
                # wrong = {k: [i for i in v if difflib.SequenceMatcher(None, k, i).quick_ratio() > 0.6] for k, v in wrong.items()}
                return wrong  # Give a dictionary of words : [suggestions]
Example #11
0
 def update_watchers(self, server, msg):
     ctx = server.lower(msg.context)
     # update 
     user = server.lower(msg.address.nick)
     self.active.setdefault(ctx, {})[user] = time.time()
     highlighted = []
     if ctx not in self.config["accounts"]: return
     acc = self.config["accounts"][ctx]
     if ctx in self.watchers:
         watchers = self.watchers[ctx]
         push = {"type": "note"}
         if msg.text.startswith("\x01ACTION ") and msg.text.endswith("\x01"):
             push["body"] = "* %s %s" % (msg.address.nick, ircstrip(msg.text[8:-1]))
         else:
             push["body"], push["title"] = ircstrip(msg.text), msg.address.nick
         for email in watchers:
             if any(email == target and hl_match(word, msg.text)
                    for word, target, _ in self.usersettings.get(ctx, [])):
                 hlpush = {"type": "note", "email": email, "body": push["body"]}
                 if "title" in push:
                     hlpush["title"] = "🔔 " + push["title"]
                 else:
                     hlpush["title"] = "🔔 Highlight from " + msg.address.nick
                 with self.pushlock:
                     self.skip.add(self.push(hlpush, acc["token"]))
                 highlighted.append(email)
             else:
                 push["email"] = email
                 with self.pushlock:
                     self.skip.add(self.push(push, acc["token"]))
     for word, email, when in self.usersettings.get(ctx, []):
         nick = server.lower(self.config["users"][email])
         # Parse when
         inactive_match = re.match(r"(\S+(?:,\s*\S+)* )?inactive( \d+)?", when)
         offline_match = re.match(r"(\S+(?:,\s*\S+)* )?offline", when)
         if inactive_match:
             who, timeout = inactive_match.groups()
             if who is None: who = [nick]
             else: who = re.split(r",\s*", who.strip())
             if timeout is None:
                 timeout = "15"
             timeout = 60 * int(timeout.strip())
             when = "inactive"
         elif offline_match:
             who, = offline_match.groups()
             if who is None: who = [nick]
             else: who = re.split(r",\s*", who)
             when = "offline"
         if email not in highlighted and hl_match(word, msg.text):
             if (when == "always"
                 or (when == "offline" and server.isIn(ctx, server.channels) and not any(server.isIn(i, server.channels[ctx])
                                                                                         for i in who))
                 or (when =="inactive" and all(not server.isIn(i, self.active[ctx]) 
                                               or time.time() - self.active[ctx][self.lower(i)] >= timeout
                                               for i in who))):
                 push = {"type": "note", "title": "🔔 Highlight from %s" % msg.address.nick, "body": ircstrip(msg.text), "email":email}
                 if msg.text.startswith("\x01ACTION ") and msg.text.endswith("\x01"):
                     push["body"] = "* %s %s" % (msg.address.nick, ircstrip(msg.text[8:-1]))
                 with self.pushlock:
                     self.skip.add(self.push(push, acc["token"]))
             highlighted.append(email)