WIP: Added consent durations and modified default embed colors (#51)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Literal, Any, Dict, Optional
|
||||
from typing import Any, Dict, Optional
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from bson import ObjectId
|
||||
@@ -33,11 +33,15 @@ class Consent(BaseCacheable):
|
||||
_id: ObjectId
|
||||
user_id: int
|
||||
guild_id: int
|
||||
scope: Literal[ConsentScope.GENERAL, ConsentScope.INTEGRATION_DEEPL]
|
||||
scope: ConsentScope
|
||||
consent_date: datetime
|
||||
expiration_date: datetime | None
|
||||
withdrawal_date: datetime | None
|
||||
|
||||
@staticmethod
|
||||
def get_cache_key(user_id: int, guild_id: int, scope: ConsentScope) -> str:
|
||||
return f"{Consent.__short_name__}_{user_id}_{guild_id}_{scope.value}"
|
||||
|
||||
# TODO Implement this method
|
||||
@classmethod
|
||||
async def from_id(cls, id: ObjectId, cache: Optional[Cache] = None, **kwargs: Any) -> Any:
|
||||
@@ -53,7 +57,7 @@ class Consent(BaseCacheable):
|
||||
cache: Optional[Cache] = None,
|
||||
) -> Any:
|
||||
cached_entry: Dict[str, Any] | None = restore_from_cache(
|
||||
cls.__short_name__, f"{user_id}_{guild_id}_{scope.value}", cache=cache
|
||||
cls.__short_name__, Consent.get_cache_key(user_id, guild_id, scope), cache=cache
|
||||
)
|
||||
|
||||
if cached_entry is not None:
|
||||
@@ -73,7 +77,7 @@ class Consent(BaseCacheable):
|
||||
|
||||
if cache is not None:
|
||||
cache.set_json(
|
||||
f"{cls.__short_name__}_{user_id}_{guild_id}_{scope.value}",
|
||||
Consent.get_cache_key(user_id, guild_id, scope),
|
||||
cls._entry_to_cache(db_entry),
|
||||
)
|
||||
|
||||
@@ -81,6 +85,8 @@ class Consent(BaseCacheable):
|
||||
|
||||
@classmethod
|
||||
def from_entry(cls, db_entry: Dict[str, Any]) -> "Consent":
|
||||
db_entry["scope"] = ConsentScope(db_entry["scope"])
|
||||
|
||||
return cls(**db_entry)
|
||||
|
||||
# TODO Add documentation
|
||||
@@ -108,7 +114,7 @@ class Consent(BaseCacheable):
|
||||
|
||||
if cache is not None:
|
||||
cache.set_json(
|
||||
f"{cls.__short_name__}_{user_id}_{guild_id}_{scope.value}",
|
||||
Consent.get_cache_key(user_id, guild_id, scope),
|
||||
cls._entry_to_cache(db_entry),
|
||||
)
|
||||
|
||||
@@ -143,7 +149,7 @@ class Consent(BaseCacheable):
|
||||
)
|
||||
|
||||
def _get_cache_key(self) -> str:
|
||||
return f"{self.__short_name__}_{self.user_id}_{self.guild_id}_{self.scope.value}"
|
||||
return self.get_cache_key(self.user_id, self.guild_id, self.scope)
|
||||
|
||||
@staticmethod
|
||||
def _entry_to_cache(db_entry: Dict[str, Any]) -> Dict[str, Any]:
|
||||
|
||||
@@ -209,7 +209,7 @@ class PycordUser(BaseCacheable):
|
||||
cache: Optional[Cache] = None,
|
||||
) -> None:
|
||||
# TODO Test this query
|
||||
async for consent_entry in Consent.__collection__.find(
|
||||
await Consent.__collection__.update_many(
|
||||
{
|
||||
"user_id": self.id,
|
||||
"guild_id": self.guild_id,
|
||||
@@ -219,6 +219,9 @@ class PycordUser(BaseCacheable):
|
||||
{"expiration_date": {"$gte": datetime.now(tz=ZoneInfo("UTC"))}},
|
||||
{"expiration_date": None},
|
||||
],
|
||||
}
|
||||
):
|
||||
await Consent.from_entry(consent_entry).withdraw(cache)
|
||||
},
|
||||
{"$set": {"withdrawal_date": datetime.now(tz=ZoneInfo("UTC"))}},
|
||||
)
|
||||
|
||||
if cache is not None:
|
||||
cache.delete(Consent.get_cache_key(self.id, self.guild_id, scope))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from logging import Logger
|
||||
from typing import Dict, Any, List
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from discord import (
|
||||
SlashCommandGroup,
|
||||
@@ -12,10 +14,11 @@ from discord import (
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import guild_only
|
||||
from libbot.i18n import _, in_every_locale
|
||||
from tempora import parse_timedelta
|
||||
|
||||
from classes import PycordUser
|
||||
from classes.pycord_bot import PycordBot
|
||||
from enums import ConsentScope
|
||||
from enums import ConsentScope, ConsentDuration
|
||||
|
||||
logger: Logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -43,6 +46,23 @@ class CogConsent(commands.Cog):
|
||||
|
||||
return choices
|
||||
|
||||
@staticmethod
|
||||
def _get_consent_durations() -> List[OptionChoice]:
|
||||
choices: List[OptionChoice] = []
|
||||
|
||||
for duration in ConsentDuration._member_map_.values():
|
||||
duration_value: str = duration.value
|
||||
|
||||
choices.append(
|
||||
OptionChoice(
|
||||
_(duration_value, "data_control", "consent_durations"),
|
||||
duration_value,
|
||||
in_every_locale(duration_value, "data_control", "consent_durations"),
|
||||
)
|
||||
)
|
||||
|
||||
return choices
|
||||
|
||||
# /consent terms <scope>
|
||||
# Will provide information about terms
|
||||
# TODO Implement i18n
|
||||
@@ -107,7 +127,14 @@ class CogConsent(commands.Cog):
|
||||
description="Scope of the consent",
|
||||
choices=_get_scope_choices(),
|
||||
)
|
||||
async def command_consent_give(self, ctx: ApplicationContext, scope: str) -> None:
|
||||
@option(
|
||||
"duration",
|
||||
description="Duration of the consent",
|
||||
choices=_get_consent_durations(),
|
||||
)
|
||||
async def command_consent_give(
|
||||
self, ctx: ApplicationContext, scope: str, duration: str = ConsentDuration.NORMAL.value
|
||||
) -> None:
|
||||
scopes_config: Dict[str, Dict[str, Any]] = self.bot.config["modules"]["consent"][
|
||||
"scopes"
|
||||
]
|
||||
@@ -124,9 +151,18 @@ class CogConsent(commands.Cog):
|
||||
|
||||
user: PycordUser = await self.bot.find_user(ctx.user, ctx.guild_id)
|
||||
|
||||
is_scope_third_party: bool = self.bot.config["modules"]["consent"]["scopes"][scope][
|
||||
"is_third_party"
|
||||
]
|
||||
expiration_date: datetime = datetime.now(tz=ZoneInfo("UTC")) + parse_timedelta(
|
||||
self.bot.config["modules"]["consent"]["durations"][
|
||||
"third_party" if is_scope_third_party else "first_party"
|
||||
][duration]
|
||||
)
|
||||
|
||||
# TODO Implement consent duration
|
||||
try:
|
||||
await user.give_consent(ConsentScope(scope), None, cache=self.bot.cache)
|
||||
await user.give_consent(ConsentScope(scope), expiration_date, cache=self.bot.cache)
|
||||
|
||||
await ctx.respond(
|
||||
embed=self.bot.create_embed_success("Success", "Consent has been given."),
|
||||
@@ -187,6 +223,11 @@ class CogConsent(commands.Cog):
|
||||
name="give_all",
|
||||
description="Give consent to all scopes",
|
||||
)
|
||||
@option(
|
||||
"duration",
|
||||
description="Duration of the consent",
|
||||
choices=_get_consent_durations(),
|
||||
)
|
||||
@guild_only()
|
||||
@option(
|
||||
"confirm",
|
||||
|
||||
@@ -47,9 +47,9 @@
|
||||
"colors": {
|
||||
"primary": "#A4A4A6",
|
||||
"secondary": "#595351",
|
||||
"success": "#4CAF50",
|
||||
"warning": "#FFC107",
|
||||
"error": "#F44336"
|
||||
"success": "#57F287",
|
||||
"warning": "#FEE75C",
|
||||
"error": "#ED4245"
|
||||
},
|
||||
"modules": {
|
||||
"consent": {
|
||||
@@ -67,6 +67,18 @@
|
||||
"terms_url": "https://www.deepl.com/en/terms-of-use",
|
||||
"privacy_url": "https://www.deepl.com/en/privacy"
|
||||
}
|
||||
},
|
||||
"durations": {
|
||||
"first_party": {
|
||||
"short": "1 month",
|
||||
"normal": "12 months",
|
||||
"long": "24 months"
|
||||
},
|
||||
"third_party": {
|
||||
"short": "1 month",
|
||||
"normal": "6 months",
|
||||
"long": "12 months"
|
||||
}
|
||||
}
|
||||
},
|
||||
"leveling": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from .cache_ttl import CacheTTL
|
||||
from .consent_duration import ConsentDuration
|
||||
from .consent_scope import ConsentScope
|
||||
from .embed_color import EmbedColor
|
||||
from .health_status import HealthStatus
|
||||
|
||||
7
enums/consent_duration.py
Normal file
7
enums/consent_duration.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class ConsentDuration(Enum):
|
||||
SHORT = "short"
|
||||
NORMAL = "normal"
|
||||
LONG = "long"
|
||||
@@ -53,6 +53,11 @@
|
||||
"name": "Integration: DeepL",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"consent_durations": {
|
||||
"short": "Short",
|
||||
"normal": "Normal",
|
||||
"long": "Long"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
|
||||
@@ -53,6 +53,11 @@
|
||||
"name": "Integration: DeepL",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"consent_durations": {
|
||||
"short": "Short",
|
||||
"normal": "Normal",
|
||||
"long": "Long"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
|
||||
@@ -67,6 +67,11 @@
|
||||
"name": "Інтеграція: DeepL",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"consent_durations": {
|
||||
"short": "Короткий",
|
||||
"normal": "Звичаний",
|
||||
"long": "Довгий"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
|
||||
@@ -6,6 +6,7 @@ libbot[speed,pycord,cache]==4.4.0
|
||||
mongodb-migrations==1.3.1
|
||||
pynacl~=1.5.0
|
||||
pytz~=2025.1
|
||||
tempora~=5.8.1
|
||||
|
||||
# Temporarily disabled because
|
||||
# these are still unused for now
|
||||
|
||||
Reference in New Issue
Block a user