From e99499f088f740af7d33a1c9b8655f2e283029ef Mon Sep 17 00:00:00 2001 From: CMDR furrycat Date: Tue, 27 Jun 2017 18:13:28 +0100 Subject: [PATCH] Handle pending and recovering states from the journal. --- plugin/faction/faction.py | 64 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/plugin/faction/faction.py b/plugin/faction/faction.py index 2c90b49..a062587 100644 --- a/plugin/faction/faction.py +++ b/plugin/faction/faction.py @@ -57,6 +57,8 @@ class Faction(DBConnection): cursor = self.query('create index if not exists faction_influence_system on faction_influence (eddb_id)') cursor = self.query('create index if not exists faction_influence_faction on faction_influence (faction_id)') 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)') self.dbh.commit() self.close_db() @@ -819,6 +821,11 @@ class Faction(DBConnection): update = False announce = {} for faction in factions: + trending_states = [] + if 'PendingStates' in faction: + trending_states += map(lambda s: (eddb.get_state_id(s['State']), s['Trend'], 'true'), faction['PendingStates']) + if 'RecoveringStates' in faction: + trending_states += map(lambda s: (eddb.get_state_id(s['State']), s['Trend'], 'false'), faction['RecoveringStates']) state_id = eddb.get_state_id(faction['FactionState']) if state_id is None: state_id = eddb.get_state_id('None') @@ -845,6 +852,17 @@ class Faction(DBConnection): if not cursor.rowcount: log.debug('No update for {} with checksum {}'.format(system, checksum)) update = True + if len(trending_states): + sql = 'insert or ignore into faction_trend values ' + clauses = [] + params = [] + for trending_tuple in trending_states: + clauses.append('(?, ?, ?, ?, ?, ?)') + params += [checksum, system_id, faction_id] + params += list(trending_tuple) + sql += ', '.join(clauses) + cursor = self.query(sql, params) + if update: # We need a value for faction_id to use the index. cursor = self.query('update faction_influence set timestamp=? where checksum=? and eddb_id=? and faction_id>0', [timestamp, checksum, system_id]) @@ -856,10 +874,28 @@ class Faction(DBConnection): log.debug('Updated influence in {}: {}'.format(system, influence)) for system, channel in announce.items(): await self.report_faction_influence(channel, system = system, update = True, yelp_if_no_data = False) - self.close_db() return True + def null_report(self): + return { 'faction_id': 0, 'text': '', 'state': '', 'pending': [], 'recovering': [] } + + def format_report(self, report, *, id = None): + if not report['text']: + return None + + states = [report['state']] + for key in ['pending', 'recovering']: + if len(report[key]): + states.append('{} {}'.format(key, ', '.join(report[key]))) + + line = '{} ({})'.format(report['text'], '; '.join(states)) + + if report['faction_id'] == id: + line = '**{}**'.format(line) + + return line + async def report_faction_influence(self, destination, *, id = None, name = None, system = None, update = False, yelp_if_no_data = True): if id is None: if name is None: @@ -872,7 +908,7 @@ class Faction(DBConnection): log.error("Can't report influence of unknown faction {}".format(name)) return False - sql = 'select s.name as system_name, i.timestamp as timestamp, i.faction_id as faction_id, n.name as faction_name, i.influence as influence, i.state_id as state_id from faction_influence i, faction_systems s, faction_names n, (select eddb_id, max(timestamp) as timestamp from faction_influence group by eddb_id) j where i.faction_id=n.faction_id and i.eddb_id=s.eddb_id and i.timestamp=j.timestamp' + sql = 'select s.name as system_name, i.timestamp as timestamp, i.faction_id as faction_id, n.name as faction_name, i.influence as influence, i.state_id as state_id, t.pending as pending, t.state_id as pending_state_id, t.trend as trend from faction_influence i, faction_systems s, faction_names n, (select eddb_id, max(timestamp) as timestamp from faction_influence group by eddb_id) j left join faction_trend t using(checksum, eddb_id, faction_id) where i.faction_id=n.faction_id and i.eddb_id=s.eddb_id and i.timestamp=j.timestamp' params = [] if id is not None: sql += ' and i.eddb_id in (select distinct eddb_id from faction_influence where faction_id=?)' @@ -880,24 +916,38 @@ class Faction(DBConnection): if system is not None: sql += ' and s.name=?' params.append(system) - sql += ' order by system_name, influence desc' + sql += ' order by system_name, influence desc, pending, trend desc' cursor = self.query(sql, params) + report = {} last_system = '' lines = [] + report = self.null_report() for row in cursor.fetchall(): if row['system_name'] != last_system: if len(lines): lines.append('** **') await bot.say_many(destination, lines) lines = [] - log.info('Reporting {} influence to {}'.format(row['system_name'], destination)) + report = self.null_report() lines.append('{}__Influence in **{}** at *{}*__'.format('News flash: ' if update else '', row['system_name'], bot.iso8601(row['timestamp']))) lines.append(' ') last_system = row['system_name'] - line = '{} {:.2f}% ({})'.format(row['faction_name'], row['influence'] * 100.0, eddb.state_name(row['state_id'])) - if row['faction_id'] == id: - line = '**{}**'.format(line) + if row['faction_id'] != report['faction_id']: + line = self.format_report(report, id = id) + if line is not None: + lines.append(line) + report = self.null_report() + report['faction_id'] = row['faction_id'] + report['text'] = '{} {:.2f}%'.format(row['faction_name'], row['influence'] * 100.0) + report['state'] = eddb.state_name(row['state_id']) + if row['trend'] is not None: + key = 'pending' if bot.parse_boolean(row['pending']) else 'recovering' + report[key].append('{} {}'.format(eddb.state_name(row['pending_state_id']), row['trend'])) + + line = self.format_report(report, id = id) + if line is not None: lines.append(line) + if len(lines): lines.append('** **') await bot.say_many(destination, lines) -- 2.7.4