forked from mindiell/hebdobot
251 lines
8.2 KiB
Python
251 lines
8.2 KiB
Python
from datetime import datetime
|
|
import locale
|
|
from textwrap import fill
|
|
|
|
from bot.review.topic import Message, Topic
|
|
from bot.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 start(self, owner):
|
|
self.started = True
|
|
self.owner = owner
|
|
self.start_time = datetime.today()
|
|
|
|
def close(self):
|
|
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.datas[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.datas[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
|