Full support for multiple faction states.
authorCMDR furrycat <elite@furrycat.net>
Sun, 23 Dec 2018 17:07:14 +0000 (17:07 +0000)
committerCMDR furrycat <elite@furrycat.net>
Sun, 23 Dec 2018 17:07:14 +0000 (17:07 +0000)
plugin/faction/faction.py

index 3318b41..7167bbf 100644 (file)
@@ -65,6 +65,8 @@ 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, state_id, pending)')
+    cursor = self.query('create table if not exists faction_states (checksum char(32) not null, eddb_id int not null, faction_id int not null, state_id int not null)')
+    cursor = self.query('create unique index if not exists faction_states_state on faction_states (checksum, eddb_id, faction_id, state_id)')
     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)')
@@ -1147,7 +1149,7 @@ class Faction(DBConnection):
     influences = []
     for faction in reversed(sorted(factions, key = lambda faction: faction['Influence'])):
       states = await self.parse_states(faction)
-      influences.append('{} {:.2f}% {}'.format(faction['Name'], faction['Influence'] * 100.0, states[0]))
+      influences.append('{} {:.2f}% {}'.format(faction['Name'], faction['Influence'] * 100.0, '; '.join(states)))
     influence = ', '.join(influences)
     log.debug('{} factions: {}'.format(system, influence))
     try:
@@ -1210,6 +1212,15 @@ class Faction(DBConnection):
       if not cursor.rowcount:
         log.debug('No update for {} with checksum {}'.format(system, checksum))
         update = True
+      if len(active_states):
+        sql = 'insert or ignore into faction_states values '
+        clauses = []
+        params = []
+        for state in active_states:
+          clauses.append('(?, ?, ?, ?)')
+          params += [checksum, system_id, faction_id, eddb.get_state_id(state)]
+        sql += ', '.join(clauses)
+        cursor = self.query(sql, params)
       if len(trending_states):
         sql = 'insert or ignore into faction_trend values '
         clauses = []
@@ -1237,7 +1248,7 @@ class Faction(DBConnection):
     return True
 
   def null_report(self):
-    return { 'faction_id': 0, 'text': '', 'state': '', 'pending': set(), 'recovering': set() }
+    return { 'faction_id': 0, 'text': '', 'states': set(), 'pending': set(), 'recovering': set() }
 
   def format_trend(self, state_id, trend):
     return '{}{}'.format('+' * trend if trend > 0 else '-' * abs(trend), eddb.state_name(state_id))
@@ -1246,7 +1257,7 @@ class Faction(DBConnection):
     if not report['text']:
       return None
 
-    states = [report['state']]
+    states = [', '.join(report['states'])]
     for key in ['pending', 'recovering']:
       if len(report[key]):
         states.append('{} {}'.format(key, ', '.join(report[key])))
@@ -1270,7 +1281,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, 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'
+    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, a.state_id as active_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 latest from faction_influence group by eddb_id) j left join faction_states a using(checksum, eddb_id, faction_id) 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.latest'
     params = []
     if id is not None:
       sql += ' and i.eddb_id in (select distinct eddb_id from faction_influence where faction_id=?)'
@@ -1281,7 +1292,7 @@ class Faction(DBConnection):
     elif system is not None:
       sql += ' and s.name=?'
       params.append(system)
-    sql += ' order by system_name, influence desc, faction_name, pending, trend desc'
+    sql += ' order by system_name, influence desc, faction_name, active_state_id, pending, trend desc'
     cursor = self.query(sql, params)
     report = {}
     last_system = ''
@@ -1307,7 +1318,7 @@ class Faction(DBConnection):
         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'])
+      report['states'].add(eddb.state_name(row['active_state_id']))
       if row['trend'] is not None:
         key = 'pending' if bot.parse_boolean(row['pending']) else 'recovering'
         report[key].add(self.format_trend(row['pending_state_id'], row['trend']))
@@ -1436,7 +1447,7 @@ class Faction(DBConnection):
       log.warning("No factions or systems to graph!")
       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 where i.faction_id=n.faction_id and i.eddb_id=s.eddb_id'
+    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, a.state_id as active_state_id from faction_influence i, faction_systems s, faction_names n, (select eddb_id, max(timestamp) as latest from faction_influence group by eddb_id) j left join faction_states a using(checksum, eddb_id, faction_id) where i.faction_id=n.faction_id and i.eddb_id=s.eddb_id'
     params = []
     if len(system_ids):
       sql += ' and i.eddb_id in ({})'.format(', '.join(['?'] * len(system_ids)))
@@ -1450,7 +1461,7 @@ class Faction(DBConnection):
     if end_date is not None:
       sql += ' and timestamp<=?'
       params.append(end_date)
-    sql += ' group by timestamp, system_name, faction_name order by timestamp desc, system_name, faction_name'
+    sql += ' group by timestamp, system_name, faction_name, active_state_id order by timestamp desc, system_name, faction_name, active_state_id'
 
     title = 'Influence'
     if len(faction_ids) == 1:
@@ -1492,7 +1503,7 @@ class Faction(DBConnection):
         entry = data[row[key]]
       entry['x'].append(dt)
       entry['y'].append(row['influence'] * 100.0)
-      entry['s'].append(row['state_id'])
+      entry['s'].append(row['active_state_id'])
     self.close_db()
 
     if not len(data):