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, })
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', )))
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', )))
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)
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)
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()
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)
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)
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)
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)