15 Commits

Author SHA1 Message Date
Klemek 78ad50be22 fix counter 2023-10-16 11:16:22 +02:00
Klemek 87217ac31c fix fix 2023-10-16 11:13:42 +02:00
Klemek c503673cbc fix utc_today 2023-10-16 11:10:02 +02:00
Klemek fffaae130c fix dates 2023-10-16 11:03:46 +02:00
Klemek eb6607de60 bump version 2023-10-16 10:18:01 +02:00
Klemek 18fe35e10f 30 to 90 days 2023-10-16 10:17:49 +02:00
Klemek cb37b052c9 fix sanity check 2022-09-02 10:22:12 +02:00
Klemek d8e9e48a13 update requirements.txt 2022-09-02 09:52:33 +02:00
Klemek 6dd45af14f discord v2 2022-09-02 09:41:52 +02:00
Klemek 3cca5c38f5 fix requirements.txt 2022-08-23 09:33:00 +02:00
Klemek 667fb0d414 Merge branch 'master' of github.com:klemek/discord-analyst 2022-08-22 09:22:26 +02:00
Klemek 5089d7d10b force discord.py version 2022-08-22 09:22:23 +02:00
Klemek afb3d7d663 remove invalid stats 2022-05-29 00:09:33 +02:00
Klemek cf2fa3208e Update gdpr.py 2022-03-07 23:08:34 +01:00
Klemek 7b4d952f9e Update GDPR.md 2022-03-07 23:08:11 +01:00
11 changed files with 37 additions and 30 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
## TL;DR
Analyst-bot collects text message information. It does not share collected data with any third-party and data is retained 18 months or until the bot is leaving the guild/server.
Analyst-bot collects text message information. It does not share collected data with any third-party and data is retained 90 days or until the bot is leaving the guild/server.
## Data collection
@@ -27,7 +27,7 @@ Any data collected is only processed in order to produce a one-time report sent
Analyst-bot stores the collected data in files that are accessible by the software and its administrator only.
Any collected data are retained maximum 30 days until deletion or when the bot is leaving a guild/server.
Any collected data are retained maximum 90 days until deletion or when the bot is leaving a guild/server.
## Data sharing
+2 -2
View File
@@ -1,6 +1,6 @@
discord.py>=1.7.0
discord.py>=2.0.0
python-dotenv>=0.15.0
python-dateutil>=2.8.1
matplotlib>=3.4.2
cryptography>=2.8
git+git://github.com/Klemek/miniscord.git
git+https://github.com/Klemek/miniscord.git
+2 -2
View File
@@ -4,7 +4,7 @@ from collections import defaultdict
# Custom libs
from utils import plural, from_now, percent, val_sum, top_key
from utils import plural, from_now, percent, val_sum, top_key, utc_today
class Counter:
@@ -25,7 +25,7 @@ class Counter:
if self.last_used is None:
return 0
return self.all_usages() + 1 / (
100000 * ((datetime.today() - self.last_used).days + 1)
100000 * (abs((utc_today() - self.last_used).days) + 1)
)
def all_usages(self) -> int:
+3 -3
View File
@@ -5,7 +5,7 @@ import discord
# Custom libs
from utils import mention, plural, from_now, top_key, percent
from utils import mention, plural, from_now, top_key, percent, utc_today
class Emoji:
@@ -44,14 +44,14 @@ class Emoji:
)
def life_days(self) -> int:
return (datetime.today() - self.emoji.created_at).days
return (utc_today() - self.emoji.created_at).days
def use_days(self) -> int:
# If never used, use creation date instead
if self.last_used is None:
return self.life_days()
else:
return (datetime.today() - self.last_used).days
return (utc_today() - self.last_used).days
def get_top_member(self) -> int:
return top_key(self.members)
+4 -4
View File
@@ -54,16 +54,16 @@ class Presence:
f"- **most visited channel**: {channel_mention(top_channel)} ({self.channel_usage[top_channel]:,} msg, {percent(self.channel_usage[top_channel]/channel_sum)})"
if show_top_channel
else "",
f"- **most contributed channel**: {channel_mention(found_in)} ({self.channel_usage[found_in]:,} msg, {percent(self.channel_usage[found_in]/self.channel_total[found_in])} of {type})"
f"- **most contributed channel**: {channel_mention(found_in)} ({self.channel_usage[found_in]:,} msg,)"
if show_top_channel and member_specific
else "",
f"- **was mentioned**: {plural(mention_sum, 'time')} ({percent(mention_sum/val_sum(self.mention_count))} of {type})"
f"- **was mentioned**: {plural(mention_sum, 'time')}"
if member_specific and len(self.mentions) > 0
else "",
f"- **mostly mentioned by**: {mention(top_mention)} ({plural(self.mentions[top_mention], 'time')}, {percent(self.mentions[top_mention]/mention_sum)})"
if member_specific and len(self.mentions) > 0
else "",
f"- **mentioned others**: {plural(mention_others_sum, 'time')} ({percent(mention_others_sum/val_sum(self.mention_count))} of {type})"
f"- **mentioned others**: {plural(mention_others_sum, 'time')}"
if len(self.mention_others) > 0 and member_specific
else "",
f"- **mostly mentioned**: {mention(top_mention_others)} ({plural(self.mention_others[top_mention_others], 'time')}, {percent(self.mention_others[top_mention_others]/mention_others_sum)})"
@@ -81,7 +81,7 @@ class Presence:
f"- **reactions**: {plural(total_reaction_used, 'time')}"
if len(self.reactions) > 0 and not member_specific
else "",
f"- **reactions**: {plural(total_reaction_used, 'time')} ({percent(total_reaction_used/val_sum(self.used_reaction))} of {type})"
f"- **reactions**: {plural(total_reaction_used, 'time')}"
if len(self.reactions) > 0 and member_specific
else "",
f"- **top reactions**: {mention(top_reaction_member)} ({plural(self.used_reaction[top_reaction_member], 'time')}, {percent(self.used_reaction[top_reaction_member]/val_sum(self.used_reaction))})"
+2 -2
View File
@@ -66,8 +66,8 @@ class ChannelLogs:
is_empty = self.last_message_id is None
try:
if is_empty:
sanity_check = len(await channel.history(limit=1).flatten())
if sanity_check != 1:
sanity_check = len([message async for message in channel.history(limit=1)])
if sanity_check < 1:
yield len(self.messages), True
return
# load backward
+2 -2
View File
@@ -30,8 +30,8 @@ CRYPT_KEY = os.getenv("CRYPT_KEY", "")
# 5 minutes, assume 'fast' arg
MIN_MODIFICATION_TIME = int(os.getenv("MAX_MODIFICATION_TIME", 5 * 60))
# 30 days, remove log file
MAX_MODIFICATION_TIME = int(os.getenv("MAX_MODIFICATION_TIME", 30 * 24 * 60 * 60))
# 90 days, remove log file
MAX_MODIFICATION_TIME = int(os.getenv("MAX_MODIFICATION_TIME", 90 * 24 * 60 * 60))
class Worker:
def __init__(
+1 -1
View File
@@ -18,7 +18,7 @@ emojis.load_emojis()
bot = Bot(
"Discord Analyst",
"1.17.0",
"1.17.5",
alias="%",
)
+3 -2
View File
@@ -18,6 +18,7 @@ from utils import (
command_cache,
FilterLevel,
SPLIT_TOKEN,
utc_now
)
from logs import (
GuildLogs,
@@ -131,7 +132,7 @@ class Scanner(ABC):
self.start_date = None if len(dates) < 1 else min(dates)
self.stop_date = None if len(dates) < 2 else max(dates)
if self.start_date is not None and self.start_date > datetime.now():
if self.start_date is not None and self.start_date > utc_now():
await message.channel.send(
f"Start date is after today", reference=message
)
@@ -228,7 +229,7 @@ class Scanner(ABC):
),
)
if self.stop_date is None:
self.stop_date = datetime.utcnow()
self.stop_date = utc_now()
self.msg_count = 0
self.total_msg = 0
+2 -2
View File
@@ -13,7 +13,7 @@ arguments:
TEXT = """
__**About Analyst-bot's data usage**__
**TL;DR**
Analyst-bot collects text message information. It does not share collected data with any third-party and data is retained 18 months or until the bot is leaving the guild/server.
Analyst-bot collects text message information. It does not share collected data with any third-party and data is retained 90 days or until the bot is leaving the guild/server.
**Data collection**
Analyst-bot collects a Discord guild/server's history when asked to.
This includes:
@@ -27,7 +27,7 @@ This does __not__ includes:
Any data collected is only processed in order to produce a one-time report sent to the user immediately. No temporary data are retained.
**Data storage and retain policy**
Analyst-bot stores the collected data in files that are accessible by the software and its administrator only.
Any collected data are retained maximum 30 days until deletion or when the bot is leaving a guild/server.
Any collected data are retained maximum 90 days until deletion or when the bot is leaving a guild/server.
**Data sharing**
Analyst-bot does not share the data collected with any third-party.
**Right to retract**
+14 -8
View File
@@ -4,7 +4,7 @@ import os
import logging
import discord
import math
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
import re
import time
import dateutil.parser
@@ -116,7 +116,7 @@ def escape_text(text: str) -> str:
return discord.utils.escape_markdown(discord.utils.escape_mentions(text))
class FakeMessage:
class FakeMessage(discord.abc.Snowflake):
def __init__(self, id: int):
self.id = id
@@ -258,13 +258,19 @@ def parse_iso_datetime(str_date: str) -> datetime:
RELATIVE_REGEX = r"(yesterday|today|\d*hours?|\d+h(ours?)?|\d*days?|\d+d(ays?)?|\d*weeks?|\d+w(eeks?)?|\d*months?|\d+m(onths?)?|\d*years?|\d+y(ears?)?)"
def utc_now() -> datetime:
return datetime.now(tz=timezone.utc)
def utc_today() -> datetime:
today = utc_now().date()
return datetime(today.year, today.month, today.day, tzinfo=timezone.utc)
def parse_relative_time(src: str) -> datetime:
today = datetime.utcnow().date()
today = datetime(today.year, today.month, today.day)
if src == "today":
return today
return utc_today()
elif src == "yesterday":
return today - relativedelta(days=1)
return utc_today() - relativedelta(days=1)
else:
m = re.match("(\d*)(\w+)", src)
delta = None
@@ -280,7 +286,7 @@ def parse_relative_time(src: str) -> datetime:
delta = relativedelta(months=value)
elif unit == "y":
delta = relativedelta(years=value)
return datetime.utcnow() - delta
return utc_now() - delta
def parse_time(src: str) -> datetime:
@@ -344,7 +350,7 @@ def get_intro(
"""
time_text = ""
if start_datetime is not None:
stop_datetime = datetime.now() if stop_datetime is None else stop_datetime
stop_datetime = utc_now() if stop_datetime is None else stop_datetime
time_text = f" (in {str_delta(stop_datetime - start_datetime)})"
# Show all data (members, channels) when it's less than 5 units
if len(members) == 0: