Browse Source

Added session command

Kirk Trombley 6 years ago
parent
commit
0bdeb9b5ca
2 changed files with 104 additions and 20 deletions
  1. 77 18
      src/plugins/session.py
  2. 27 2
      src/test_driver.py

+ 77 - 18
src/plugins/session.py

@@ -1,16 +1,23 @@
 import datetime
 
-from sqlalchemy import Column, Integer, DateTime
+from sqlalchemy import Column, Integer, String, DateTime
 
 from command_system import RollbotResponse, RollbotFailure, as_plugin, ModelBase
 
 
 class DnDSession(ModelBase):
     __tablename__ = "dnd_session"
-    id = Column(Integer, primary_key=True)
+    group_id = Column(String, primary_key=True)
     session_time = Column(DateTime)
 
 
+class DnDCancellationBlame(ModelBase):
+    __tablename__ = "dnd_session_cancel_blame"
+    group_id = Column(String, primary_key=True)
+    name = Column(String, primary_key=True)
+    count = Column(Integer)
+
+
 WEEKDAYS = {
     "monday": 0,
     "tuesday": 1,
@@ -26,7 +33,6 @@ def parse_datetime(args):
     try:
         day_date = next(args)
     except StopIteration:
-        print(1)
         return  # must have at least one more argument
 
     day_date = day_date.lower()
@@ -48,7 +54,6 @@ def parse_datetime(args):
             day = date_parts[1]
             year = datetime.date.today().year
         else:
-            print(2)
             return  # invalid format
 
     hour = 19
@@ -85,17 +90,24 @@ def parse_datetime(args):
 
 
 
-def get_upcoming(db):
-    return db.query(DnDSession).order_by(DnDSession.session_time).first()
+def get_latest_session(db, group_id):
+    saved = db.query(DnDSession).get(group_id)
+    if saved is None:
+        return
+
+    if saved.session_time >= datetime.datetime.now():
+        return saved
 
+    db.delete(saved)
+    return
 
-def get_fmt_next(db):
-    dt = get_upcoming(db).session_time
-    if dt is None or dt < datetime.datetime.now():
+
+def get_fmt_next(db, group_id):
+    nxt = get_latest_session(db, group_id)
+    if nxt is None or nxt.session_time < datetime.datetime.now():
         return "No upcoming session found."
-    else:
-        return "Next DnD session scheduled for {}/{}/{} at {}:{:02d}.".format(
-            dt.month, dt.day, dt.year, dt.hour, dt.minute)
+
+    return "Next DnD session scheduled for " + nxt.session_time.strftime("%b %d, %Y, at %I:%M %p")
 
 
 def session_next(db, message, args):
@@ -107,25 +119,72 @@ def session_next(db, message, args):
             debugging={"explain": "Could not process argument as a date/time."}
         )
 
-    db.add(DnDSession(session_time=dt))
+    if dt < datetime.datetime.now():
+        return RollbotResponse(
+            message,
+            failure=RollbotFailure.INVALID_ARGUMENTS,
+            debugging={"explain": "Cannot schedule sessions in the past."}
+        )
+
+    nxt = get_latest_session(db, message.group_id)
+    if nxt is not None:
+        db.delete(nxt)
+
+    db.add(DnDSession(group_id=message.group_id, session_time=dt))
 
-    return RollbotResponse(message, txt=get_fmt_next(db))
+    return RollbotResponse(message, txt=get_fmt_next(db, message.group_id))
 
 
 def session_worst(db, message, args):
-    return RollbotResponse(message, txt="TODO")
+    rankings = db.query(DnDCancellationBlame
+        ).filter(DnDCancellationBlame.group_id == message.group_id
+        ).order_by(DnDCancellationBlame.count.desc()
+        ).all()
+
+    if len(rankings) == 0:
+        return RollbotResponse(message, txt="I don't have any records of cancelled sessions.")
+
+    rankings = "\n".join(f"{i+1}: {r.name} has cancelled {r.count} session(s)" for i, r in enumerate(rankings))
+    return RollbotResponse(message, txt="Rankings:\n"+rankings)
 
 
 def session_view(db, message, args):
-    return RollbotResponse(message, txt="TODO")
+    return RollbotResponse(message, txt=get_fmt_next(db, message.group_id))
 
 
 def session_late(db, message, args):
-    return RollbotResponse(message, txt="TODO")
+    nxt = get_latest_session(db, message.group_id)
+    if nxt is None:
+        return RollbotResponse(message, txt="No upcoming session found.")
+
+    now = datetime.datetime.now()
+    nxt = nxt.session_time
+    if nxt >= now:
+        return RollbotResponse(message, txt="You're not late yet!")
+
+    late = (now - nxt).total_seconds() / 60
+    return RollbotResponse(message, txt="You're running %.2f minutes late..." % late)
 
 
 def session_cancel(db, message, args):
-    return RollbotResponse(message, txt="TODO")
+    nxt = get_latest_session(db, message.group_id)
+    if nxt is None:
+        return RollbotResponse(message, txt="No upcoming session found.")
+
+    db.delete(nxt)
+
+    args = message.args(normalize=False)
+    next(args)  # discard "cancel"
+    blame = " ".join(args)
+    if len(blame) > 0:
+        counter = db.query(DnDCancellationBlame).get((message.group_id, blame))
+        if counter is not None:
+            counter.count += 1
+        else:
+            db.add(DnDCancellationBlame(group_id=message.group_id, name=blame, count=1))
+        return RollbotResponse(message, txt=f"Sigh, session cancelled, and it's all {blame}'s fault!")
+    else:
+        return RollbotResponse(message, txt=f"Sigh, session cancelled...")
 
 
 SUBCOMMANDS = dict(

+ 27 - 2
src/test_driver.py

@@ -1,15 +1,20 @@
 import atexit
 import logging
+import os
 
 from rollbot import Rollbot
 from command_system import RollbotMessage
+from config import DB_FILE
 
-
+try:
+    os.remove(DB_FILE)
+except FileNotFoundError:
+    pass
 rollbot = Rollbot(logging.getLogger(__name__))
 
 
 def test_drive(msg, from_admin=True):
-    rmsg = RollbotMessage("mock", None, None, None, None, msg)
+    rmsg = RollbotMessage("mock", None, None, "test_group", None, msg)
     rmsg.from_admin = from_admin
     r =rollbot.run_command(rmsg)
     print(msg, ":", r.txt, ",", r.failure)
@@ -27,10 +32,30 @@ if __name__ == "__main__":
     atexit.register(rollbot.shutdown_plugins)
 
     [test_drive(msg) for msg in [
+        "!session worst",
         "!session blah",
+        "!session cancel",
         "!session next",
         "!session next asdf",
         "!session next Sunday",
+        "!session late",
+        "!session view",
+        "!session cancel T e S t",
+        "!session next Sunday",
+        "!session late",
+        "!session view",
+        "!session cancel T e S t",
+        "!session next Sunday",
+        "!session late",
+        "!session view",
+        "!session cancel dIfFeReNt",
+        "!session late",
+        "!session cancel",
+        "!session next Saturday",
+        "!session next 01/01/1980",
+        "!session next 01/01/2980",
+        "!session late",
         "!session view",
         "!session cancel",
+        "!session worst",
     ]]