|
@@ -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(
|