Example #1
0
File: memo.py Project: shoosen/ibid
    def messages_for(self, event, who, source):
        identities = get_identities(event)

        if not source:
            source = event.source
        else:
            source = source.lower()

        # Join on column x isn't possible in SQLAlchemy 0.4:
        identities_to = event.session.query(Identity) \
                .filter_by(source=source, identity=who).all()

        identities_to = [identity.id for identity in identities_to]

        memos = event.session.query(Memo) \
                .filter_by(delivered=False) \
                .filter(Memo.from_id.in_(identities)) \
                .filter(Memo.to_id.in_(identities_to)) \
                .order_by(Memo.time.asc()).all()

        if memos:
            event.addresponse(u'Pending: ' + u', '.join(
                '%i: %s (%s)' % (i + 1, memo.memo, format_date(memo.time))
                for i, memo in enumerate(memos)
            ))
        else:
            event.addresponse(u'Sorry, all your memos to %(who)s on %(source)s '
                              u'are already delivered', {
                'who': who,
                'source': source,
            })
Example #2
0
    def messages_for(self, event, who, source):
        identities = get_identities(event)

        if not source:
            source = event.source
        else:
            source = source.lower()

        # Join on column x isn't possible in SQLAlchemy 0.4:
        identities_to = event.session.query(Identity) \
                .filter_by(source=source, identity=who).all()

        identities_to = [identity.id for identity in identities_to]

        memos = event.session.query(Memo) \
                .filter_by(delivered=False) \
                .filter(Memo.from_id.in_(identities)) \
                .filter(Memo.to_id.in_(identities_to)) \
                .order_by(Memo.time.asc()).all()

        if memos:
            event.addresponse(u'Pending: ' + u', '.join(
                '%i: %s (%s)' % (i + 1, memo.memo, format_date(memo.time))
                for i, memo in enumerate(memos)
            ))
        else:
            event.addresponse(u'Sorry, all your memos to %(who)s on %(source)s '
                              u'are already delivered', {
                'who': who,
                'source': source,
            })
Example #3
0
    def set_factoid(self, event, correction, name, addition1, verb1, verb2,
                    addition2, value):
        verb = verb1 or verb2
        addition = addition1 or addition2

        name = strip_name(name)

        if name == u'':
            event.addresponse(u"Sorry, I'm not interested in empty factoids")
            return

        if name.lower() in self.interrogatives:
            event.addresponse(
                choice((
                    u"I'm afraid I have no idea",
                    u"Not a clue, sorry",
                    u"Erk, dunno",
                )))
            return

        factoid = event.session.query(Factoid).join(Factoid.names)\
                .filter(FactoidName.name==escape_name(name)).first()
        if factoid:
            if correction:
                identities = get_identities(event)
                if not auth_responses(event, u'factoidadmin') and len(
                        filter(lambda x: x.identity_id not in identities,
                               factoid.values)) > 0:
                    return
                for fvalue in factoid.values:
                    event.session.delete(fvalue)
            elif not addition:
                event.addresponse(u'I already know stuff about %s', name)
                return
        else:
            factoid = Factoid()
            fname = FactoidName(unicode(name), event.identity)
            factoid.names.append(fname)
            event.session.add(factoid)
            event.session.flush()
            log.info(u"Creating factoid %s with name '%s' by %s", factoid.id,
                     fname.name, event.identity)

        if not reply_re.match(value) and not action_re.match(value):
            value = '%s %s' % (verb, value)
        fvalue = FactoidValue(unicode(value), event.identity)
        factoid.values.append(fvalue)
        event.session.add(factoid)
        event.session.commit()
        self.last_set_factoid = factoid.names[0].name
        log.info(u"Added value '%s' to factoid %s (%s) by %s/%s (%s)",
                 fvalue.value, factoid.id, factoid.names[0].name,
                 event.account, event.identity, event.sender['connection'])
        event.addresponse(
            choice((
                u'If you say so',
                u'One learns a new thing every day',
                u"I'll remember that",
                u'Got it',
            )))
Example #4
0
    def set_factoid(self, event, correction, name, addition1, verb1, verb2, addition2, value):
        verb = verb1 or verb2
        addition = addition1 or addition2

        name = strip_name(name)

        if name == u'':
            event.addresponse(u"Sorry, I'm not interested in empty factoids")
            return

        if name.lower() in self.interrogatives:
            event.addresponse(choice((
                u"I'm afraid I have no idea",
                u"Not a clue, sorry",
                u"Erk, dunno",
            )))
            return

        factoid = event.session.query(Factoid).join(Factoid.names)\
                .filter(FactoidName.name==escape_name(name)).first()
        if factoid:
            if correction:
                identities = get_identities(event)
                if not auth_responses(event, u'factoidadmin') and len(filter(lambda x: x.identity_id not in identities, factoid.values)) > 0:
                    return
                for fvalue in factoid.values:
                    event.session.delete(fvalue)
            elif not addition:
                event.addresponse(u'I already know stuff about %s', name)
                return
        else:
            factoid = Factoid()
            fname = FactoidName(unicode(name), event.identity)
            factoid.names.append(fname)
            event.session.save_or_update(factoid)
            event.session.flush()
            log.info(u"Creating factoid %s with name '%s' by %s", factoid.id, fname.name, event.identity)

        if not reply_re.match(value) and not action_re.match(value):
            value = '%s %s' % (verb, value)
        fvalue = FactoidValue(unicode(value), event.identity)
        factoid.values.append(fvalue)
        event.session.save_or_update(factoid)
        event.session.commit()
        self.last_set_factoid=factoid.names[0].name
        log.info(u"Added value '%s' to factoid %s (%s) by %s/%s (%s)",
                fvalue.value, factoid.id, factoid.names[0].name,
                event.account, event.identity, event.sender['connection'])
        event.addresponse(choice((
                u'If you say so',
                u'One learns a new thing every day',
                u"I'll remember that",
                u'Got it',
            )))
Example #5
0
    def append(self, event, name, number, pattern, is_regex, suffix):
        name = strip_name(name)
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True,
                               literal=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(
                    u"I don't know about any %(name)s matching %(pattern)s", {
                        'name': name,
                        'pattern': pattern,
                    })
            else:
                factoids = get_factoid(event.session,
                                       name,
                                       None,
                                       pattern,
                                       is_regex,
                                       all=True)
                if factoids:
                    event.addresponse(
                        u"I only know %(number)d things about %(name)s", {
                            u'number': len(factoids),
                            u'name': name,
                        })
                else:
                    event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1 and number is None:
            event.addresponse(
                u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            oldvalue = factoid[2].value
            factoid[2].value += suffix
            event.session.add(factoid[2])
            event.session.commit()

            log.info(
                u"Appended '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                suffix, factoid[2].id, oldvalue, factoid[0].id,
                factoid[0].names[0].name, event.account, event.identity,
                event.sender['connection'])
            event.addresponse(True)
Example #6
0
    def append(self, event, name, number, pattern, is_regex, suffix):
        name = strip_name(name)
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True, literal=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(u"I don't know about any %(name)s matching %(pattern)s", {
                    'name': name,
                    'pattern': pattern,
                })
            else:
                factoids = get_factoid(event.session, name, None, pattern, is_regex, all=True)
                if factoids:
                    event.addresponse(u"I only know %(number)d things about %(name)s", {
                        u'number': len(factoids),
                        u'name': name,
                    })
                else:
                    event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1 and number is None:
            event.addresponse(u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            oldvalue = factoid[2].value
            factoid[2].value += suffix
            event.session.add(factoid[2])
            event.session.commit()

            log.info(u"Appended '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                    suffix, factoid[2].id, oldvalue, factoid[0].id,
                    factoid[0].names[0].name, event.account, event.identity,
                    event.sender['connection'])
            event.addresponse(True)
Example #7
0
File: memo.py Project: shoosen/ibid
def get_memos(event, delivered=False):
    identities = get_identities(event)
    return event.session.query(Memo) \
            .filter_by(delivered=delivered) \
            .filter(Memo.to_id.in_(identities)) \
            .order_by(Memo.time.asc()).all()
Example #8
0
def get_memos(event, delivered=False):
    identities = get_identities(event)
    return event.session.query(Memo) \
            .filter_by(delivered=delivered) \
            .filter(Memo.to_id.in_(identities)) \
            .order_by(Memo.time.asc()).all()
Example #9
0
    def modify(self, event, name, number, pattern, is_regex, operation, sep):
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(u"I don't know about any %(name)s matching %(pattern)s", {
                    'name': name,
                    'pattern': pattern,
                })
            else:
                event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1:
            event.addresponse(u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            # Not very pythonistic, but escaping is a nightmare.
            separator = sep
            parts = [[]]
            pos = 0
            while pos < len(operation):
                char = operation[pos]
                if char == separator:
                    parts.append([])
                elif char == u"\\":
                    if pos < len(operation) - 1:
                        if operation[pos+1] == u"\\":
                            parts[-1].append(u"\\")
                            pos += 1
                        elif operation[pos+1] == separator:
                            parts[-1].append(separator)
                            pos += 1
                        else:
                            parts[-1].append(u"\\")
                    else:
                        parts[-1].append(u"\\")
                else:
                    parts[-1].append(char)
                pos += 1

            parts = [u"".join(x) for x in parts]

            if len(parts) != 4:
                event.addresponse(u"That operation makes no sense. Try something like s/foo/bar/")
                return

            oldvalue = factoid[2].value
            op, search, replace, flags = parts
            flags = flags.lower()
            if op == "s":
                if "r" not in flags:
                    plain_search = search
                    search = re.escape(search)
                    replace = replace.replace('\\', '\\\\')
                if "i" in flags:
                    search += "(?i)"
                try:
                    if "r" not in flags and not re.search(search, oldvalue):
                        event.addresponse(u"I couldn't find '%(terms)s' in "
                                          u"'%(oldvalue)s'. If that was a "
                                          u"proper regular expression, append "
                                          u"the 'r' flag", {
                                                'terms': plain_search,
                                                'oldvalue': oldvalue,
                                            })
                        return

                    factoid[2].value = re.sub(search, replace, oldvalue, int("g" not in flags))
                except:
                    event.addresponse(u"That operation makes no sense. Try something like s/foo/bar/")
                    return

            elif op == "y":
                if len(search) != len(replace):
                    event.addresponse(u"That operation makes no sense. The source and destination must be the same length")
                    return
                try:
                    table = dict((ord(x), ord(y)) for x, y in zip(search, replace))
                    factoid[2].value = oldvalue.translate(table)

                except:
                    event.addresponse(u"That operation makes no sense. Try something like y/abcdef/ABCDEF/")
                    return

            event.session.save_or_update(factoid[2])
            event.session.commit()

            log.info(u"Applying '%s' to value %s of factoid %s (%s) by %s/%s (%s)",
                    operation, factoid[2].id, factoid[0].id, oldvalue, event.account, event.identity, event.sender['connection'])

            event.addresponse(True)
Example #10
0
    def forget(self, event, name, number, pattern, is_regex):
        factoids = get_factoid(event.session, name, number, pattern, is_regex, all=True, literal=True)
        if factoids:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = event.session.query(Factoid).get(factoids[0][0].id)

            if len(factoids) > 1 and pattern is not None:
                event.addresponse(u'Pattern matches multiple factoids, please be more specific')
                return

            if number or pattern:
                if factoids[0][2].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidValue).filter_by(factoid_id=factoid.id).count() == 1:
                    if len(filter(lambda x: x.identity_id not in identities, factoid.names)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)",
                            id, name, event.account, event.identity, event.sender['connection'])
                else:
                    id = factoids[0][2].id
                    event.session.delete(factoids[0][2])
                    event.session.commit()
                    log.info(u"Deleted value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                            id, factoids[0][2].value, factoid.id, name,
                            event.account, event.identity, event.sender['connection'])

            else:
                if factoids[0][1].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidName).filter_by(factoid_id=factoid.id).count() == 1:
                    if len(filter(lambda x: x.identity_id not in identities, factoid.values)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)",
                            id, name, event.account, event.identity,
                            event.sender['connection'])
                else:
                    id = factoids[0][1].id
                    event.session.delete(factoids[0][1])
                    event.session.commit()
                    log.info(u"Deleted name %s (%s) of factoid %s (%s) by %s/%s (%s)",
                            id, factoids[0][1].name, factoid.id, factoids[0][0].names[0].name,
                            event.account, event.identity, event.sender['connection'])

            event.addresponse(True)
        else:
            factoids = get_factoid(event.session, name, None, pattern, is_regex, all=True, literal=True)
            if factoids:
                event.addresponse(u"I only know %(number)d things about %(name)s", {
                    u'number': len(factoids),
                    u'name': name,
                })
            else:
                event.addresponse(u"I didn't know about %s anyway", name)
Example #11
0
    def modify(self, event, name, number, pattern, is_regex, operation, sep):
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True)
        if len(factoids) == 0:
            if pattern:
                event.addresponse(
                    u"I don't know about any %(name)s matching %(pattern)s", {
                        'name': name,
                        'pattern': pattern,
                    })
            else:
                event.addresponse(u"I don't know about %s", name)
        elif len(factoids) > 1:
            event.addresponse(
                u"Pattern matches multiple factoids, please be more specific")
        else:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = factoids[0]

            if factoid[2].identity_id not in identities and not factoidadmin:
                return

            # Not very pythonistic, but escaping is a nightmare.
            separator = sep
            parts = [[]]
            pos = 0
            while pos < len(operation):
                char = operation[pos]
                if char == separator:
                    parts.append([])
                elif char == u"\\":
                    if pos < len(operation) - 1:
                        if operation[pos + 1] == u"\\":
                            parts[-1].append(u"\\")
                            pos += 1
                        elif operation[pos + 1] == separator:
                            parts[-1].append(separator)
                            pos += 1
                        else:
                            parts[-1].append(u"\\")
                    else:
                        parts[-1].append(u"\\")
                else:
                    parts[-1].append(char)
                pos += 1

            parts = [u"".join(x) for x in parts]

            if len(parts) != 4:
                event.addresponse(
                    u"That operation makes no sense. Try something like s/foo/bar/"
                )
                return

            oldvalue = factoid[2].value
            op, search, replace, flags = parts
            flags = flags.lower()
            if op == "s":
                if "r" not in flags:
                    plain_search = search
                    search = re.escape(search)
                    replace = replace.replace('\\', '\\\\')
                if "i" in flags:
                    search += "(?i)"
                try:
                    if "r" not in flags and not re.search(search, oldvalue):
                        event.addresponse(
                            u"I couldn't find '%(terms)s' in "
                            u"'%(oldvalue)s'. If that was a "
                            u"proper regular expression, append "
                            u"the 'r' flag", {
                                'terms': plain_search,
                                'oldvalue': oldvalue,
                            })
                        return

                    factoid[2].value = re.sub(search, replace, oldvalue,
                                              int("g" not in flags))
                except:
                    event.addresponse(
                        u"That operation makes no sense. Try something like s/foo/bar/"
                    )
                    return

            elif op == "y":
                if len(search) != len(replace):
                    event.addresponse(
                        u"That operation makes no sense. The source and destination must be the same length"
                    )
                    return
                try:
                    table = dict(
                        (ord(x), ord(y)) for x, y in zip(search, replace))
                    factoid[2].value = oldvalue.translate(table)

                except:
                    event.addresponse(
                        u"That operation makes no sense. Try something like y/abcdef/ABCDEF/"
                    )
                    return

            event.session.add(factoid[2])
            event.session.commit()

            log.info(
                u"Applying '%s' to value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                operation, factoid[2].id, oldvalue, factoid[0].id,
                factoid[0].names[0].name, event.account, event.identity,
                event.sender['connection'])

            event.addresponse(True)
Example #12
0
    def forget(self, event, name, number, pattern, is_regex):
        factoids = get_factoid(event.session,
                               name,
                               number,
                               pattern,
                               is_regex,
                               all=True,
                               literal=True)
        if factoids:
            factoidadmin = auth_responses(event, u'factoidadmin')
            identities = get_identities(event)
            factoid = event.session.query(Factoid).get(factoids[0][0].id)

            if len(factoids) > 1 and pattern is not None:
                event.addresponse(
                    u'Pattern matches multiple factoids, please be more specific'
                )
                return

            if number or pattern:
                if factoids[0][
                        2].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidValue).filter_by(
                        factoid_id=factoid.id).count() == 1:
                    if len(
                            filter(lambda x: x.identity_id not in identities,
                                   factoid.names)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)", id,
                             name, event.account, event.identity,
                             event.sender['connection'])
                else:
                    id = factoids[0][2].id
                    event.session.delete(factoids[0][2])
                    event.session.commit()
                    log.info(
                        u"Deleted value %s (%s) of factoid %s (%s) by %s/%s (%s)",
                        id, factoids[0][2].value, factoid.id, name,
                        event.account, event.identity,
                        event.sender['connection'])

            else:
                if factoids[0][
                        1].identity_id not in identities and not factoidadmin:
                    return

                if event.session.query(FactoidName).filter_by(
                        factoid_id=factoid.id).count() == 1:
                    if len(
                            filter(lambda x: x.identity_id not in identities,
                                   factoid.values)) > 0 and not factoidadmin:
                        return
                    id = factoid.id
                    event.session.delete(factoid)
                    event.session.commit()
                    log.info(u"Deleted factoid %s (%s) by %s/%s (%s)", id,
                             name, event.account, event.identity,
                             event.sender['connection'])
                else:
                    id = factoids[0][1].id
                    event.session.delete(factoids[0][1])
                    event.session.commit()
                    log.info(
                        u"Deleted name %s (%s) of factoid %s (%s) by %s/%s (%s)",
                        id, factoids[0][1].name, factoid.id,
                        factoids[0][0].names[0].name, event.account,
                        event.identity, event.sender['connection'])

            event.addresponse(True)
        else:
            factoids = get_factoid(event.session,
                                   name,
                                   None,
                                   pattern,
                                   is_regex,
                                   all=True,
                                   literal=True)
            if factoids:
                event.addresponse(
                    u"I only know %(number)d things about %(name)s", {
                        u'number': len(factoids),
                        u'name': name,
                    })
            else:
                event.addresponse(u"I didn't know about %s anyway", name)