repl_driver.py 3.9 KB

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