From f2e3790a642a0c01465968d69a35958214891788 Mon Sep 17 00:00:00 2001 From: Edward Powell Date: Mon, 15 Dec 2014 19:42:05 -0500 Subject: [PATCH] Revert "Migrate modules to new db" This reverts commit f263963f86ef22f5fff29a594e0a626d6fc31e0c. --- willie/modules/adminchannel.py | 19 ++++-- willie/modules/clock.py | 105 ++++++++++++++++++------------- willie/modules/rss.py | 110 +++++++++++++++++++++++++-------- willie/modules/safety.py | 11 +++- willie/modules/weather.py | 45 +++++++++----- willie/tools.py | 29 +++++---- 6 files changed, 208 insertions(+), 111 deletions(-) diff --git a/willie/modules/adminchannel.py b/willie/modules/adminchannel.py index 82938974f0..d90e9c7383 100644 --- a/willie/modules/adminchannel.py +++ b/willie/modules/adminchannel.py @@ -315,7 +315,8 @@ def topic(bot, trigger): narg = 1 mask = None - mask = bot.db.get_channel_value(channel, 'topic_mask') + if bot.db and channel in bot.db.preferences: + mask = bot.db.preferences.get(channel, 'topic_mask') mask = mask or default_mask(trigger) mask = mask.replace('%s', '{}') narg = len(re.findall('{}', mask)) @@ -342,8 +343,11 @@ def set_mask(bot, trigger): """ if bot.privileges[trigger.sender][trigger.nick] < OP: return - bot.db.set_channel_value(trigger.sender, 'topic_mask', trigger.group(2)) - bot.say("Gotcha, " + trigger.nick) + if not bot.db: + bot.say("I'm afraid I can't do that.") + else: + bot.db.preferences.update(trigger.sender.lower(), {'topic_mask': trigger.group(2)}) + bot.say("Gotcha, " + trigger.nick) @commands('showmask') @@ -351,6 +355,9 @@ def show_mask(bot, trigger): """Show the topic mask for the current channel.""" if bot.privileges[trigger.sender][trigger.nick] < OP: return - mask = bot.db.get_channel_value(trigger.sender, 'topic_mask') - mask = mask or default_mask(trigger) - bot.say(mask) + if not bot.db: + bot.say("I'm afraid I can't do that.") + elif trigger.sender.lower() in bot.db.preferences: + bot.say(bot.db.preferences.get(trigger.sender.lower(), 'topic_mask')) + else: + bot.say(default_mask(trigger)) diff --git a/willie/modules/clock.py b/willie/modules/clock.py index 0e1e1302de..3e8540fc5c 100644 --- a/willie/modules/clock.py +++ b/willie/modules/clock.py @@ -26,6 +26,14 @@ def configure(config): 'Preferred time format (http://strftime.net)', '%F - %T%Z') +def setup(bot): + #Having a db means pref's exists. Later, we can just use `if bot.db`. + if bot.db and not bot.db.preferences.has_columns('tz'): + bot.db.preferences.add_columns(['tz']) + if bot.db and not bot.db.preferences.has_columns('time_format'): + bot.db.preferences.add_columns(['time_format']) + + @commands('t', 'time') @example('.t America/New_York') def f_time(bot, trigger): @@ -51,6 +59,8 @@ def update_user(bot, trigger): """ if not pytz: bot.reply("Sorry, I don't have timezone support installed.") + elif not bot.db: + bot.reply("I can't remember that; I don't have a database.") else: tz = trigger.group(2) if not tz: @@ -62,7 +72,7 @@ def update_user(bot, trigger): "http://dft.ba/-tz") return - bot.db.set_nick_value(trigger.nick, 'timezone', tz) + bot.db.preferences.update(trigger.nick, {'tz': tz}) if len(tz) < 7: bot.say("Okay, {}, but you should use one from http://dft.ba/-tz " "if you use DST.".format(trigger.nick)) @@ -77,30 +87,33 @@ def update_user_format(bot, trigger): Sets your preferred format for time. Uses the standard strftime format. You can use http://strftime.net or your favorite search engine to learn more. """ - tformat = trigger.group(2) - if not tformat: - bot.reply("What format do you want me to use? Try using" - " http://strftime.net to make one.") - - tz = get_timezone(bot.db, bot.config, None, None, trigger.sender) - - # Get old format as back-up - old_format = bot.db.get_nick_value(trigger.nick, 'time_format') - - # Save the new format in the database so we can test it. - bot.db.set_nick_value(trigger.nick, 'time_format', tformat) - - try: - timef = format_time(db=bot.db, zone=tz, nick=trigger.nick) - except: - bot.reply("That format doesn't work. Try using" - " http://strftime.net to make one.") - # New format doesn't work. Revert save in database. - bot.db.set_nick_value(trigger.nick, 'time_format', old_format) - return - bot.reply("Got it. Your time will now appear as %s. (If the " - "timezone is wrong, you might try the settz command)" - % timef) + if bot.db: + tformat = trigger.group(2) + if not tformat: + bot.reply("What format do you want me to use? Try using" + " http://strftime.net to make one.") + return + + tz = get_timezone(bot.db, bot.config, None, None, trigger.sender) + + # Get old format as back-up + old_format = bot.db.preferences.get(trigger.nick, 'time_format') + + # Save the new format in the database so we can test it. + bot.db.preferences.update(trigger.nick, {'time_format': tformat}) + + try: + timef = format_time(db=bot.db, zone=tz, nick=trigger.nick) + except: + bot.reply("That format doesn't work. Try using" + " http://strftime.net to make one.") + # New format doesn't work. Revert save in database. + bot.db.preferences.update(trigger.nick, {'time_format': old_format}) + return + bot.reply("Got it. Your time will now appear as {}. (If the timezone " + "is wrong, you might try the settz command)".format(timef)) + else: + bot.reply("I can't remember that; I don't have a database.") @commands('channeltz') @@ -113,6 +126,8 @@ def update_channel(bot, trigger): return elif not pytz: bot.reply("Sorry, I don't have timezone support installed.") + elif not bot.db: + bot.reply("I can't remember that; I don't have a database.") else: tz = trigger.group(2) if not tz: @@ -124,7 +139,7 @@ def update_channel(bot, trigger): "http://dft.ba/-tz") return - bot.db.set_channel_value(trigger.sender, 'timezone', tz) + bot.db.preferences.update(trigger.sender, {'tz': tz}) if len(tz) < 7: bot.say("Okay, {}, but you should use one from http://dft.ba/-tz " "if you use DST.".format(trigger.nick)) @@ -142,21 +157,23 @@ def update_channel_format(bot, trigger): """ if bot.privileges[trigger.sender][trigger.nick] < OP: return - - tformat = trigger.group(2) - if not tformat: - bot.reply("What format do you want me to use? Try using" - " http://strftime.net to make one.") - - tz = get_timezone(bot.db, bot.config, None, None, trigger.sender) - try: - timef = format_time(zone=tz) - except: - bot.reply("That format doesn't work. Try using" - " http://strftime.net to make one.") - return - bot.db.set_channel_value(trigger.sender, 'time_format', tformat) - bot.reply("Got it. Times in this channel will now appear as %s " - "unless a user has their own format set. (If the timezone" - " is wrong, you might try the settz and channeltz " - "commands)" % timef) + elif not bot.db: + bot.reply("I can't remember that; I don't have a database.") + else: + tformat = trigger.group(2) + if not tformat: + bot.reply("What format do you want me to use? Try using" + " http://strftime.net to make one.") + + tz = get_timezone(bot.db, bot.config, None, None, trigger.sender) + try: + timef = format_time(zone=tz) + except: + bot.reply("That format doesn't work. Try using" + " http://strftime.net to make one.") + return + bot.db.preferences.update(trigger.sender, {'time_format': tformat}) + bot.reply("Got it. Times in this channel will now appear as {} " + "unless a user has their own format set. (If the timezone" + " is wrong, you might try the settz and channeltz " + "commands)".format(timef)) diff --git a/willie/modules/rss.py b/willie/modules/rss.py index fda54d2ce0..93e991a3c3 100644 --- a/willie/modules/rss.py +++ b/willie/modules/rss.py @@ -29,6 +29,8 @@ def setup(bot): bot.memory['rss_manager'] = RSSManager(bot) + if not bot.db: + raise ConfigurationError("Database not set up, or unavailable.") conn = bot.db.connect() c = conn.cursor() @@ -38,14 +40,31 @@ def setup(bot): c.execute('SELECT * FROM rss_feeds') except StandardError: create_table(bot, c) + migrate_from_old_tables(bot, c) + + # These tables are no longer used, but lets not delete them right away. + # c.execute('DROP TABLE IF EXISTS rss') + # c.execute('DROP TABLE IF EXISTS recent') + + conn.commit() + + # The modified column was added on 2013-07-21. + try: + c.execute('SELECT modified FROM rss_feeds') + except StandardError: + c.execute('ALTER TABLE rss_feeds ADD modified TEXT') conn.commit() + conn.close() def create_table(bot, c): # MySQL needs to only compare on the first n characters of a TEXT field # but SQLite won't accept the syntax needed to make it do it. - primary_key = '(channel, feed_name)' + if bot.db.type == 'mysql': + primary_key = '(channel(254), feed_name(254))' + else: + primary_key = '(channel, feed_name)' c.execute('''CREATE TABLE IF NOT EXISTS rss_feeds ( channel TEXT, @@ -63,6 +82,41 @@ def create_table(bot, c): )'''.format(primary_key)) +def migrate_from_old_tables(bot, c): + sub = bot.db.substitution + + try: + c.execute('SELECT * FROM rss') + oldfeeds = c.fetchall() + except StandardError: + oldfeeds = [] + + for feed in oldfeeds: + channel, site_name, site_url, fg, bg = feed + + # get recent article if possible + try: + c.execute(''' + SELECT article_title, article_url FROM recent + WHERE channel = {0} AND site_name = {0} + '''.format(sub), (channel, site_name)) + article_title, article_url = c.fetchone() + except (StandardError, TypeError): + article_title = article_url = None + + # add feed to new table + if article_url: + c.execute(''' + INSERT INTO rss_feeds (channel, feed_name, feed_url, fg, bg, article_title, article_url) + VALUES ({0}, {0}, {0}, {0}, {0}, {0}, {0}) + '''.format(sub), (channel, site_name, site_url, fg, bg, article_title, article_url)) + else: + c.execute(''' + INSERT INTO rss_feeds (channel, feed_name, feed_url, fg, bg) + VALUES ({0}, {0}, {0}, {0}, {0}) + '''.format(sub), (channel, site_name, site_url, fg, bg)) + + def colour_text(text, fg=None, bg=None): """Given some text and fore/back colours, return a coloured text string.""" if fg is None: @@ -81,6 +135,7 @@ def manage_rss(bot, trigger): class RSSManager: def __init__(self, bot): self.running = True + self.sub = bot.db.substitution # get a list of all methods in this class that start with _rss_ self.actions = sorted(method[5:] for method in dir(self) if method[:5] == '_rss_') @@ -149,19 +204,19 @@ def _rss_add(self, bot, trigger, c): bg = int(match.group(5)) % 16 if match.group(5) else None c.execute(''' - SELECT * FROM rss_feeds WHERE channel = ? AND feed_name = ? - ''', (channel, feed_name)) + SELECT * FROM rss_feeds WHERE channel = {0} AND feed_name = {0} + '''.format(self.sub), (channel, feed_name)) if not c.fetchone(): c.execute(''' INSERT INTO rss_feeds (channel, feed_name, feed_url, fg, bg) - VALUES (?, ?, ?, ?, ?) - ''', (channel, feed_name, feed_url, fg, bg)) + VALUES ({0}, {0}, {0}, {0}, {0}) + '''.format(self.sub), (channel, feed_name, feed_url, fg, bg)) bot.reply("Successfully added the feed to the channel.") else: c.execute(''' - UPDATE rss_feeds SET feed_url = ?, fg = ?, bg = ? - WHERE channel = ? AND feed_name = ? - ''', (feed_url, fg, bg, channel, feed_name)) + UPDATE rss_feeds SET feed_url = {0}, fg = {0}, bg = {0} + WHERE channel = {0} AND feed_name = {0} + '''.format(self.sub), (feed_url, fg, bg, channel, feed_name)) bot.reply("Successfully modified the feed.") return True @@ -185,9 +240,9 @@ def _rss_del(self, bot, trigger, c): args = [arg for arg in (channel, feed_name) if arg] c.execute(('DELETE FROM rss_feeds WHERE ' - + ('channel = ? AND ' if channel else '') - + ('feed_name = ?' if feed_name else '') - ).rstrip(' AND '), args) + + ('channel = {0} AND ' if channel else '') + + ('feed_name = {0}' if feed_name else '') + ).rstrip(' AND ').format(self.sub), args) if c.rowcount: noun = 'feeds' if c.rowcount != 1 else 'feed' @@ -225,10 +280,10 @@ def _toggle(self, bot, trigger, c): feed_name = match.group(3).strip('"') if match.group(3) else None args = [arg for arg in (enabled, channel, feed_name) if arg is not None] - c.execute(('UPDATE rss_feeds SET enabled = ? WHERE ' - + ('channel = ? AND ' if channel else '') - + ('feed_name = ?' if feed_name else '') - ).rstrip(' AND '), args) + c.execute(('UPDATE rss_feeds SET enabled = {0} WHERE ' + + ('channel = {0} AND ' if channel else '') + + ('feed_name = {0}' if feed_name else '') + ).rstrip(' AND ').format(self.sub), args) if c.rowcount: noun = 'feeds' if c.rowcount != 1 else 'feed' @@ -320,6 +375,7 @@ def read_feeds(bot, force=False): if not bot.memory['rss_manager'].running and not force: return + sub = bot.db.substitution conn = bot.db.connect() c = conn.cursor() c.execute('SELECT * FROM rss_feeds') @@ -334,9 +390,9 @@ def read_feeds(bot, force=False): def disable_feed(): c.execute(''' - UPDATE rss_feeds SET enabled = ? - WHERE channel = ? AND feed_name = ? - ''', (0, feed.channel, feed.name)) + UPDATE rss_feeds SET enabled = {0} + WHERE channel = {0} AND feed_name = {0} + '''.format(sub), (0, feed.channel, feed.name)) conn.commit() try: @@ -360,9 +416,9 @@ def disable_feed(): feed.name, fp.href ) c.execute(''' - UPDATE rss_feeds SET feed_url = ? - WHERE channel = ? AND feed_name = ? - ''', (fp.href, feed.channel, feed.name)) + UPDATE rss_feeds SET feed_url = {0} + WHERE channel = {0} AND feed_name = {0} + '''.format(sub), (fp.href, feed.channel, feed.name)) conn.commit() elif status == 410: # GONE @@ -393,10 +449,10 @@ def disable_feed(): # save article title, url, and modified date c.execute(''' UPDATE rss_feeds - SET article_title = ?, article_url = ?, published = ?, etag = ?, modified = ? - WHERE channel = ? AND feed_name = ? - ''', (entry.title, entry.link, entry_dt, feed_etag, feed_modified, - feed.channel, feed.name)) + SET article_title = {0}, article_url = {0}, published = {0}, etag = {0}, modified = {0} + WHERE channel = {0} AND feed_name = {0} + '''.format(sub), (entry.title, entry.link, entry_dt, feed_etag, feed_modified, + feed.channel, feed.name)) conn.commit() if feed.published and entry_dt: @@ -419,7 +475,9 @@ def disable_feed(): timestamp = entry_update_dt or entry_dt if timestamp: # attempt to get time format from preferences - tformat = bot.db.get_channel_value(feed.channel, 'time_format') + tformat = '' + if feed.channel in bot.db.preferences: + tformat = bot.db.preferences.get(feed.channel, 'time_format') or tformat if not tformat and bot.config.has_option('clock', 'time_format'): tformat = bot.config.clock.time_format diff --git a/willie/modules/safety.py b/willie/modules/safety.py index ffb3baf5bc..7030df8ac1 100644 --- a/willie/modules/safety.py +++ b/willie/modules/safety.py @@ -53,6 +53,8 @@ def configure(config): def setup(bot): if not bot.config.has_section('safety'): raise ConfigurationError("Safety module not configured") + if bot.db and not bot.db.preferences.has_columns('safety'): + bot.db.preferences.add_columns(['safety']) bot.memory['safety_cache'] = willie.tools.WillieMemory() for item in bot.config.safety.get_list('known_good'): known_good.append(re.compile(item, re.I)) @@ -91,8 +93,8 @@ def url_handler(bot, trigger): else: check = bool(check) # DB overrides config: - setting = bot.db.get_channel_value(trigger.sender, 'safety') - if setting is not None: + if bot.db and trigger.sender.lower() in bot.db.preferences: + setting = bot.db.preferences.get(trigger.sender.lower(), 'safety') if setting == 'off': return # Not checking elif setting in ['on', 'strict', 'local', 'local strict']: @@ -162,11 +164,14 @@ def toggle_safety(bot, trigger): options = ' / '.join(allowed_states) bot.reply('Available options: %s' % options) return + if not bot.db: + bot.reply('No database configured, can\'t modify settings') + return if not trigger.isop and not trigger.admin: bot.reply('Only channel operators can change safety settings') channel = trigger.sender.lower() - bot.db.set_channel_value(channel, 'safety', trigger.group(2).lower()) + bot.db.preferences.update(channel, {'safety': trigger.group(2).lower()}) bot.reply('Safety is now set to %s in this channel' % trigger.group(2)) diff --git a/willie/modules/weather.py b/willie/modules/weather.py index e78ee49bab..682effe244 100644 --- a/willie/modules/weather.py +++ b/willie/modules/weather.py @@ -16,6 +16,12 @@ from lxml import etree +def setup(bot): + # Having a db means pref's exists. Later, we can just use `if bot.db`. + if bot.db and not bot.db.preferences.has_columns('woeid'): + bot.db.preferences.add_columns(['woeid']) + + def woeid_search(query): """ Find the first Where On Earth ID for the given query. Result is the etree @@ -126,14 +132,16 @@ def weather(bot, trigger): location = trigger.group(2) woeid = '' if not location: - woeid = bot.db.get_nick_value(trigger.nick, 'woeid') + if bot.db and trigger.nick in bot.db.preferences: + woeid = bot.db.preferences.get(trigger.nick, 'woeid') if not woeid: return bot.msg(trigger.sender, "I don't know where you live. " + 'Give me a location, like .weather London, or tell me where you live by saying .setlocation London, for example.') else: location = location.strip() - woeid = bot.db.get_channel_value(location, 'woeid') - if woeid is None: + if bot.db and location in bot.db.preferences: + woeid = bot.db.preferences.get(location, 'woeid') + else: first_result = woeid_search(location) if first_result is not None: woeid = first_result.find('woeid').text @@ -161,20 +169,23 @@ def update_woeid(bot, trigger): bot.reply('Give me a location, like "Washington, DC" or "London".') return NOLIMIT - first_result = woeid_search(trigger.group(2)) - if first_result is None: - return bot.reply("I don't know where that is.") + if bot.db: + first_result = woeid_search(trigger.group(2)) + if first_result is None: + return bot.reply("I don't know where that is.") - woeid = first_result.find('woeid').text + woeid = first_result.find('woeid').text - bot.db.set_nick_value(trigger.nick, 'woeid', woeid) + bot.db.preferences.update(trigger.nick, {'woeid': woeid}) - neighborhood = first_result.find('neighborhood').text or '' - if neighborhood: - neighborhood += ',' - city = first_result.find('city').text or '' - state = first_result.find('state').text or '' - country = first_result.find('country').text or '' - uzip = first_result.find('uzip').text or '' - bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' % - (woeid, neighborhood, city, state, country, uzip)) + neighborhood = first_result.find('neighborhood').text or '' + if neighborhood: + neighborhood += ',' + city = first_result.find('city').text or '' + state = first_result.find('state').text or '' + country = first_result.find('country').text or '' + uzip = first_result.find('uzip').text or '' + bot.reply('I now have you at WOEID %s (%s %s, %s, %s %s.)' % + (woeid, neighborhood, city, state, country, uzip)) + else: + bot.reply("I can't remember that; I don't have a database.") diff --git a/willie/tools.py b/willie/tools.py index 8b503c43ff..975190a1e5 100644 --- a/willie/tools.py +++ b/willie/tools.py @@ -512,10 +512,9 @@ def get_timezone(db=None, config=None, zone=None, nick=None, channel=None): Time zone is pulled in the following priority: 1. `zone`, if it is valid - 2. The timezone for the channel or nick `zone` in `db` if one is set and - valid. - 3. The timezone for the nick `nick` in `db`, if one is set and valid. - 4. The timezone for the channel `channel` in `db`, if one is set and valid. + 2. The timezone for `zone` in `db` if one is set and valid. + 3. The timezone for `nick` in `db`, if one is set and valid. + 4. The timezone for `channel` in `db`, if one is set and valid. 5. The default timezone in `config`, if one is set and valid. If `db` is not given, or given but not set up, steps 2 and 3 will be @@ -551,12 +550,12 @@ def check(zone): if zone: tz = check(zone) - if not tz: - tz = check(db.get_channel_or_nick_value(zone, 'timezone')) - if not tz and nick: - tz = check(db.get_nick_value(nick, 'timezone')) - if not tz and channel: - tz = check(db.get_channel_value(channel, 'timezone')) + if not tz and zone in db.preferences: + tz = check(db.preferences.get(zone, 'tz')) + if not tz and nick and nick in db.preferences: + tz = check(db.preferences.get(nick, 'tz')) + if not tz and channel and channel in db.preferences: + tz = check(db.preferences.get(channel, 'tz')) if not tz and config and config.has_option('core', 'default_timezone'): tz = check(config.core.default_timezone) return tz @@ -575,8 +574,8 @@ def format_time(db=None, config=None, zone=None, nick=None, channel=None, The format for the string is chosen in the following order: - 1. The format for the nick `nick` in `db`, if one is set and valid. - 2. The format for the channel `channel` in `db`, if one is set and valid. + 1. The format for `nick` in `db`, if one is set and valid. + 2. The format for `channel` in `db`, if one is set and valid. 3. The default format in `config`, if one is set and valid. 4. ISO-8601 @@ -584,10 +583,10 @@ def format_time(db=None, config=None, zone=None, nick=None, channel=None, is not given, step 3 will be skipped.""" tformat = None if db: - if nick: - tformat = db.get_nick_value(nick, 'time_format') + if nick and nick in db.preferences: + tformat = db.preferences.get(nick, 'time_format') if not tformat and channel in db.preferences: - tformat = db.get_channel_value(channel, 'time_format') + tformat = db.preferences.get(channel, 'time_format') if not tformat and config and config.has_option('core', 'default_time_format'): tformat = config.core.default_time_format