@@ -193,11 +193,24 @@ def activity_values(member, when):
193193 for attr in ('timestamps' , 'assets' , 'party' ):
194194 try :
195195 values ['other' ][attr ] = getattr (member .activity , attr )
196- except KeyError :
196+ except AttributeError :
197197 pass
198198
199199 return values
200200
201+ def voice_event_values (member , when , voice_state ):
202+ return {
203+ 'timestamp' : when ,
204+ 'user_id' : member .id ,
205+ 'guild_id' : member .guild .id ,
206+ 'self_deaf' : voice_state .self_deaf ,
207+ 'self_mute' : voice_state .self_mute ,
208+ 'guild_deaf' : voice_state .deaf ,
209+ 'guild_mute' : voice_state .mute ,
210+ 'afk' : voice_state .afk ,
211+ 'voice_channel_id' : getattr (voice_state .channel , 'id' , None ),
212+ }
213+
201214class _Transaction :
202215 __slots__ = (
203216 'conn' ,
@@ -253,6 +266,7 @@ class DiscordSqlHandler:
253266 'tb_typing' ,
254267 'tb_statuses' ,
255268 'tb_activities' ,
269+ 'tb_voice_events' ,
256270 'tb_pins' ,
257271 'tb_mentions' ,
258272 'tb_guilds' ,
@@ -272,6 +286,7 @@ class DiscordSqlHandler:
272286 'typing_cache' ,
273287 'status_cache' ,
274288 'activity_cache' ,
289+ 'voice_event_cache' ,
275290 'guild_cache' ,
276291 'channel_cache' ,
277292 'voice_channel_cache' ,
@@ -338,6 +353,18 @@ def __init__(self, addr, cache_size, logger=null_logger):
338353 Column ('twitch_name' , String , nullable = True ),
339354 Column ('other' , JSON ),
340355 UniqueConstraint ('timestamp' , 'user_id' , name = 'uq_activities' ))
356+ self .tb_voice_events = Table ('voice_events' , meta ,
357+ Column ('timestamp' , DateTime , primary_key = True ),
358+ Column ('user_id' , BigInteger , ForeignKey ('users.user_id' ), primary_key = True ),
359+ Column ('guild_id' , BigInteger , ForeignKey ('guilds.guild_id' ), primary_key = True ),
360+ Column ('self_deaf' , Boolean ),
361+ Column ('self_mute' , Boolean ),
362+ Column ('guild_deaf' , Boolean ),
363+ Column ('guild_mute' , Boolean ),
364+ Column ('afk' , Boolean ),
365+ Column ('voice_channel_id' , BigInteger ,
366+ ForeignKey ('voice_channels.voice_channel_id' ), nullable = True ),
367+ UniqueConstraint ('timestamp' , 'user_id' , 'guild_id' , name = 'uq_voice_events' ))
341368 self .tb_pins = Table ('pins' , meta ,
342369 Column ('pin_id' , BigInteger , primary_key = True ),
343370 Column ('message_id' , BigInteger , ForeignKey ('messages.message_id' ),
@@ -465,6 +492,7 @@ def __init__(self, addr, cache_size, logger=null_logger):
465492 self .typing_cache = LruCache (cache_size ['event-size' ])
466493 self .status_cache = LruCache (cache_size ['event-size' ])
467494 self .activity_cache = LruCache (cache_size ['event-size' ])
495+ self .voice_event_cache = LruCache (cache_size ['event-size' ])
468496 self .guild_cache = LruCache (cache_size ['lookup-size' ])
469497 self .channel_cache = LruCache (cache_size ['lookup-size' ])
470498 self .voice_channel_cache = LruCache (cache_size ['lookup-size' ])
@@ -670,6 +698,23 @@ def activity_change(self, trans, member):
670698 trans .execute (ins )
671699 self .activity_cache [key ] = values
672700
701+ # Voice state
702+ def voice_state_change (self , trans , member , voice_state ):
703+ timestamp = datetime .now ()
704+ key = (timestamp , member .id , member .guild .id )
705+
706+ if self .voice_event_cache .get (key , None ):
707+ self .logger .debug ("Voice state change lookup is up-to-date" )
708+ return
709+
710+ self .logger .info (f"Inserting voice state change event for user { member .id } " )
711+ values = voice_event_values (member , timestamp , voice_state )
712+ ins = self .tb_voice_events \
713+ .insert () \
714+ .values (values )
715+ trans .execute (ins )
716+ self .voice_event_cache [key ] = values
717+
673718 # Reactions
674719 def add_reaction (self , trans , reaction , user ):
675720 self .logger .info (f"Inserting live reaction for user { user .id } on message { reaction .message .id } " )
0 commit comments