repl_driver.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. from datetime import datetime
  2. from dataclasses import dataclass
  3. import asyncio
  4. import rollbot
  5. from rollbot.injection import ArgList, Lazy, Database, Data, Args
  6. @dataclass
  7. class MyCounter:
  8. one: int = 0
  9. two: int = 0
  10. class MyBot(rollbot.Rollbot[str]):
  11. def read_config(self, key):
  12. return key
  13. def parse(self, raw):
  14. return rollbot.Message(
  15. origin_id="REPL",
  16. channel_id=".",
  17. sender_id=".",
  18. timestamp=datetime.now(),
  19. origin_admin=True,
  20. channel_admin=True,
  21. text=raw,
  22. attachments=[],
  23. )
  24. async def respond(self, res):
  25. print(res, flush=True)
  26. async def goodbye_command(message, context):
  27. await context.respond(rollbot.Response.from_message(message, "Goodbye!"))
  28. async def count_command(message, context):
  29. args = message.text.split("count", maxsplit=1)[1].strip().split()
  30. name = args[0] if len(args) > 0 else "main"
  31. async with context.database() as db:
  32. await db.execute(
  33. "INSERT INTO counter VALUES (?, 1) \
  34. ON CONFLICT (name) DO UPDATE SET count=count + 1",
  35. (name,),
  36. )
  37. await db.commit()
  38. async with db.execute("SELECT count FROM counter WHERE name = ?", (name,)) as cursor:
  39. res = (await cursor.fetchone())[0]
  40. await context.respond(rollbot.Response.from_message(message, f"{name} = {res}"))
  41. @rollbot.as_command
  42. async def count2(args: ArgList, connect: Lazy(Database)):
  43. name = args[0] if len(args) > 0 else "main"
  44. db = await connect()
  45. await db.execute(
  46. "INSERT INTO counter VALUES (?, 1) \
  47. ON CONFLICT (name) DO UPDATE SET count=count + 2",
  48. (name,),
  49. )
  50. await db.commit()
  51. async with db.execute("SELECT count FROM counter WHERE name = ?", (name,)) as cursor:
  52. res = (await cursor.fetchone())[0]
  53. return f"{name} = {res}"
  54. @rollbot.as_command
  55. async def count3(counter: Data(MyCounter).For(Args), store: Data(MyCounter), args: Args):
  56. counter.one += 1
  57. counter.two += 2
  58. await store.save(args, counter)
  59. return f"{args} = {counter}"
  60. @rollbot.on_startup
  61. async def make_table(context):
  62. async with context.database() as db:
  63. await db.execute(
  64. "CREATE TABLE IF NOT EXISTS counter ( \
  65. name TEXT NOT NULL PRIMARY KEY, \
  66. count INTEGER NOT NULL DEFAULT 0 \
  67. );"
  68. )
  69. await db.commit()
  70. @rollbot.on_shutdown
  71. async def shutdown(context):
  72. await context.respond(rollbot.Response(origin_id="REPL", channel_id=".", text="Shutting down!"))
  73. @rollbot.as_command
  74. def simple():
  75. return "Simple!"
  76. @rollbot.as_command
  77. def generator():
  78. yield "This is"
  79. yield "a generator!"
  80. @rollbot.as_command
  81. async def coroutine():
  82. await asyncio.sleep(1.0)
  83. return "Here's a coroutine!"
  84. @rollbot.as_command
  85. async def asyncgen():
  86. yield "This is"
  87. await asyncio.sleep(0.5)
  88. yield "an async"
  89. await asyncio.sleep(0.5)
  90. yield "generator!"
  91. config = rollbot.get_command_config().extend(
  92. rollbot.CommandConfiguration(
  93. commands={
  94. "goodbye": goodbye_command,
  95. "count": count_command,
  96. },
  97. call_and_response={
  98. "hello": "Hello!",
  99. },
  100. aliases={
  101. "hi": "hello",
  102. "bye": "goodbye",
  103. },
  104. bangs=("/",),
  105. )
  106. )
  107. bot = MyBot(config, "/tmp/my.db")
  108. async def run():
  109. await bot.on_startup()
  110. try:
  111. while True:
  112. await bot.on_message(input("> "))
  113. except EOFError:
  114. pass
  115. await bot.on_shutdown()
  116. asyncio.run(run())