Merge pull request #8 from Klemek/f-streak
FrequencyScanner: streak calculation
This commit is contained in:
@@ -96,6 +96,8 @@ python3 src/main.py
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
* **v1.11**
|
||||||
|
* streak computing in `%pres`
|
||||||
* **v1.10**
|
* **v1.10**
|
||||||
* multithreading for queries
|
* multithreading for queries
|
||||||
* bug fix
|
* bug fix
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class Counter:
|
|||||||
else:
|
else:
|
||||||
output += f"**#{i + 1}**"
|
output += f"**#{i + 1}**"
|
||||||
sum = val_sum(self.usages)
|
sum = val_sum(self.usages)
|
||||||
output += f" {name} - {plural(sum, counted)} ({percent(sum/total_usage)}) (last {from_now(self.last_used)})"
|
output += f" {name} - {plural(sum, counted)} ({percent(sum/total_usage)}, last {from_now(self.last_used)})"
|
||||||
top_item = top_key(self.usages)
|
top_item = top_key(self.usages)
|
||||||
if top_item != 0 and transform is not None:
|
if top_item != 0 and transform is not None:
|
||||||
if self.usages[top_item] == sum:
|
if self.usages[top_item] == sum:
|
||||||
|
|||||||
@@ -2,7 +2,16 @@ from typing import List
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import calendar
|
import calendar
|
||||||
|
|
||||||
from utils import str_date, str_datetime, from_now, plural, percent, precise, top_key
|
from utils import (
|
||||||
|
str_date,
|
||||||
|
str_datetime,
|
||||||
|
from_now,
|
||||||
|
plural,
|
||||||
|
percent,
|
||||||
|
precise,
|
||||||
|
top_key,
|
||||||
|
mention,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Frequency:
|
class Frequency:
|
||||||
@@ -16,8 +25,19 @@ class Frequency:
|
|||||||
self.busiest_day_count = 0
|
self.busiest_day_count = 0
|
||||||
self.busiest_hour = None
|
self.busiest_hour = None
|
||||||
self.busiest_hour_count = 0
|
self.busiest_hour_count = 0
|
||||||
|
self.streaks = []
|
||||||
|
self.last_author = None
|
||||||
|
self.last_streak_start = None
|
||||||
|
self.last_streak_author = None
|
||||||
|
self.longest_streak = None
|
||||||
|
self.longest_streak_start = None
|
||||||
|
self.longest_streak_author = None
|
||||||
|
|
||||||
def to_string(self) -> List[str]:
|
def to_string(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
member_specific: bool,
|
||||||
|
) -> List[str]:
|
||||||
delta = self.dates[-1] - self.dates[0]
|
delta = self.dates[-1] - self.dates[0]
|
||||||
total_msg = len(self.dates)
|
total_msg = len(self.dates)
|
||||||
busiest_weekday = top_key(self.week)
|
busiest_weekday = top_key(self.week)
|
||||||
@@ -31,14 +51,24 @@ class Frequency:
|
|||||||
n_hours = delta.days
|
n_hours = delta.days
|
||||||
if self.dates[0].hour <= busiest_hour and self.dates[-1].hour >= busiest_hour:
|
if self.dates[0].hour <= busiest_hour and self.dates[-1].hour >= busiest_hour:
|
||||||
n_hours += 1
|
n_hours += 1
|
||||||
return [
|
ret = [
|
||||||
f"- **earliest message**: {str_datetime(self.dates[0])} ({from_now(self.dates[0])})",
|
f"- **earliest message**: {str_datetime(self.dates[0])} ({from_now(self.dates[0])})",
|
||||||
f"- **latest message**: {str_datetime(self.dates[-1])} ({from_now(self.dates[-1])})",
|
f"- **latest message**: {str_datetime(self.dates[-1])} ({from_now(self.dates[-1])})",
|
||||||
f"- **messages/day**: {precise(total_msg/delta.days, precision=3)}",
|
f"- **messages/day**: {precise(total_msg/delta.days, precision=3)}",
|
||||||
f"- **busiest day of week**: {calendar.day_name[busiest_weekday]} (~{precise(self.week[busiest_weekday]/n_weekdays, precision=3)} msg, {percent(self.week[busiest_weekday]/total_msg)})",
|
f"- **busiest day of week**: {calendar.day_name[busiest_weekday]} (~{precise(self.week[busiest_weekday]/n_weekdays, precision=3)} msg, {percent(self.week[busiest_weekday]/total_msg)})",
|
||||||
f"- **busiest day ever**: {str_date(self.busiest_day)} ({from_now(self.busiest_day)}) ({self.busiest_day_count} msg)",
|
f"- **busiest day ever**: {str_date(self.busiest_day)} ({from_now(self.busiest_day)}, {self.busiest_day_count} msg)",
|
||||||
f"- **messages/hour**: {precise(total_msg*3600/delta.total_seconds(), precision=3)}",
|
f"- **messages/hour**: {precise(total_msg*3600/delta.total_seconds(), precision=3)}",
|
||||||
f"- **busiest hour of day**: {busiest_hour:0>2}:00 (~{precise(self.day[busiest_hour]/n_hours, precision=3)} msg, {percent(self.day[busiest_hour]/total_msg)})",
|
f"- **busiest hour of day**: {busiest_hour:0>2}:00 (~{precise(self.day[busiest_hour]/n_hours, precision=3)} msg, {percent(self.day[busiest_hour]/total_msg)})",
|
||||||
f"- **busiest hour ever**: {str_datetime(self.busiest_hour)} ({from_now(self.busiest_hour)}) ({self.busiest_hour_count} msg)",
|
f"- **busiest hour ever**: {str_datetime(self.busiest_hour)} ({from_now(self.busiest_hour)}, {self.busiest_hour_count} msg)",
|
||||||
f"- **longest break**: {plural(round(self.longest_break.total_seconds()/3600), 'hour')} ({plural(self.longest_break.days,'day')}) from {str_datetime(self.longest_break_start)} ({from_now(self.longest_break_start)})",
|
f"- **longest break**: {plural(round(self.longest_break.total_seconds()/3600), 'hour')} ({plural(self.longest_break.days,'day')}) from {str_datetime(self.longest_break_start)} ({from_now(self.longest_break_start)})",
|
||||||
|
f"- **avg. streak**: {precise(sum(self.streaks)/len(self.streaks), precision=3)} msg",
|
||||||
]
|
]
|
||||||
|
if member_specific:
|
||||||
|
ret += [
|
||||||
|
f"- **longest streak**: {self.longest_streak:,} msg from {str_datetime(self.longest_streak_start)} ({from_now(self.longest_streak_start)})"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
ret += [
|
||||||
|
f"- **longest streak**: {mention(self.longest_streak_author)} ({self.longest_streak:,} msg from {str_datetime(self.longest_streak_start)}, {from_now(self.longest_streak_start)})"
|
||||||
|
]
|
||||||
|
return ret
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ emojis.load_emojis()
|
|||||||
|
|
||||||
bot = Bot(
|
bot = Bot(
|
||||||
"Discord Analyst",
|
"Discord Analyst",
|
||||||
"1.10",
|
"1.11",
|
||||||
alias="%",
|
alias="%",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ class FrequencyScanner(Scanner):
|
|||||||
def get_results(self, intro: str) -> List[str]:
|
def get_results(self, intro: str) -> List[str]:
|
||||||
FrequencyScanner.compute_results(self.freq)
|
FrequencyScanner.compute_results(self.freq)
|
||||||
res = [intro]
|
res = [intro]
|
||||||
res += self.freq.to_string()
|
res += self.freq.to_string(
|
||||||
|
member_specific=self.member_specific,
|
||||||
|
)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -64,6 +66,20 @@ class FrequencyScanner(Scanner):
|
|||||||
):
|
):
|
||||||
impacted = True
|
impacted = True
|
||||||
freq.dates += [message.created_at]
|
freq.dates += [message.created_at]
|
||||||
|
if message.author == freq.last_author:
|
||||||
|
freq.streaks[-1] += 1
|
||||||
|
else:
|
||||||
|
if len(freq.streaks) > 0 and (
|
||||||
|
freq.longest_streak is None
|
||||||
|
or freq.streaks[-1] > freq.longest_streak
|
||||||
|
):
|
||||||
|
freq.longest_streak = freq.streaks[-1]
|
||||||
|
freq.longest_streak_start = freq.last_streak_start
|
||||||
|
freq.longest_streak_author = freq.last_streak_author
|
||||||
|
freq.streaks += [1]
|
||||||
|
freq.last_streak_start = message.created_at
|
||||||
|
freq.last_streak_author = message.author
|
||||||
|
freq.last_author = message.author
|
||||||
return impacted
|
return impacted
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class FullScanner(Scanner):
|
|||||||
FrequencyScanner.compute_results(self.freq)
|
FrequencyScanner.compute_results(self.freq)
|
||||||
res = [intro]
|
res = [intro]
|
||||||
res += ["__Frequency__:"]
|
res += ["__Frequency__:"]
|
||||||
res += self.freq.to_string()
|
res += self.freq.to_string(member_specific=self.member_specific)
|
||||||
res += ["__Composition__:"]
|
res += ["__Composition__:"]
|
||||||
res += self.compo.to_string(self.msg_count)
|
res += self.compo.to_string(self.msg_count)
|
||||||
res += ["__Presence__:"]
|
res += ["__Presence__:"]
|
||||||
|
|||||||
Reference in New Issue
Block a user