0.4.1.0.a6
- I forgot hybrid commands call two triggers whenever executed, thus messing with the counter on the docsite - *Let's see if this fixes things..*
This commit is contained in:
		
							parent
							
								
									fe09e1dd1f
								
							
						
					
					
						commit
						dab1e4e9e0
					
				
							
								
								
									
										2
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bot.py
									
									
									
									
									
								
							@ -9,7 +9,7 @@ from modules.common.boot_notice import post_boot_notice
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Version consists of:
 | 
					# Version consists of:
 | 
				
			||||||
# Major.Enhancement.Minor.Patch.Test  (Test is alphanumeric; doesn’t trigger auto update)
 | 
					# Major.Enhancement.Minor.Patch.Test  (Test is alphanumeric; doesn’t trigger auto update)
 | 
				
			||||||
VERSION = "0.4.1.0.a5"
 | 
					VERSION = "0.4.1.0.a6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ---------- Env loading ----------
 | 
					# ---------- Env loading ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,6 @@ from discord.ext import commands
 | 
				
			|||||||
import discord
 | 
					import discord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COUNTER_KEY_PREFIX = "cmd::"
 | 
					COUNTER_KEY_PREFIX = "cmd::"
 | 
				
			||||||
LOCK_WINDOW_SEC = 1.0  # timelock window; change if you want stricter/looser locking
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _key_from_app(cmd: discord.app_commands.Command) -> str:
 | 
					def _key_from_app(cmd: discord.app_commands.Command) -> str:
 | 
				
			||||||
    name = getattr(cmd, "qualified_name", None) or getattr(cmd, "name", "unknown")
 | 
					    name = getattr(cmd, "qualified_name", None) or getattr(cmd, "name", "unknown")
 | 
				
			||||||
@ -16,11 +15,11 @@ def _key_from_ctx(ctx: commands.Context) -> str:
 | 
				
			|||||||
    return f"{COUNTER_KEY_PREFIX}{name}"
 | 
					    return f"{COUNTER_KEY_PREFIX}{name}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UsageStatsCog(commands.Cog):
 | 
					class UsageStatsCog(commands.Cog):
 | 
				
			||||||
    """Command run counters with a per-command timelock."""
 | 
					    """Count command runs without double-counting hybrids invoked as slash."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, bot: commands.Bot):
 | 
					    def __init__(self, bot: commands.Bot):
 | 
				
			||||||
        self.bot = bot
 | 
					        self.bot = bot
 | 
				
			||||||
        print("[usage] UsageStatsCog init (timelock)")
 | 
					        print("[usage] UsageStatsCog init")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.Cog.listener()
 | 
					    @commands.Cog.listener()
 | 
				
			||||||
    async def on_app_command_completion(self, interaction: discord.Interaction, command: discord.app_commands.Command):
 | 
					    async def on_app_command_completion(self, interaction: discord.Interaction, command: discord.app_commands.Command):
 | 
				
			||||||
@ -28,39 +27,34 @@ class UsageStatsCog(commands.Cog):
 | 
				
			|||||||
        if not dm:
 | 
					        if not dm:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            counter_key = _key_from_app(command)
 | 
					            key = _key_from_app(command)
 | 
				
			||||||
            newv = dm.incr_counter_timelocked(counter_key, window_sec=LOCK_WINDOW_SEC)
 | 
					            newv = dm.incr_counter(key, 1)
 | 
				
			||||||
            if newv is not None:
 | 
					            print(f"[usage] app ++ {key} -> {newv}")
 | 
				
			||||||
                print(f"[usage] app ++ {counter_key} -> {newv}")
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                print(f"[usage] app ~~ timelocked {counter_key}")
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            print("[usage] app !! incr failed:", repr(e))
 | 
					            print("[usage] app !! incr failed:", repr(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @commands.Cog.listener()
 | 
					    @commands.Cog.listener()
 | 
				
			||||||
    async def on_command_completion(self, ctx: commands.Context):
 | 
					    async def on_command_completion(self, ctx: commands.Context):
 | 
				
			||||||
        # If a HybridCommand was invoked as a slash interaction, let the app listener count it.
 | 
					        # If a HybridCommand was invoked via slash, the app listener already counted it.
 | 
				
			||||||
        if isinstance(getattr(ctx, "command", None), commands.HybridCommand) and getattr(ctx, "interaction", None):
 | 
					        if isinstance(getattr(ctx, "command", None), commands.HybridCommand) and getattr(ctx, "interaction", None):
 | 
				
			||||||
 | 
					            print("[usage] px  ~~ hybrid-as-slash; ignored (already counted in app)")
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dm = getattr(self.bot, "data_manager", None)
 | 
					        dm = getattr(self.bot, "data_manager", None)
 | 
				
			||||||
        if not dm:
 | 
					        if not dm:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            counter_key = _key_from_ctx(ctx)
 | 
					            key = _key_from_ctx(ctx)
 | 
				
			||||||
            newv = dm.incr_counter_timelocked(counter_key, window_sec=LOCK_WINDOW_SEC)
 | 
					            newv = dm.incr_counter(key, 1)
 | 
				
			||||||
            if newv is not None:
 | 
					            print(f"[usage] px  ++ {key} -> {newv}")
 | 
				
			||||||
                print(f"[usage] px  ++ {counter_key} -> {newv}")
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                print(f"[usage] px  ~~ timelocked {counter_key}")
 | 
					 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            print("[usage] px  !! incr failed:", repr(e))
 | 
					            print("[usage] px  !! incr failed:", repr(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def setup(bot: commands.Bot):
 | 
					async def setup(bot: commands.Bot):
 | 
				
			||||||
    # Prevent duplicate registration if extensions are reloaded / auto-discovered twice
 | 
					    # Avoid double registration if extensions are discovered/reloaded twice
 | 
				
			||||||
    if getattr(bot, "_usage_stats_loaded", False):
 | 
					    if getattr(bot, "_usage_stats_loaded", False):
 | 
				
			||||||
        print("[usage] UsageStatsCog already loaded; skipping duplicate add")
 | 
					        print("[usage] UsageStatsCog already loaded; skipping duplicate add")
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
    await bot.add_cog(UsageStatsCog(bot))
 | 
					    await bot.add_cog(UsageStatsCog(bot))
 | 
				
			||||||
    bot._usage_stats_loaded = True
 | 
					    bot._usage_stats_loaded = True
 | 
				
			||||||
    print("[usage] UsageStatsCog loaded (timelock)")
 | 
					    print("[usage] UsageStatsCog loaded")
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user