working on frequency analysis
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
from .emote import Emote
|
from .emote import Emote
|
||||||
from .freq import Frequency
|
from .frequency import Frequency
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import discord
|
|||||||
|
|
||||||
# Custom libs
|
# Custom libs
|
||||||
|
|
||||||
from utils import mention, plural, day_interval
|
from utils import mention, plural, from_now
|
||||||
|
|
||||||
|
|
||||||
class Emote:
|
class Emote:
|
||||||
@@ -73,7 +73,7 @@ class Emote:
|
|||||||
if show_life and not self.default:
|
if show_life and not self.default:
|
||||||
output += f"(in {plural(self.life_days(), 'day')}) "
|
output += f"(in {plural(self.life_days(), 'day')}) "
|
||||||
if self.used():
|
if self.used():
|
||||||
output += f"(last used {day_interval(self.use_days())})"
|
output += f"(last used {from_now(self.last_used)})"
|
||||||
if show_members:
|
if show_members:
|
||||||
output += f" (mostly by {mention(self.get_top_member())}: {self.members[self.get_top_member()]})"
|
output += f" (mostly by {mention(self.get_top_member())}: {self.members[self.get_top_member()]})"
|
||||||
return output
|
return output
|
||||||
|
|||||||
@@ -1,2 +1,25 @@
|
|||||||
|
from typing import List
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from utils import str_date, str_datetime, from_now
|
||||||
|
|
||||||
|
|
||||||
class Frequency:
|
class Frequency:
|
||||||
pass
|
def __init__(self):
|
||||||
|
self.earliest = None
|
||||||
|
self.latest = None
|
||||||
|
self.longest_break = timedelta(seconds=0)
|
||||||
|
self.longest_break_start = None
|
||||||
|
|
||||||
|
def to_string(self) -> List[str]:
|
||||||
|
return [
|
||||||
|
f"**earliest message:** {str_date(self.earliest)} ({from_now(self.earliest)})",
|
||||||
|
f"**latest message:** {str_date(self.latest)} ({from_now(self.latest)})",
|
||||||
|
# "**msg/day:** n",
|
||||||
|
# "**busiest day of week:** dd (avg. n msg)",
|
||||||
|
# "**busiest day ever:** jj/mm/yyyy (n days ago) (n msg)",
|
||||||
|
# "**msg/hour:** n",
|
||||||
|
# "**busiest hour of day:** hh (avg. n msg)",
|
||||||
|
# "**busiest hour ever:** hh jj/mm/yyyy (n days ago) (n msg)",
|
||||||
|
f"**longest break:** {int(self.longest_break.total_seconds() / 3600):,} hours from {str_datetime(self.longest_break_start)} ({from_now(self.earliest)})",
|
||||||
|
]
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class GuildLogs:
|
|||||||
max_chan = len(target_channels)
|
max_chan = len(target_channels)
|
||||||
await code_message(
|
await code_message(
|
||||||
progress,
|
progress,
|
||||||
f"Reading history...\n0 messages in 0/{max_chan} channels\n(this might take a while)",
|
f"Reading new history...\n0 messages in 0/{max_chan} channels\n(this might take a while)",
|
||||||
)
|
)
|
||||||
for channel in target_channels:
|
for channel in target_channels:
|
||||||
if channel.id not in self.channels:
|
if channel.id not in self.channels:
|
||||||
@@ -95,7 +95,7 @@ class GuildLogs:
|
|||||||
dt = (datetime.now() - t0).total_seconds()
|
dt = (datetime.now() - t0).total_seconds()
|
||||||
await code_message(
|
await code_message(
|
||||||
progress,
|
progress,
|
||||||
f"Reading history...\n{tmp_msg:,} messages in {total_chan + 1}/{max_chan} channels ({round(tmp_queried_msg/dt)}m/s)\n{warning_msg}",
|
f"Reading new history...\n{tmp_msg:,} messages in {total_chan + 1}/{max_chan} channels ({round(tmp_queried_msg/dt)}m/s)\n{warning_msg}",
|
||||||
)
|
)
|
||||||
if done:
|
if done:
|
||||||
total_chan += 1
|
total_chan += 1
|
||||||
@@ -109,17 +109,17 @@ class GuildLogs:
|
|||||||
t0 = datetime.now()
|
t0 = datetime.now()
|
||||||
await code_message(
|
await code_message(
|
||||||
progress,
|
progress,
|
||||||
f"Saving (1/3)...\n{total_msg:,} messages in {total_chan} channels",
|
f"Saving history (1/3)...\n{total_msg:,} messages in {total_chan} channels",
|
||||||
)
|
)
|
||||||
json_data = bytes(json.dumps(self.dict()), "utf-8")
|
json_data = bytes(json.dumps(self.dict()), "utf-8")
|
||||||
await code_message(
|
await code_message(
|
||||||
progress,
|
progress,
|
||||||
f"Saving (2/3)...\n{total_msg:,} messages in {total_chan} channels",
|
f"Saving history (2/3)...\n{total_msg:,} messages in {total_chan} channels",
|
||||||
)
|
)
|
||||||
gziped_data = gzip.compress(json_data)
|
gziped_data = gzip.compress(json_data)
|
||||||
await code_message(
|
await code_message(
|
||||||
progress,
|
progress,
|
||||||
f"Saving (3/3)...\n{total_msg:,} messages in {total_chan} channels",
|
f"Saving history (3/3)...\n{total_msg:,} messages in {total_chan} channels",
|
||||||
)
|
)
|
||||||
with open(self.log_file, mode="wb") as f:
|
with open(self.log_file, mode="wb") as f:
|
||||||
f.write(gziped_data)
|
f.write(gziped_data)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from typing import List
|
from typing import List
|
||||||
|
from datetime import datetime
|
||||||
import discord
|
import discord
|
||||||
|
|
||||||
|
|
||||||
@@ -35,7 +36,7 @@ class FrequencyScanner(Scanner):
|
|||||||
|
|
||||||
def get_results(self, intro: str) -> List[str]:
|
def get_results(self, intro: str) -> List[str]:
|
||||||
res = [intro]
|
res = [intro]
|
||||||
# TODO
|
res += self.freq.to_string()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -44,7 +45,20 @@ class FrequencyScanner(Scanner):
|
|||||||
) -> bool:
|
) -> bool:
|
||||||
impacted = False
|
impacted = False
|
||||||
# If author is included in the selection (empty list is all)
|
# If author is included in the selection (empty list is all)
|
||||||
if not message.bot and (len(raw_members) == 0 or message.author in raw_members):
|
if len(raw_members) == 0 or message.author in raw_members:
|
||||||
impacted = True
|
impacted = True
|
||||||
|
date = message.created_at
|
||||||
|
# order is latest to earliest
|
||||||
|
if freq.latest is None:
|
||||||
|
freq.earliest = date
|
||||||
|
freq.latest = date
|
||||||
|
|
||||||
|
delay = freq.earliest - date
|
||||||
|
if delay > freq.longest_break:
|
||||||
|
freq.longest_break = delay
|
||||||
|
freq.longest_break_start = date
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
freq.earliest = date
|
||||||
return impacted
|
return impacted
|
||||||
|
|||||||
+31
-5
@@ -2,6 +2,7 @@ from typing import List
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
import discord
|
import discord
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
# DISCORD API
|
# DISCORD API
|
||||||
|
|
||||||
@@ -73,13 +74,38 @@ def plural(count: int, word: str) -> str:
|
|||||||
return str(count) + " " + word + ("s" if count != 1 else "")
|
return str(count) + " " + word + ("s" if count != 1 else "")
|
||||||
|
|
||||||
|
|
||||||
def day_interval(interval: int) -> str:
|
# DATE FORMATTING
|
||||||
if interval == 0:
|
|
||||||
return "today"
|
|
||||||
elif interval == 1:
|
def str_date(date: datetime) -> str:
|
||||||
|
return date.strftime("%d %b. %Y") # 12 Jun. 2018
|
||||||
|
|
||||||
|
|
||||||
|
def str_datetime(date: datetime) -> str:
|
||||||
|
return date.strftime("%H:%M, %d %b. %Y") # 12:05, 12 Jun. 2018
|
||||||
|
|
||||||
|
|
||||||
|
def from_now(src: datetime) -> str:
|
||||||
|
delay = datetime.utcnow() - src
|
||||||
|
seconds = delay.seconds
|
||||||
|
minutes = seconds // 60
|
||||||
|
hours = minutes // 60
|
||||||
|
if delay.days < 1:
|
||||||
|
if hours < 1:
|
||||||
|
if minutes == 0:
|
||||||
|
return "now"
|
||||||
|
elif minutes == 1:
|
||||||
|
return "a minute ago"
|
||||||
|
else:
|
||||||
|
return f"{minutes} minutes ago"
|
||||||
|
elif hours == 1:
|
||||||
|
return "an hour ago"
|
||||||
|
else:
|
||||||
|
return f"{hours} hours ago"
|
||||||
|
elif delay.days == 1:
|
||||||
return "yesterday"
|
return "yesterday"
|
||||||
else:
|
else:
|
||||||
return f"{interval} days ago"
|
return f"{delay.days:,} days ago"
|
||||||
|
|
||||||
|
|
||||||
# APP SPECIFIC
|
# APP SPECIFIC
|
||||||
|
|||||||
Reference in New Issue
Block a user