diff --git a/src/cogs/citation.py b/src/cogs/citation.py index 34757e2..2eb8732 100644 --- a/src/cogs/citation.py +++ b/src/cogs/citation.py @@ -3,7 +3,8 @@ import re import os from discord.ext import commands customTimezone = os.environ['TIMEZONE'] -from utils.core import goodTimezone, userOrNick +from utils.core import userOrNick +from utils.time import goodTimezone def setup(client): client.add_cog(Citation(client)) diff --git a/src/cogs/confreriedukassoulait.py b/src/cogs/confreriedukassoulait.py index 6019b02..393da6b 100644 --- a/src/cogs/confreriedukassoulait.py +++ b/src/cogs/confreriedukassoulait.py @@ -6,7 +6,8 @@ from random import choice from datetime import datetime from pytz import timezone customTimezone = os.environ['TIMEZONE'] -from utils.core import goodTimezone, userOrNick +from utils.core import userOrNick +from utils.time import goodTimezone from cogs.internet import Internet def setup(client): diff --git a/src/cogs/utils.py b/src/cogs/utils.py index 3a695de..c3c1833 100644 --- a/src/cogs/utils.py +++ b/src/cogs/utils.py @@ -1,5 +1,4 @@ import discord -import time import os import re from discord.ext import commands, tasks @@ -8,9 +7,9 @@ from datetime import datetime from pytz import timezone from discord_slash import cog_ext from utils.reminder import Reminder -from utils.core import map_list_among_us, get_age, getURLsInString, getMentionInString, cleanCodeStringWithMentionAndURLs -from utils.core import cleanUser, userOrNick, ageLayout, stringTempsVersSecondes, timedeltaToString, intToTimestamp, nowTimestampUTC -from utils.core import timestampFR +from utils.core import map_list_among_us, getURLsInString, getMentionInString, cleanCodeStringWithMentionAndURLs +from utils.core import cleanUser, userOrNick +from utils.time import stringTempsVersSecondes, nowUTC, intToDatetime, timedeltaToString, timestampScreen, getAge, ageLayout, nowCustom def setup(client): client.add_cog(Utils(client)) @@ -36,22 +35,22 @@ class Utils(commands.Cog): arg = None if arg == 'help': - return await ctx.send(embed = discord.Embed(color = discord.Colour.random(), description = ":hourglass: correspond au temps entre deux battements de cœurs\n\n:stopwatch: correspond au temps que met le client a calculer le ping\n\n:heartbeat: correspond au temps que met le client a réagir au messages")) + return await ctx.send(embed = discord.Embed(color = discord.Colour.random(), description = ":hourglass: correspond au temps entre deux battements de cœurs\n\n:heartbeat: correspond au temps que met le client a réagir au messages (0 est normal lors de l'utilisation d'une commande slash)\n\n:stopwatch: correspond au temps que met le client a calculer le ping")) else: - now = int(round(time.time() * 1000)) + now = int(round(nowCustom() * 1000)) if fromSlash != True: ping = now - int(round(ctx.message.created_at.timestamp() * 1000)) else: ping = now - int(round(ctx.slash_created_at * 1000)) embed = discord.Embed(description = 'Pinging...') message = await ctx.send(embed = embed) - ping2 = int(round(time.time() * 1000)) - now - await message.edit(embed = discord.Embed(color = discord.Colour.random(), description = f':hourglass: {round(self.client.latency * 1000)} ms\n\n:stopwatch: {ping2} ms\n\n:heartbeat: {ping} ms')) + ping2 = int(round(nowCustom() * 1000)) - now + await message.edit(embed = discord.Embed(color = discord.Colour.random(), description = f':hourglass: {round(self.client.latency * 1000)} ms\n\n:heartbeat: {ping} ms\n\n:stopwatch: {ping2} ms')) if fromSlash != True: await ctx.message.add_reaction(emoji = '✅') @cog_ext.cog_slash(name="ping", description = "Affiche mon ping, mettre 'help' en argument pour connaître à quoi correspond les données.") async def __ping(self, ctx, arg = None): - ctx.slash_created_at = int(datetime.now(timezone(self.customTimezone)).timestamp()) + ctx.slash_created_at = nowCustom() if arg == None: return await self._ping(ctx, True) else: @@ -227,7 +226,7 @@ class Utils(commands.Cog): await ctx.message.delete() embed = discord.Embed(description = text, color = discord.Colour.random()) embed.set_author(name = f"Mémo noté depuis {ctx.guild.name}", icon_url = ctx.author.avatar_url) - embed.set_footer(text = f'📝 le {datetime.now(timezone(self.customTimezone)).strftime("%d/%m/%Y à %H:%M:%S")}') + embed.set_footer(text = f'📝 le {timestampScreen(intToDatetime(nowUTC()))}') await ctx.author.send(embed = embed) return await ctx.send("Tu viens de recevoir ton mémo !", delete_after = 5) @_memo.error @@ -368,14 +367,14 @@ class Utils(commands.Cog): value = str(user[0].created_at.astimezone(timezone(self.customTimezone)))[:-13].replace('-', '/').split() embed.add_field(name = "Compte créé le", value = f"{value[0][8:]}/{value[0][5:-3]}/{value[0][:4]} à {value[1]}") - embed.add_field(name = "Âge du compte", value = ageLayout(get_age(user[0].created_at))) + embed.add_field(name = "Âge du compte", value = ageLayout(getAge(user[0].created_at))) embed.add_field(name = "Mention", value = user[0].mention) value = str(user[0].joined_at.astimezone(timezone(self.customTimezone)))[:-13].replace('-', '/').split() embed.add_field(name = "Serveur rejoint le", value = f"{value[0][8:]}/{value[0][5:-3]}/{value[0][:4]} à {value[1]}") - embed.add_field(name = "Est sur le serveur depuis", value = ageLayout(get_age(user[0].joined_at))) + embed.add_field(name = "Est sur le serveur depuis", value = ageLayout(getAge(user[0].joined_at))) if fromSlash != True: await ctx.message.add_reaction(emoji = '✅') return await ctx.send(embed = embed) @@ -510,7 +509,7 @@ class Utils(commands.Cog): elif seconds > 7776000: # 90 * 60 * 60 * 24 embed.add_field(name="Attention", value="Tu as spécifié une durée trop longue, la durée maximum étant de 90 jours.") else: - now = int(nowTimestampUTC()) + now = int(nowUTC()) messageID = None if fromSlash != True: messageID = ctx.message.id @@ -526,7 +525,7 @@ class Utils(commands.Cog): @tasks.loop(minutes = 1) async def _reminderLoop(self): - expiration = Reminder().recuperationExpiration(int(nowTimestampUTC())) + expiration = Reminder().recuperationExpiration(int(nowUTC())) for expired in expiration: message = f"<@{expired[4]}>" reminder = expired[2] @@ -539,8 +538,8 @@ class Utils(commands.Cog): if sourceMessage != None: sourceMessage = await channel.fetch_message(sourceMessage) await sourceMessage.add_reaction(emoji = '✅') - finalEmbed = discord.Embed(description = cleanCodeStringWithMentionAndURLs(reminder), timestamp = intToTimestamp(expired[3]), color = discord.Colour.random()) - finalEmbed.set_footer(text=f"Message d'il y a {timedeltaToString(int(nowTimestampUTC()) - expired[3])}") + finalEmbed = discord.Embed(description = cleanCodeStringWithMentionAndURLs(reminder), timestamp = intToDatetime(expired[3]), color = discord.Colour.random()) + finalEmbed.set_footer(text=f"Message d'il y a {timedeltaToString(int(nowUTC()) - expired[3])}") links = "" findedURLs = getURLsInString(reminder) @@ -577,12 +576,12 @@ class Utils(commands.Cog): texte = reminder[0] if len(texte) > 1024: texte = f"{texte[:1021]}..." - expiration = reminder[2] - int(nowTimestampUTC()) + expiration = reminder[2] - int(nowUTC()) if expiration > 0: expiration = f"Expire dans {timedeltaToString(expiration)} +1m de retard max." else: expiration = f"A déjà expiré." - embed.add_field(value = texte, name = f"Fais le {timestampFR(intToTimestamp(reminder[1]))}\n{expiration}", inline = False) + embed.add_field(value = texte, name = f"Fais le {timestampScreen(intToDatetime(reminder[1]))}\n{expiration}", inline = False) else: embed.add_field(name = "\u200b", value = "Vous n'avez aucun rappel en attente !") embed.set_footer(text = "Les rappels qui ont déjà expirés vont apparaître dans quelques instants.") diff --git a/src/utils/core.py b/src/utils/core.py index 21948de..3577f4e 100644 --- a/src/utils/core.py +++ b/src/utils/core.py @@ -1,19 +1,7 @@ import re import json import requests -import os from time import time -from pytz import timezone -from datetime import datetime, timedelta - -myTimezone = os.environ['TIMEZONE'] - -def goodTimezone(date, tz, type = 0): - """renvoie une date en fonction d'un timezone""" - if type == 0: - return str(timezone(tz).fromutc(date))[:-13].replace('-', '/').split() - elif type == 1: - return str(timezone(tz).fromutc(date))[:-13].replace('-', '/').replace(' ', ' à ') def map_list_among_us(map): """Sélecteur de map pour la commande amongus⁢⁢⁢⁢⁢⁢⁢⁢⁢⁢""" @@ -26,41 +14,6 @@ def map_list_among_us(map): return maps["skeld"] + maps["mira"] + maps["polus"] + maps["airship"] return maps[map] -def get_age(date): - """Recupère un age précisément à la seconde près""" - joursRestants = datetime.now() - date - years = joursRestants.total_seconds() / (365.242 * 24 * 3600) - months = (years - int(years)) * 12 - days = (months - int(months)) * (365.242 / 12) - hours = (days - int(days)) * 24 - minutes = (hours - int(hours)) * 60 - seconds = (minutes - int(minutes)) * 60 - return (int(years), int(months), int(days), int(hours), int(minutes), int(seconds)) - -def ageLayout(tuple): - """avec la méthode 'get_age', permet de mettre en forme un âge⁢⁢⁢⁢⁢⁢⁢⁢⁢⁢""" - time = {} - time[0], time[1], time[2], time[3], time[4], time[5] = "an", "mois", "jour", "heure", "minute", "seconde" - for i in range(len(tuple)): - if tuple[i] > 1 and i != 1: - time[i] = time[i] + "s" - message = "" - if tuple[5] > 0: # pour les secondes - affichage = [5] # on affiche que : seconde - if tuple[4] > 0: - affichage = [4, 5] # on affiche : minute + seconde - if tuple[3] > 0: - affichage = [3, 4, 5] # on affiche : heure + minute + seconde - if tuple[2] > 0: - affichage = [2, 3, 4] # on affiche : jour + heure + minute - if tuple[1] > 0: - affichage = [1, 2, 3] # on affiche : mois + jour + heure - if tuple[0] > 0: - affichage = [0, 1, 3] # on affiche : an + mois + heure - for i in affichage: - message = message + f", {tuple[i]} {time[i]}" - return message[2:] - def userOrNick(user): """Affiche le pseudo et/ou le surnom""" if user == None: @@ -154,62 +107,3 @@ def ligneFormatage(ligne): for balises in liste_balise: ligne = ligne.replace(balises[0], balises[1]) return ligne - -def stringTempsVersSecondes(time): - conversionTemps = { - "86400": ["j", "d"], - "3600": ["h"], - "60": ["m"], - "1": ["s", ""] - } - - valeursMultiplicateur = "" - for i in conversionTemps.values(): - for j in i: - valeursMultiplicateur += f"{j}|" - match = re.findall(f'([0-9]+)({valeursMultiplicateur[:-1]})?', time) - - if not match: - return "Veuillez entrer un temps valide." - - remindertime = 0 - for i in match: - for tempsEnSeconde, nomCommun in conversionTemps.items(): - if i[1] in nomCommun: - remindertime += int(tempsEnSeconde) * int(i[0]) - - return remindertime - -def nowTimestampCustom(): - return datetime.now(timezone(myTimezone)).timestamp() - -def UTCTimestampToCustomTimestamp(timestamp): - return timezone(myTimezone).fromutc(timestamp) - -def nowTimestampUTC(): - return datetime.utcnow().timestamp() - -def intToTimestamp(int): - return datetime.fromtimestamp(int) - -def timedeltaToString(time): - age = str(timedelta(seconds = time)).replace('days, ', 'jours, :').split(':') - if len(age) == 4: - a = [1, 1, 1, 1] # a pour affichage - if len(age) == 3: - a = [0, 1, 1, 1] - age.insert(0, None) - for i in range(1, 4): - if int(age[i]) == 0: - a[i] = 0 - age[0] = age[0] if a[0] == 1 else '' - age[1] = f"{age[1]}h " if a[1] == 1 else '' - age[2] = f"{age[2]}m " if a[2] == 1 else '' - age[3] = f"{age[3]}s" if a[3] == 1 else '' - return ''.join(age) - -def timestampFR(timestamp): - date_edit = str(UTCTimestampToCustomTimestamp(timestamp)).replace('-', '/').split(' ') - date = date_edit[0] - heure = date_edit[1].split('+')[0] - return f"{date[8:]}/{date[5:-3]}/{date[:4]} à {heure}" diff --git a/src/utils/time.py b/src/utils/time.py new file mode 100644 index 0000000..341e7bb --- /dev/null +++ b/src/utils/time.py @@ -0,0 +1,114 @@ +from os import environ +from pytz import timezone +from datetime import datetime, timedelta +from re import findall + +myTimezone = environ['TIMEZONE'] + +def stringTempsVersSecondes(time): + """Convertis une durée rentrée par un utilisateur en string vers des secondes en int""" + conversionTemps = { + "86400": ["j", "d"], + "3600": ["h"], + "60": ["m"], + "1": ["s", ""] + } + + valeursMultiplicateur = "" + for i in conversionTemps.values(): + for j in i: + valeursMultiplicateur += f"{j}|" + match = findall(f'([0-9]+)({valeursMultiplicateur[:-1]})?', time) + + if not match: + return "Veuillez entrer un temps valide." + + remindertime = 0 + for i in match: + for tempsEnSeconde, nomCommun in conversionTemps.items(): + if i[1] in nomCommun: + remindertime += int(tempsEnSeconde) * int(i[0]) + + return remindertime + +def nowCustom(): + """Heure de maintenant avec fuseau horaire local en float""" + return datetime.now(timezone(myTimezone)).timestamp() + +def nowUTC(): + """Heure de maintenant en UTC en float""" + return datetime.utcnow().timestamp() + +def UTCDatetimeToCustomDatetime(datetime): + """Conversion d'une timestamp UTC en timestamp local en datetime""" + return timezone(myTimezone).fromutc(datetime) + +def intToDatetime(intOrFloat): + """Convertis un int ou float en Datetime""" + return datetime.fromtimestamp(intOrFloat) + +def timestampScreen(timestamp): + """Affichage d'une timestamp""" + date_edit = str(UTCDatetimeToCustomDatetime(timestamp)).replace('-', '/').split(' ') + date = date_edit[0] + heure = date_edit[1].split('+')[0] + return f"{date[8:]}/{date[5:-3]}/{date[:4]} à {heure.split('.')[0]}" + +def timedeltaToString(time): + """Différence entre une heure en seconde et maintenant""" + age = str(timedelta(seconds = time)).replace('days, ', 'jours, :').split(':') + if len(age) == 4: + a = [1, 1, 1, 1] # a pour affichage + if len(age) == 3: + a = [0, 1, 1, 1] + age.insert(0, None) + for i in range(1, 4): + if int(age[i]) == 0: + a[i] = 0 + age[0] = age[0] if a[0] == 1 else '' + age[1] = f"{age[1]}h " if a[1] == 1 else '' + age[2] = f"{age[2]}m " if a[2] == 1 else '' + age[3] = f"{age[3]}s" if a[3] == 1 else '' + return ''.join(age) + +def getAge(date): + """Recupère un age précisément à la seconde près""" + joursRestants = datetime.now() - date + years = joursRestants.total_seconds() / (365.242 * 24 * 3600) + months = (years - int(years)) * 12 + days = (months - int(months)) * (365.242 / 12) + hours = (days - int(days)) * 24 + minutes = (hours - int(hours)) * 60 + seconds = (minutes - int(minutes)) * 60 + return (int(years), int(months), int(days), int(hours), int(minutes), int(seconds)) + +def ageLayout(tuple): + """avec la méthode 'getAge', permet de mettre en forme un âge⁢⁢⁢⁢⁢⁢⁢⁢⁢⁢""" + time = {} + time[0], time[1], time[2], time[3], time[4], time[5] = "an", "mois", "jour", "heure", "minute", "seconde" + for i in range(len(tuple)): + if tuple[i] > 1 and i != 1: + time[i] = time[i] + "s" + message = "" + if tuple[5] > 0: # pour les secondes + affichage = [5] # on affiche que : seconde + if tuple[4] > 0: + affichage = [4, 5] # on affiche : minute + seconde + if tuple[3] > 0: + affichage = [3, 4, 5] # on affiche : heure + minute + seconde + if tuple[2] > 0: + affichage = [2, 3, 4] # on affiche : jour + heure + minute + if tuple[1] > 0: + affichage = [1, 2, 3] # on affiche : mois + jour + heure + if tuple[0] > 0: + affichage = [0, 1, 3] # on affiche : an + mois + heure + for i in affichage: + message = message + f", {tuple[i]} {time[i]}" + return message[2:] + +def goodTimezone(date, tz, type = 0): + """Renvoie une date en fonction d'un timezone""" + if type == 0: + return str(timezone(tz).fromutc(date))[:-13].replace('-', '/').split() + elif type == 1: + return str(timezone(tz).fromutc(date))[:-13].replace('-', '/').replace(' ', ' à ')