Compare commits

...

6 Commits

10 changed files with 153 additions and 8 deletions

View File

@ -15,7 +15,7 @@ import settings
class HebdoBot(IrcBot): class HebdoBot(IrcBot):
def __init__(self, settings): def __init__(self, settings):
super().__init__(settings) super().__init__(settings)
self.VERSION = "3.0.0" self.VERSION = "3.1.0"
self.review = Review() self.review = Review()
for event in events: for event in events:
@ -65,7 +65,7 @@ class HebdoBot(IrcBot):
""" """
channel = event.target channel = event.target
sender = event.source.nick sender = event.source.nick
message = event.arguments[0] message = event.arguments[0].strip()
if self.review.is_started: if self.review.is_started:
self.review.add_message(sender, message) self.review.add_message(sender, message)

View File

@ -3,6 +3,7 @@ from .bad_command import BadCommand
from .cancel_previous_input import CancelPreviousInput from .cancel_previous_input import CancelPreviousInput
from .collective_subject import CollectiveSubject from .collective_subject import CollectiveSubject
from .comment import Comment from .comment import Comment
from .completion import Completion
from .chrono import Chrono from .chrono import Chrono
from .current import Current from .current import Current
from .date import Date from .date import Date
@ -36,6 +37,7 @@ hooks = (
Help(), Help(),
IndividualSubject(), IndividualSubject(),
Missing(), Missing(),
Completion(),
Record(), Record(),
StartReview(), StartReview(),
StopReview(), StopReview(),

44
hooks/completion.py Normal file
View File

@ -0,0 +1,44 @@
import logger
class Completion:
def process(self, bot, channel, sender, message):
"""
Si la commande est bonne, le bot renvoie la liste des personnes ayant participé
au sujet en cours mais n'ayant pas encore fini (commentaire %fini ou % fini).
"""
if message.lower() == "!complet":
logger.info("!complet caught.")
if not bot.review.is_started:
bot.send(channel, f"{sender}, pas de revue en cours.")
return True
if bot.review.current_topic is None:
bot.send(channel, "% Pas de sujet en cours.")
return True
participants = bot.review.current_topic.participants
find_text = f"# {bot.review.current_topic.title}"
if bot.review.current_topic.collective:
find_text = "#" + find_text
text_found = False
for message in bot.review.messages:
if text_found:
if message.text in ("%fini", "% fini", "%ras", "% ras"):
participants = list(set(participants) - set((message.author,)))
if find_text == message.text:
text_found = True
if participants == []:
bot.send(
channel,
"% Tout le monde a terminé de s'exprimer sur le sujet courant \\o/",
)
else:
bot.send(
channel,
"% Personnes n'ayant pas encore terminé de s'exprimer sur le "
f"sujet courant : {', '.join(participants)}",
)
return True

View File

@ -30,9 +30,9 @@ class Help:
" !fin : terminer la revue en cours", " !fin : terminer la revue en cours",
" !stop  : abandonner la revue en cours", " !stop  : abandonner la revue en cours",
" ", " ",
"Autres commandes : !anniv, !bonjour, !chrono, !date, !hello, " "Autres commandes : !anniv, !bonjour, !chrono, !complet, !date, "
"!licence, !manquantes, !merci, !record, !salut, !stats, !status, " "!hello, !licence, !manquantes, !merci, !record, !salut, !stats, "
"!version", "!status, !version",
), ),
) )

View File

@ -6,7 +6,7 @@ class StopReview:
""" """
Si la commande est bonne, le bot abandonne la revue hebdomadaire en cours. Si la commande est bonne, le bot abandonne la revue hebdomadaire en cours.
""" """
if message.lower() in ("!stop"): if message.lower() == "!stop":
logger.info("!stop caught.") logger.info("!stop caught.")
if not bot.review.is_started: if not bot.review.is_started:

View File

@ -174,7 +174,10 @@ class ReviewStats:
def save(self): def save(self):
with open(self.filepath, "w") as file_handle: with open(self.filepath, "w") as file_handle:
for data in self.datas: for data in self.datas:
duration = ""
if data.duration is not None:
duration = f"\t{data.duration}"
file_handle.write( file_handle.write(
f"{data.date.strftime('%Y%m%d-%Hh%M')}\t" f"{data.date.strftime('%Y%m%d-%Hh%M')}\t"
f"{data.user_count}\t{data.duration}\n" f"{data.user_count}{duration}\n"
) )

View File

@ -10,3 +10,11 @@ def test_private_command(bot):
bot.test_private_message(bot.channel, SENDER, "!hello") bot.test_private_message(bot.channel, SENDER, "!hello")
assert len(bot.answers) == 1 assert len(bot.answers) == 1
assert bot.answers[0].message == "Vos commandes dans le salon public" assert bot.answers[0].message == "Vos commandes dans le salon public"
def test_public_message(bot):
# Cheating here to save message sent
bot.review.started = True
bot.test_public_message(bot.channel, SENDER, " hello ")
assert len(bot.answers) == 0
assert bot.review.messages[0].text == "hello"

View File

@ -1,6 +1,7 @@
from datetime import datetime from datetime import datetime
import shutil import shutil
from review.stats import ReviewStats
from tests.utils import bot, OWNER, SENDER from tests.utils import bot, OWNER, SENDER
@ -52,3 +53,38 @@ def test_other_review(bot):
with open("tests/reviews/20240402-log-irc-revue-hebdomadaire.txt") as file_handle: with open("tests/reviews/20240402-log-irc-revue-hebdomadaire.txt") as file_handle:
content_tested = file_handle.read() content_tested = file_handle.read()
assert content_ok in content_tested assert content_ok in content_tested
def test_fast_review(bot):
bot.test_public_message(bot.channel, "lllll", "!start")
bot.test_public_message(bot.channel, "lllll", "# new test")
bot.test_public_message(bot.channel, "lllll", "test")
bot.test_public_message(bot.channel, "lllll", "!fin")
bot.test_public_message(bot.channel, "lllll", "!stats")
def test_review_with_one_user_dont_update_stats(bot):
review = ReviewStats("tests/reviews/reviewstats.csv")
review.load()
size = review.size
bot.test_public_message(bot.channel, "lllll", "!start")
bot.test_public_message(bot.channel, "lllll", "# new test")
bot.test_public_message(bot.channel, "lllll", "test")
bot.test_public_message(bot.channel, "lllll", "!fin")
review = ReviewStats("tests/reviews/reviewstats.csv")
review.load()
assert review.size == size
def test_review_with_two_user_update_stats(bot):
review = ReviewStats("tests/reviews/reviewstats.csv")
review.load()
size = review.size
bot.test_public_message(bot.channel, "lllll", "!start")
bot.test_public_message(bot.channel, "lllll", "# new test")
bot.test_public_message(bot.channel, "lllll", "test")
bot.test_public_message(bot.channel, "ooooo", "another test")
bot.test_public_message(bot.channel, "lllll", "!fin")
review = ReviewStats("tests/reviews/reviewstats.csv")
review.load()
assert review.size == (size + 1)

View File

@ -1,7 +1,7 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
import shutil import shutil
from tests.utils import bot, OWNER, SENDER from tests.utils import bot, OWNER, SENDER, SENDER_2
def setup_function(): def setup_function():
@ -515,3 +515,54 @@ def test_finish_review_no_participation(bot):
bot.test_public_message(bot.channel, OWNER, "!fin") bot.test_public_message(bot.channel, OWNER, "!fin")
assert len(bot.answers) == 1 assert len(bot.answers) == 1
assert bot.answers[0].message == "Participation nulle détectée. La revue est ignorée." assert bot.answers[0].message == "Participation nulle détectée. La revue est ignorée."
def test_simple_completion_on_topic(bot):
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, SENDER_2, "Sender_2 message on individual topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, OWNER, "!complet")
assert len(bot.answers) == 1
assert SENDER_2 not in bot.answers[0].message[76:]
assert SENDER in bot.answers[0].message[76:]
assert OWNER in bot.answers[0].message[76:]
def test_semi_completion_on_topic(bot):
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, SENDER_2, "Sender_2 message on individual topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, SENDER_2, "%ras")
bot.test_public_message(bot.channel, SENDER, "%fini")
bot.test_public_message(bot.channel, OWNER, "!complet")
assert len(bot.answers) == 1
assert SENDER_2 not in bot.answers[0].message[76:]
assert SENDER not in bot.answers[0].message[76:]
assert OWNER in bot.answers[0].message[76:]
def test_total_completion_on_topic(bot):
bot.test_public_message(bot.channel, OWNER, "!start")
bot.test_public_message(bot.channel, OWNER, "# individual topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on individual topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on individual topic")
bot.test_public_message(bot.channel, SENDER_2, "Sender_2 message on individual topic")
bot.test_public_message(bot.channel, OWNER, "## collective topic")
bot.test_public_message(bot.channel, OWNER, "Owner message on collective topic")
bot.test_public_message(bot.channel, SENDER, "Sender message on collective topic")
bot.test_public_message(bot.channel, SENDER_2, "%ras")
bot.test_public_message(bot.channel, SENDER, "%fini")
bot.test_public_message(bot.channel, OWNER, "% fini")
bot.test_public_message(bot.channel, OWNER, "!complet")
assert len(bot.answers) == 1
assert SENDER_2 + "," not in bot.answers[0].message[76:]
assert SENDER + "," not in bot.answers[0].message[76:]
assert OWNER + "," not in bot.answers[0].message[76:]

View File

@ -7,6 +7,7 @@ from tests import settings
OWNER = "me" OWNER = "me"
SENDER = "foobar" SENDER = "foobar"
SENDER_2 = "foobaz"
@dataclass @dataclass