From 54e65b4ecbec405b94cbe29afb708404d8262724 Mon Sep 17 00:00:00 2001 From: CMDR furrycat Date: Wed, 11 Oct 2017 10:52:47 +0100 Subject: [PATCH] Show summary graph, by default every 30 days. --- plugin/faction/faction.py | 77 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/plugin/faction/faction.py b/plugin/faction/faction.py index f957ba5..42c9bce 100644 --- a/plugin/faction/faction.py +++ b/plugin/faction/faction.py @@ -50,7 +50,7 @@ class Faction(DBConnection): def create_tables(self): self.open_db() - cursor = self.query('create table if not exists factions (id char(36) not null, bot_id varchar(32) not null, member_id varchar(32) not null, server_id varchar(32) not null, channel_id varchar(32), newsflash_channel_id varchar(32), faction_id int not null, name varchar(128) not null, state_id int not null, interval int not null default 86400, updated datetime)') + cursor = self.query('create table if not exists factions (id char(36) not null, bot_id varchar(32) not null, member_id varchar(32) not null, server_id varchar(32) not null, channel_id varchar(32), newsflash_channel_id varchar(32), faction_id int not null, name varchar(128) not null, state_id int not null, interval int not null default 86400, summary int default 30, updated datetime, last_spoke datetime)') cursor = self.query('create unique index if not exists factions_id on factions (id)') cursor = self.query('create index if not exists factions_bot_id on factions (bot_id)') cursor = self.query('create table if not exists faction_names (faction_id int not null, name varchar(128) not null)') @@ -63,7 +63,7 @@ class Faction(DBConnection): cursor = self.query('create unique index if not exists faction_influence_checksum on faction_influence (checksum, eddb_id, faction_id)') cursor = self.query('create table if not exists faction_trend (checksum char(32) not null, eddb_id int not null, faction_id int not null, state_id int not null, trend int not null, pending boolean)') cursor = self.query('create unique index if not exists faction_trend_state on faction_trend (checksum, eddb_id, faction_id, pending)') - cursor = self.query('create table if not exists systems (id char(36) not null, bot_id varchar(32) not null, member_id varchar(32) not null, server_id varchar(32) not null, name varchar(128) not null, channel_id varchar(32), newsflash_channel_id varchar(32), eddb_id int not null, interval int not null default 86400, updated datetime)') + cursor = self.query('create table if not exists systems (id char(36) not null, bot_id varchar(32) not null, member_id varchar(32) not null, server_id varchar(32) not null, name varchar(128) not null, channel_id varchar(32), newsflash_channel_id varchar(32), eddb_id int not null, interval int not null default 86400, summary int default 30, updated datetime, last_spoke datetime)') cursor = self.query('create unique index if not exists systems_id on systems (id)') cursor = self.query('create index if not exists systems_bot_id on systems (bot_id)') self.dbh.commit() @@ -79,7 +79,7 @@ class Faction(DBConnection): def get_tracked_factions(self): now = self.now() - cursor = self.query("select id, name, server_id, member_id, channel_id, newsflash_channel_id, interval, faction_id, name, state_id, updated from factions where updated is null or updated < ? - interval and bot_id=?", [now, client.user.id]) + cursor = self.query("select id, name, server_id, member_id, channel_id, newsflash_channel_id, interval, summary, faction_id, name, state_id, updated, last_spoke from factions where updated is null or updated < ? - interval and bot_id=?", [now, client.user.id]) for row in cursor.fetchall(): yield TrackedFaction(row) self.close_db() @@ -103,7 +103,7 @@ class Faction(DBConnection): def get_tracked_systems(self): now = self.now() - cursor = self.query("select id, name, server_id, member_id, channel_id, newsflash_channel_id, interval, eddb_id, name, updated from systems where updated is null or updated < ? - interval and bot_id=?", [now, client.user.id]) + cursor = self.query("select id, name, server_id, member_id, channel_id, newsflash_channel_id, interval, summary, eddb_id, name, updated, last_spoke from systems where updated is null or updated < ? - interval and bot_id=?", [now, client.user.id]) for row in cursor.fetchall(): yield TrackedSystem(row) self.close_db() @@ -228,8 +228,10 @@ class Faction(DBConnection): # Convert to list because we will be sharing the cursor. for faction in list(self.get_tracked_factions()): await self.report_tracked_faction(faction) + await self.show_tracked_faction_summary(faction) for system in list(self.get_tracked_systems()): await self.report_tracked_system(system) + await self.show_tracked_system_summary(system) await asyncio.sleep(waittime) @@ -469,6 +471,8 @@ class Faction(DBConnection): text = '{} track'.format(what) if tracked.interval: text += ' every {}'.format(bot.unparse_seconds(int(tracked.interval))) + if tracked.summary: + text += ' summary {}'.format(tracked.summary) if tracked.is_private: text += ' in private' elif tracked.channel_id is not None: @@ -623,6 +627,62 @@ class Faction(DBConnection): await self.report_faction_influence(channel, system_id = tracked.eddb_id, yelp_if_no_data = False) await self.report_stale_system_influence(channel, id = tracked.eddb_id) + async def show_tracked_faction_or_system_summary(self, tracked, what): + if what not in ['faction', 'system']: + log.error('Can only report faction or system.') + return + + if tracked.summary is None: + return + + now = self.now() + if tracked.last_spoke is not None and (now - tracked.last_spoke) / 86400 < tracked.summary: + return + + channel = None + channel_id = tracked.newsflash_channel_id if tracked.channel_id is None else tracked.channel_id + if tracked.is_private: + for server in client.servers: + try: + member = server.get_member(tracked.member_id) + channel = await client.start_private_message(member) + break + except: + log.exception('report_tracked_{}'.format(what)) + else: + channel = client.get_channel(channel_id) + + if channel is None: + log.warning("Can't get channel for {} {}".format(what, tracked.id)) + return + + then = now - 86400 * tracked.summary + sql = 'select distinct s.name as system_name from faction_systems s, faction_influence i where s.eddb_id=i.eddb_id and timestamp>=?' + params = [then] + if what == 'faction': + sql += ' and i.faction_id=?' + params.append(tracked.faction_id) + else: + sql += ' and i.eddb_id=?' + params.append(tracked.eddb_id) + cursor = self.query(sql, params) + system_names = [row['system_name'] for row in cursor.fetchall()] + self.close_db() + if len(system_names): + result = await self.graph_faction_history(channel, systems = system_names, start_date = then) + if not result: + log.warning('Failed summary graph for faction {}'.format(tracked.id)) + return + else: + log.info('No systems updated since {} for faction {}'.format(bot.iso8601(then), tracked.name)) + await self.update_tracked_faction(tracked.id, last_spoke = now) + + async def show_tracked_faction_summary(self, tracked): + await self.show_tracked_faction_or_system_summary(tracked, 'faction') + + async def show_tracked_system_summary(self, tracked): + await self.show_tracked_system_or_system_summary(tracked, 'system') + async def get_faction(self, destination, name): factions = eddb.find_faction(name) if not len(factions): @@ -812,6 +872,13 @@ class Faction(DBConnection): break else: break + elif arg == 'summary': + if param: + try: + parsed[arg] = int(param) + ok = True + except ValueError: + log.error('Invalid summary {}'.format(param)) else: if editing and self.is_uuid(arg): # UUID missing 'id'. @@ -888,6 +955,7 @@ class Faction(DBConnection): create = await self.parse_faction(message, args) if create is None: return + create['last_spoke'] = self.now() faction = await self.can_manage_factions(message.author, message.channel, 'create', create = TrackedFaction(create)) if not faction: @@ -958,6 +1026,7 @@ class Faction(DBConnection): create = await self.parse_system(message, args) if create is None: return + create['last_spoke'] = self.now() system = await self.can_manage_systems(message.author, message.channel, 'create', create = TrackedSystem(create)) if not system: -- 2.7.4