Compare commits
1 Commits
main
...
reviewstat
Author | SHA1 | Date | |
---|---|---|---|
919bb59859 |
@ -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.1.0"
|
self.VERSION = "3.0.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].strip()
|
message = event.arguments[0]
|
||||||
if self.review.is_started:
|
if self.review.is_started:
|
||||||
self.review.add_message(sender, message)
|
self.review.add_message(sender, message)
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ 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
|
||||||
@ -37,7 +36,6 @@ hooks = (
|
|||||||
Help(),
|
Help(),
|
||||||
IndividualSubject(),
|
IndividualSubject(),
|
||||||
Missing(),
|
Missing(),
|
||||||
Completion(),
|
|
||||||
Record(),
|
Record(),
|
||||||
StartReview(),
|
StartReview(),
|
||||||
StopReview(),
|
StopReview(),
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
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
|
|
@ -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, !complet, !date, "
|
"Autres commandes : !anniv, !bonjour, !chrono, !date, !hello, "
|
||||||
"!hello, !licence, !manquantes, !merci, !record, !salut, !stats, "
|
"!licence, !manquantes, !merci, !record, !salut, !stats, !status, "
|
||||||
"!status, !version",
|
"!version",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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() == "!stop":
|
if message.lower() in ("!stop"):
|
||||||
logger.info("!stop caught.")
|
logger.info("!stop caught.")
|
||||||
|
|
||||||
if not bot.review.is_started:
|
if not bot.review.is_started:
|
||||||
|
@ -9,6 +9,29 @@ class ReviewData:
|
|||||||
user_count: int
|
user_count: int
|
||||||
duration: int
|
duration: int
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return (
|
||||||
|
f"{self.date.strftime('%Y%m%d-%Hh%M')}\t{self.user_count}"
|
||||||
|
f"{f'\t{self.duration}' if self.duration is not None else ''}"
|
||||||
|
"\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load(line: str):
|
||||||
|
datas = re.split(r"\s+", line.strip())
|
||||||
|
if len(datas) == 2:
|
||||||
|
return ReviewData(
|
||||||
|
datetime.strptime(datas[0], "%Y%m%d-%Hh%M"),
|
||||||
|
int(datas[1]),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ReviewData(
|
||||||
|
datetime.strptime(datas[0], "%Y%m%d-%Hh%M"),
|
||||||
|
int(datas[1]),
|
||||||
|
int(datas[2]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Board:
|
class Board:
|
||||||
def __init__(self, datas={}):
|
def __init__(self, datas={}):
|
||||||
@ -148,23 +171,7 @@ class ReviewStats:
|
|||||||
lines = file_handle.read().splitlines()
|
lines = file_handle.read().splitlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if line.strip() != "":
|
if line.strip() != "":
|
||||||
datas = re.split(r"\s+", line)
|
self.datas.append(ReviewData.load(line))
|
||||||
if len(datas) == 2:
|
|
||||||
self.datas.append(
|
|
||||||
ReviewData(
|
|
||||||
datetime.strptime(datas[0], "%Y%m%d-%Hh%M"),
|
|
||||||
int(datas[1]),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
self.datas.append(
|
|
||||||
ReviewData(
|
|
||||||
datetime.strptime(datas[0], "%Y%m%d-%Hh%M"),
|
|
||||||
int(datas[1]),
|
|
||||||
int(datas[2]) if datas[2]!="" else None,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
# no file, no stats
|
# no file, no stats
|
||||||
pass
|
pass
|
||||||
@ -174,10 +181,4 @@ 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 = ""
|
file_handle.write(str(data))
|
||||||
if data.duration is not None:
|
|
||||||
duration = f"\t{data.duration}"
|
|
||||||
file_handle.write(
|
|
||||||
f"{data.date.strftime('%Y%m%d-%Hh%M')}\t"
|
|
||||||
f"{data.user_count}{duration}\n"
|
|
||||||
)
|
|
||||||
|
@ -10,11 +10,3 @@ 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"
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
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
|
||||||
|
|
||||||
|
|
||||||
@ -53,38 +52,3 @@ 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)
|
|
||||||
|
8
tests/test_review_data.py
Normal file
8
tests/test_review_data.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from review.stats import ReviewData
|
||||||
|
|
||||||
|
|
||||||
|
def test_reviewdata():
|
||||||
|
for filename in ("reviewstats_1.csv", "reviewstats_2.csv"):
|
||||||
|
with open(f"tests/datas/{filename}", "r") as review:
|
||||||
|
for line in review:
|
||||||
|
assert line == str(ReviewData.load(line))
|
@ -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, SENDER_2
|
from tests.utils import bot, OWNER, SENDER
|
||||||
|
|
||||||
|
|
||||||
def setup_function():
|
def setup_function():
|
||||||
@ -515,54 +515,3 @@ 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:]
|
|
||||||
|
@ -7,7 +7,6 @@ from tests import settings
|
|||||||
|
|
||||||
OWNER = "me"
|
OWNER = "me"
|
||||||
SENDER = "foobar"
|
SENDER = "foobar"
|
||||||
SENDER_2 = "foobaz"
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
Loading…
Reference in New Issue
Block a user