loading big history by 10k chunks

This commit is contained in:
klemek
2019-11-14 20:46:45 +01:00
parent 98481e7b1d
commit ea74778e15
+32 -22
View File
@@ -6,6 +6,10 @@ import re
import help import help
from utils import debug, aggregate, no_duplicate from utils import debug, aggregate, no_duplicate
# CONSTANTS
CHUNK_SIZE = 10000
# MAIN # MAIN
@@ -18,7 +22,6 @@ async def compute(message, args):
:param args: arguments of the command :param args: arguments of the command
:type args: list[:class:`str`] :type args: list[:class:`str`]
""" """
debug(message, f"command '{message.content}'")
guild = message.guild guild = message.guild
@@ -81,6 +84,7 @@ class Emote:
:ivar last_used: date of last use :ivar last_used: date of last use
:vartype last_used: datetime :vartype last_used: datetime
""" """
def __init__(self, emoji): def __init__(self, emoji):
self.emoji = emoji self.emoji = emoji
self.usages = 0 self.usages = 0
@@ -157,32 +161,38 @@ async def analyse_channel(channel, emotes, members, progress, nm0, nc):
nm = 0 nm = 0
nmm = 0 nmm = 0
try: try:
# Read ALL messages from the channel (pretty long : 300 msg/s) messages = [None]
async for m in channel.history(limit=None): while len(messages) >= CHUNK_SIZE or messages[-1] is None:
# If author is not bot or included in the selection (empty list is all) messages = await channel.history(limit=CHUNK_SIZE, before=messages[-1]).flatten()
if not m.author.bot and (len(members) == 0 or m.author in members): for m in messages:
# Find all emotes un the current message in the form "<:emoji:123456789>" tm0 = datetime.now()
# Filter for known emotes # If author is not bot or included in the selection (empty list is all)
found = [name for name in re.findall(r"(<:\w+:\d+>)", m.content) if name in emotes] if not m.author.bot and (len(members) == 0 or m.author in members):
# For each emote, update its usage # Find all emotes un the current message in the form "<:emoji:123456789>"
for name in found: # Filter for known emotes
emotes[name].usages += 1 found = [name for name in re.findall(r"(<:\w+:\d+>)", m.content) if name in emotes]
emotes[name].update_use(m.created_at) # For each emote, update its usage
# Count this message as impacted for name in found:
nmm += 1 emotes[name].usages += 1
# If we include all members, get reactions emotes[name].update_use(m.created_at)
if len(members) == 0: # Count this message as impacted
nmm += 1
# For each reaction of this message, test if known emote and update when it's the case # For each reaction of this message, test if known emote and update when it's the case
for reaction in m.reactions: for reaction in m.reactions:
name = str(reaction.emoji) name = str(reaction.emoji)
# reaction.emoji can be only str, we don't want that # reaction.emoji can be only str, we don't want that
if not (isinstance(reaction.emoji, str)) and name in emotes: if not (isinstance(reaction.emoji, str)) and name in emotes:
emotes[name].reactions += reaction.count if len(members) == 0:
emotes[name].update_use(m.created_at) emotes[name].reactions += reaction.count
# Count this message as treated and show progress every 1k messages emotes[name].update_use(m.created_at)
nm += 1 """ else:
if (nm0 + nm) % 1000 == 0: users = await reaction.users().flatten()
await progress.edit(content=f"```{(nm0 + nm) // 1000}k messages and {nc} channels analysed```") for member in members:
if member in users:
emotes[name].reactions += 1
emotes[name].update_use(m.created_at)"""
nm += len(messages)
await progress.edit(content=f"```{nm0 + nm:,} messages and {nc} channels analysed```")
return nm, nmm return nm, nmm
except discord.errors.HTTPException: except discord.errors.HTTPException:
# When an exception occurs (like Forbidden) sent -1 # When an exception occurs (like Forbidden) sent -1