def find_fact(bot, text, exact=False, db=None): lang_search = bot.memory['ratfacts']['lang'] fact = Fact.find(db, name=text, lang=lang_search[0] if exact else lang_search) if fact: return fact if '-' in text: name, lang = text.rsplit('-', 1) if not exact: lang = [lang] + lang_search return Fact.find(db, name=name, lang=lang) return None
def cmd_fact_edit(bot, trigger): if not option: bot.reply("Missing fact.") return NOLIMIT if '-' not in option: bot.reply( "Fact must include a language specifier. (Perhaps you meant '{name}-{lang}'?)" .format(name=option, lang=bot.memory['ratfacts']['lang'][0])) return NOLIMIT name, lang = option.rsplit('-', 1) if command in ('add', 'set'): message = extra.strip() if extra else None if not message: bot.reply("Can't add a blank fact.") return NOLIMIT fact = db.merge( Fact(name=name, lang=lang, message=extra, author=str(trigger.nick))) is_new = not inspect(fact).persistent db.commit() bot.reply(("Added " if is_new else "Updated ") + format_fact(fact)) return NOLIMIT fact = Fact.find(db, name=name, lang=lang) if fact: db.delete(fact) db.commit() bot.reply("Deleted " + format_fact(fact)) else: bot.reply("No such fact.") return NOLIMIT
def cmd_fact_edit(bot, trigger): if not option: bot.reply("Missing fact.") return NOLIMIT if '-' not in option: bot.reply( "Fact must include a language specifier. (Perhaps you meant '{name}-{lang}'?)" .format(name=option, lang=bot.memory['ratfacts']['lang'][0]) ) return NOLIMIT name, lang = option.rsplit('-', 1) if command in ('add', 'set'): message = extra.strip() if extra else None if not message: bot.reply("Can't add a blank fact.") return NOLIMIT fact = db.merge(Fact(name=name, lang=lang, message=extra, author=str(trigger.nick))) is_new = not inspect(fact).persistent db.commit() bot.reply(("Added " if is_new else "Updated ") + format_fact(fact)) return NOLIMIT fact = Fact.find(db, name=name, lang=lang) if fact: db.delete(fact) db.commit() bot.reply("Deleted " + format_fact(fact)) else: bot.reply("No such fact.") return NOLIMIT
def cmd_fact(bot, trigger, db=None): """ Lists known facts, list details on a fact, or rescans the fact database. !fact - Lists all known facts !fact FACT [full] - Shows detailed stats on the specified fact. 'full' dumps all translations to a PM. !fact LANGUAGE [full] - Shows detailed stats on the specified language. 'full' dumps all facts to a PM. The following commands require privileges: !fact import [-f] - Reimports JSON data. -f overwrites existing rows. !fact full - Dumps all facts, all languages to a PM. !fact add <id> <text> - Creates a new fact or updates an existing one. <id> must be of the format <factname>-<lang> Aliases: set !fact del <id> <text> - Deletes a fact. <id> must be of the format <factname>-<lang> Aliases: delete remove """ pm = functools.partial(bot.say, destination=trigger.nick) parts = re.split(r'\s+', trigger.group(2), maxsplit=2) if trigger.group(2) else None command = parts.pop(0).lower() if parts else None option = parts.pop(0).lower() if parts else None extra = parts[0] if parts else None access = 0 if command in('full', 'rescan', 'import', 'add', 'del', 'delete', 'set', 'remove'): access = ratlib.sopel.best_channel_mode(bot, trigger.nick) if not command: # List known facts. unique_facts = list(Fact.unique_names(db)) if not unique_facts: return bot.reply("Like Jon Snow, I know nothing. (Or there's a problem with the fact database.)") return bot.say("{} known fact(s): {}".format(len(unique_facts), ", ".join(unique_facts))) if command == 'import': if access & (HALFOP | OP): import_facts(bot, merge=(option == '-f')) return bot.say("Facts imported.") return bot.reply("Not authorized.") if command == 'full': if not (access & (HALFOP | OP)): return bot.reply("Not authorized.") if not trigger.is_privmsg: bot.reply("Messaging you the complete fact database.") pm("Language search order is {}".format(", ".join(bot.memory['ratfacts']['lang']))) for fact in Fact.findall(db): pm(format_fact(fact)) pm("-- End of list --") return NOLIMIT if command in ('add', 'set', 'del', 'delete', 'remove'): if not (access & (HALFOP | OP)): return bot.reply("Not authorized.") if not option: bot.reply("Missing fact.") return NOLIMIT if '-' not in option: bot.reply( "Fact must include a language specifier. (Perhaps you meant '{name}-{lang}'?)" .format(name=option, lang=bot.memory['ratfacts']['lang'][0]) ) return NOLIMIT name, lang = option.rsplit('-', 1) if command in('add', 'set'): message = extra.strip() if extra else None if not message: bot.reply("Can't add a blank fact.") return NOLIMIT fact = db.merge(Fact(name=name, lang=lang, message=extra, author=str(trigger.nick))) is_new = not inspect(fact).persistent db.commit() bot.reply(("Added " if is_new else "Updated ") + format_fact(fact)) return NOLIMIT fact = Fact.find(db, name=name, lang=lang) if fact: db.delete(fact) db.commit() bot.reply("Deleted " + format_fact(fact)) else: bot.reply("No such fact.") return NOLIMIT def _translation_stats(exists, missing, s='translation', p='translations'): if exists: exists = "{count} {word} ({names})".format( count=len(exists), word=s if len(exists) == 1 else p, names=", ".join(sorted(exists)) ) else: exists = "no " + p if missing: missing = "missing {count} ({names})".format(count=len(missing), names=", ".join(sorted(missing))) else: missing = "none missing" return exists + ", " + missing # See if it's the name of a fact or a lang full = option == 'full' for attr, opposite, name, opposite_name_s, opposite_name_p in [ ('name', 'lang', 'fact', 'translation', 'translations'), ('lang', 'name', 'language', 'fact', 'facts') ]: if not db.query(Fact.query(db, order_by=False, **{attr: command}).exists()).scalar(): continue sq = Fact.unique_query(db, field=getattr(Fact, opposite), order_by=False).subquery() sq_opp = getattr(sq.c, opposite) fact_opp = getattr(Fact, opposite) fact_col = getattr(Fact, attr) query = ( db.query(Fact, sq_opp) .select_from(sq.outerjoin(Fact, (sq_opp == fact_opp) & (fact_col == command))) .order_by(Fact.message.is_(None), sq_opp) ) exists = set() missing = set() if full: if not trigger.is_privmsg: bot.reply("Messaging you what I know about {} '{}'".format(name, command)) pm("Fact search for {} '{}'".format(name, command)) for fact, key in query: if fact and full: pm(format_fact(fact)) (exists if fact else missing).add(key) summary = ( "{} '{}': ".format(name.title(), command) + _translation_stats(exists, missing, s=opposite_name_s, p=opposite_name_p) ) if full: pm(summary) return NOLIMIT else: bot.say(summary) return NOLIMIT bot.reply("'{}' is not a known fact, language, or subcommand".format(command)) return NOLIMIT