1+ import sqlite3
12from collections import defaultdict
23from dataclasses import dataclass , field
34from itertools import chain
5+ from sqlite3 import Connection , Cursor
46from typing import Any , Dict , Iterable , List , Optional , Set
57
68import discord
79import tenacity
810from discord import Colour , Embed , app_commands
911from discord .ext import commands
1012from utils import enchants
13+ from utils .config import guild_config
1114from utils .constants import SLOT_NAMES , Role
1215from utils .models import Raider
1316from utils .report import Report
@@ -23,19 +26,23 @@ class RaidWeakEquipment:
2326 low_quality_gems : Dict [str , Set ] = field (default_factory = defaultdict )
2427 no_enchants : Dict [str , Set ] = field (default_factory = defaultdict )
2528 low_enchants : Dict [str , Set ] = field (default_factory = defaultdict )
29+ offspec_raid : Dict [str , Set ] = field (default_factory = defaultdict )
2630
27- def from_raiders (self , raiders : Iterable [Raider ]) -> 'RaidWeakEquipment' :
31+ def from_raiders (self , raiders : Iterable [Raider ], guild_id : str , raid_time : int ) -> 'RaidWeakEquipment' :
2832 self .empty_sockets = defaultdict (set )
2933 self .low_quality_gems = defaultdict (set )
3034 self .no_enchants = defaultdict (set )
3135 self .low_enchants = defaultdict (set )
36+ self .offspec_raid = defaultdict (set )
3237
3338 for raider in raiders :
3439 for item in raider .gear :
3540 if item ['id' ] == 0 :
3641 continue
3742 self ._check_sockets (raider .name , item )
3843 self ._check_enchants (raider .name , item )
44+ if guild_config .has_section (guild_id ) and guild_config [guild_id ].getboolean ('epgp_enabled' ):
45+ self ._check_offspec (raider .name , item , guild_id , raid_time )
3946
4047 return self
4148
@@ -75,6 +82,28 @@ def _check_enchants(self, raider_name: str, item: Dict) -> None:
7582 elif item ['permanentEnchant' ] in enchants .BAD_ENCHANTS [item ['slot' ]]:
7683 self .low_enchants [raider_name ].add (SLOT_NAMES .get (item ['slot' ]))
7784
85+ def _check_offspec (self , raider_name : str , item : Dict , guild_id : str , raid_time : int ) -> None :
86+ """Checks if items looted for off-spec during month before raid were equipped in raid
87+
88+ :param raider_name: Raider name
89+ :param item: Equipped item dictionary
90+ :param guild_id: Discord Guild ID. Used to query a proper DB
91+ :param raid_time: Start time of the raid
92+ """
93+ db_name = f'./data/{ guild_id } .db'
94+ connection : Connection = sqlite3 .connect (db_name )
95+ cursor : Cursor = connection .cursor ()
96+
97+ cursor .execute ('''SELECT * FROM Traffic WHERE
98+ item_id=? AND target=? AND (gpa - gpb)=0 AND timestamp BETWEEN ? and ? ''' ,
99+ (item ['id' ], raider_name , raid_time - 2592000 , raid_time ),
100+ )
101+ if not cursor .fetchone () is None :
102+ self .offspec_raid [raider_name ].add (SLOT_NAMES .get (item ['slot' ]))
103+
104+ cursor .close ()
105+ connection .close ()
106+
78107
79108class Gear (commands .Cog ):
80109
@@ -89,10 +118,10 @@ async def gear(self, interaction: discord.Interaction, report_id: str) -> None:
89118 # noinspection PyUnresolvedReferences
90119 await interaction .response .defer ()
91120
92- embed = await self .process_interaction (report_id )
121+ embed = await self .process_interaction (report_id , str ( interaction . guild . id ) )
93122 await interaction .edit_original_response (embed = embed )
94123
95- async def process_interaction (self , report_id : str ) -> Optional [discord .Embed ]:
124+ async def process_interaction (self , report_id : str , guild_id : str ) -> Optional [discord .Embed ]:
96125 async with WCLClient () as client :
97126 try :
98127 rs = await client .get_table_summary (report_id )
@@ -111,7 +140,8 @@ async def process_interaction(self, report_id: str) -> Optional[discord.Embed]:
111140 raiders = self ._make_raiders (rs )
112141 # Check gems and enchants
113142 equipment = RaidWeakEquipment ()
114- equipment .from_raiders (chain .from_iterable (raiders .values ()))
143+ raid_time = int (rs ['reportData' ]['report' ]['startTime' ] / 1000 )
144+ equipment .from_raiders (chain .from_iterable (raiders .values ()), guild_id , raid_time )
115145
116146 embed .add_field (
117147 name = 'Нет камней' ,
@@ -133,6 +163,12 @@ async def process_interaction(self, report_id: str) -> Optional[discord.Embed]:
133163 value = self ._print_raiders (equipment .low_enchants ) or 'С пивком потянет!' ,
134164 inline = False ,
135165 )
166+ if guild_config .has_section (guild_id ) and guild_config [guild_id ].getboolean ('epgp_enabled' ):
167+ embed .add_field (
168+ name = 'Оффспек лут в рейде' ,
169+ value = self ._print_raiders (equipment .offspec_raid ) or 'Все молодцы!' ,
170+ inline = False ,
171+ )
136172
137173 return embed
138174
0 commit comments