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)')
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()
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()
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()
# 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)
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:
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):
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'.
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:
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: