hebdobot/review/review.py
2024-04-06 10:03:48 +02:00

259 lines
8.4 KiB
Python

from datetime import datetime
import locale
from textwrap import fill
from review.topic import Message, Topic
from review.aliases import Aliases
LENGTH_LINE = 80
class Review:
def __init__(self):
self.participants = []
self.topics = []
self.messages = []
self.owner = None
self.started = False
self.ended = False
self.start_time = None
self.end_time = None
@property
def is_started(self):
return self.started
@property
def is_ended(self):
return self.ended
@property
def last_topic(self):
if len(self.topics) >= 2:
return self.topics[-2]
@property
def current_topic(self):
if len(self.topics) > 0:
return self.topics[-1]
@property
def has_participants(self):
return len(self.participants) > 0
@property
def individual_topics(self):
return [topic for topic in self.topics if topic.individual]
@property
def collective_topics(self):
return [topic for topic in self.topics if topic.collective]
@property
def has_individual_topic(self):
return len(self.individual_topics) > 0
@property
def has_collective_topic(self):
return len(self.collective_topics) > 0
@property
def user_count(self):
return len(self.participants)
@property
def duration(self):
return (self.end_time - self.start_time).seconds // 60 if self.ended else None
@property
def year(self):
return self.start_time.year
def is_owner(self, owner):
return owner.lower() == self.owner.lower()
def new_topic(self, title, collective=True):
self.topics.append(Topic(title, collective))
def new_collective_topic(self, title):
self.new_topic(title)
def new_individual_topic(self, title):
self.new_topic(title, False)
def add_message(self, sender, message):
self.messages.append(Message(sender, message))
def add_input(self, sender, message):
if self.current_topic:
if sender not in self.participants:
self.participants.append(sender)
self.current_topic.add_message(sender, message)
def add_participant(self, sender):
if self.current_topic:
if sender not in self.participants:
self.participants.append(sender)
self.current_topic.add_participant(sender)
def start(self, owner):
self.started = True
self.ended = False
self.owner = owner
self.start_time = datetime.today()
def close(self):
self.started = False
self.ended = True
self.end_time = datetime.today()
def cancel(self):
self.participants = []
self.topics = []
self.messages = []
self.owner = None
self.started = False
self.ended = False
self.start_time = None
self.end_time = None
def report(self, stats, user_aliases_filepath):
locale.setlocale(locale.LC_ALL, "fr_FR.utf8")
formatter = "%A %d %B %Y"
hour_formatter = "%Hh%M"
aliases = Aliases(user_aliases_filepath)
def add_center(text, character=" "):
text_size = len(text) + 2
left_size = (LENGTH_LINE - text_size) // 2
right_size = LENGTH_LINE - left_size - text_size
result = character * left_size + " " + text
if character != " ":
result += " " + character * right_size
result += "\n"
return result
content = "=" * LENGTH_LINE + "\n"
content += add_center("Revue de la semaine en cours")
content += "\n"
content += add_center(self.start_time.strftime(formatter))
content += "=" * LENGTH_LINE + "\n"
content += "\n"
content += "\n"
content += "=" * LENGTH_LINE + "\n"
content += "\n"
content += add_center("Personnes participantes", "-")
for participant in self.participants:
content += f"* {aliases[participant]} ({participant})\n"
if self.has_individual_topic:
for participant in self.participants:
content += "\n"
content += "=" * LENGTH_LINE + "\n"
content += "\n"
content += add_center(f"{aliases[participant]} ({participant})", "-")
for topic in self.individual_topics:
if topic.has_participant(participant):
content += "\n"
content += f"=== {topic.title} ===\n"
content += "\n"
for message in topic.get_messages(participant):
content += fill(f"* {message.text}", width=LENGTH_LINE)
content += "\n"
if self.has_collective_topic:
for topic in self.collective_topics:
content += "\n"
content += "=" * LENGTH_LINE + "\n"
content += add_center(topic.title)
content += "=" * LENGTH_LINE + "\n"
content += "\n"
for message in topic.get_messages():
content += fill(
f"* {message.author} : {message.text}",
width=LENGTH_LINE,
)
content += "\n"
content += "\n"
content += add_center("Log IRC brut")
content += "\n"
for message in self.messages:
content += fill(f"* {message.author} : {message.text}\n", width=LENGTH_LINE)
content += "\n"
# Add statistics
content += "\n"
content += add_center("Statistiques")
content += "\n"
content += (
f"C'était la {stats.size + 1}e revue hebdomadaire de l'April, "
f"la {stats.year_review(self.year) + 1}e de l'année {self.year}.\n"
)
content += (
"Horaire de début de la revue : "
f"{self.start_time.strftime(hour_formatter)}\n"
)
content += (
"Horaire de fin de la revue : "
f"{self.end_time.strftime(hour_formatter)}\n"
)
content += f"Durée de la revue : {self.duration} minutes\n"
content += f"Nombre de personnes participantes : {self.user_count}\n"
if self.user_count < stats.max_users:
content += (
"La participation moyenne aux revues est "
f"de {stats.avg_users:.1f} personnes.\n"
)
elif self.user_count == stats.max_users:
content += (
"\\o/ Record de participation égalé \\o/ Le précédent record "
f"de {stats.max_users} personnes était le "
f"{stats.biggest.date.strftime(formatter)}.\n"
)
else:
content += (
f"*\\o/* Nouveau record de participation : {self.user_count} "
"personnes ! *\\o/* Le précédent record était de "
f"{stats.max_users} personnes le "
f"{stats.biggest.date.strftime(formatter)}.\n"
)
percentage = (
stats.users_board[self.user_count] / stats.users_board.sum * 100
)
content += fill(
"Statistiques sur la participation à la revue "
f"({self.user_count} personnes) : position "
f"{stats.users_board.position(self.user_count)} "
f"(min.={stats.users_board.min}, "
f"moy.={stats.users_board.avg:.1f}, "
f"max.={stats.users_board.max}) "
f"fréquence {stats.users_board[self.user_count]}"
f"/{stats.users_board.sum} "
f"({percentage:.0f} %) ",
width=LENGTH_LINE,
)
content += "\n"
percentage = (
stats.users_board[self.user_count] / stats.users_board.sum * 100
)
content += fill(
"Statistiques sur la durée de la revue "
f"({self.duration} min) : position "
f"{stats.durations_board.position(self.duration)} "
f"(min.={stats.durations_board.min} min, "
f"moy.={stats.durations_board.avg:.1f} min, "
f"max.={stats.durations_board.max} min) "
f"fréquence {stats.durations_board[self.duration]}"
f"/{stats.durations_board.sum} "
f"({percentage:.0f} %) ",
width=LENGTH_LINE,
)
content += "\n"
return content