curse.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from sqlalchemy import Column, Integer, String
  2. from command_system import RollbotResponse, RollbotFailure, as_plugin, ModelBase, pop_arg
  3. class CurseBlessScore(ModelBase):
  4. __tablename__ = "curse_bless_score"
  5. group_id = Column(String, primary_key=True)
  6. person_id = Column(Integer, primary_key=True)
  7. curses = Column(Integer)
  8. blessings = Column(Integer)
  9. def get_score(db, group_id, name):
  10. person_id = name.strip().lower()
  11. score = db.query(CurseBlessScore).get((group_id, person_id))
  12. if not score:
  13. score = CurseBlessScore(group_id=group_id, person_id=person_id, curses=0, blessings=0)
  14. db.add(score)
  15. return score
  16. def fmt_times(n):
  17. return str(n) + (" time" if n == 1 else " times")
  18. def get_response(msg, name, score):
  19. return RollbotResponse(msg, txt=f"It is done! {name} has been cursed {fmt_times(score.curses)} and blessed {fmt_times(score.blessings)} in this chat.")
  20. @as_plugin
  21. def curse(db, msg):
  22. # TODO might be nice to add subcommands to this later
  23. name, args = pop_arg(msg.raw_args)
  24. if not name.startswith("!"):
  25. score = get_score(db, msg.group_id, name)
  26. # Note we do this instead of += b/c that can create race conditions in sqlalchemy
  27. score.curses = score.curses + 1
  28. return get_response(msg, name, score)
  29. # strip off the '!'
  30. subc = name[1:].strip()
  31. if len(subc) == 0:
  32. # handle the case of spaces between ! and subcommand
  33. subc, args = pop_arg(args)
  34. subc = subc.lower()
  35. name, _ = pop_arg(args)
  36. person_id = name.strip().lower()
  37. if subc == "aggregate":
  38. curses = 0
  39. blessings = 0
  40. for cbs in db.query(CurseBlessScore).filter(CurseBlessScore.person_id == person_id):
  41. curses += cbs.curses
  42. blessings += cbs.blessings
  43. return RollbotResponse(msg, txt=f"From my records, {name} has been cursed {fmt_times(curses)} and blessed {fmt_times(blessings)} across all chats.")
  44. elif subc == "clear":
  45. if not msg.from_admin:
  46. return RollbotResponse(msg, failure=RollbotFailure.PERMISSIONS)
  47. cbs = db.query(CurseBlessScore).get((msg.group_id, person_id))
  48. if cbs:
  49. oc = cbs.curses
  50. ob = cbs.blessings
  51. cbs.curses = 0
  52. cbs.blessings = 0
  53. return RollbotResponse(msg, txt=f"Done! I have cleared all records of {name} in this chat, who was previously cursed {fmt_times(oc)} and blessed {fmt_times(ob)}!")
  54. return RollbotResponse(msg, txt=f"Sorry! I don't know who {name} is!")
  55. elif subc == "clearall":
  56. if not msg.from_admin:
  57. return RollbotResponse(msg, failure=RollbotFailure.PERMISSIONS)
  58. cnt = 0
  59. oc = 0
  60. ob = 0
  61. for cbs in db.query(CurseBlessScore).filter(CurseBlessScore.person_id == person_id):
  62. oc += cbs.curses
  63. ob += cbs.blessings
  64. cbs.curses = 0
  65. cbs.blessings = 0
  66. cnt += 1
  67. if cnt == 0:
  68. return RollbotResponse(msg, txt=f"Sorry! I don't know who {name} is!")
  69. return RollbotResponse(msg, txt=f"Done! I have cleared all records of {name} in all chats, who was previously cursed {fmt_times(oc)} and blessed {fmt_times(ob)} in total!")
  70. else:
  71. return RollbotResponse(msg, failure=RollbotFailure.INVALID_SUBCOMMAND)
  72. @as_plugin
  73. def bless(db, msg):
  74. name, _ = pop_arg(msg.raw_args)
  75. score = get_score(db, msg.group_id, name)
  76. score.blessings = score.blessings + 1
  77. return get_response(msg, name, score)