MegBot 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #!/usr/bin/env python
  2. ##
  3. # This file is part of MegBot.
  4. #
  5. # MegBot is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # MegBot is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with MegBot. If not, see <http://www.gnu.org/licenses/>.
  17. ##
  18. import sys
  19. import os
  20. from signal import SIGHUP, SIGTSTP, signal
  21. from threading import Thread
  22. from time import sleep
  23. import traceback
  24. from Configuration import configuration
  25. from Loader import Master_Loader
  26. class Bot(object):
  27. def __init__(self, name, config, thread, run=True):
  28. """Initalises bot"""
  29. self.name = name
  30. self.config = config
  31. self.settings = config["networks"][name]
  32. self.running = False
  33. self.channels = {}
  34. self.thread = thread
  35. # allow the main thread to call us
  36. self.thread["object"] = self
  37. self.alive = True
  38. # load loaders - yeh i know.
  39. Master_Loader(self, self.config[u"paths"]) # returns None.
  40. self.core["Coreconnect"].main(self)
  41. if run:
  42. self.server = self.libraries["IRCObjects"].L_Server(self)
  43. self.server.__setuphooks__(self)
  44. self.run()
  45. def run(self):
  46. """This will run the bot.
  47. It loops (indefinitly) asking the parser for messages from the IRC
  48. It'll then split them up indevidually by \r\n (end of an IRC message)
  49. Once it has each message it'll pass it along to the delegator which
  50. will validate and then deluege if needed to the correct
  51. part of the bot
  52. """
  53. while self.alive:
  54. while not self.running and self.alive:
  55. sleep(1)
  56. while self.running and self.alive:
  57. try:
  58. data = self.core["Coreparser"].main(self, [])
  59. except Exception:
  60. traceback.print_exc()
  61. self.running = False
  62. break
  63. for line in data.split("\r\n"):
  64. self.core["Coredelegator"].main(self, line)
  65. try:
  66. self.sock.close()
  67. except Exception:
  68. pass
  69. self.__init__(self.name,
  70. self.config,
  71. self.thread,
  72. False)
  73. def restart_connections(sig, frame):
  74. global bots
  75. # we get signal!
  76. print "[DEBUG] WE GET SIGNAL!"
  77. for network in bots:
  78. if connection["thread"].is_alive():
  79. continue
  80. new_connection = {}
  81. new_connection["thread"] = Thread(target=Bot, args=(network, configuration, new_connection))
  82. new_connection["object"] = None
  83. new_connection["thread"].daemon = True
  84. new_connection["thread"].start()
  85. bots[network] = new_connection
  86. if __name__ == "__main__":
  87. # since there is no good logging and/or way of talking to the
  88. # bot this is set to not ready as it shouldn't be used
  89. DaemonNotReady = True
  90. if "-d" in sys.argv and not DaemonNotReady:
  91. print "[Warning] Daemon mode isn't ready yet - see https://github.com/xray7224/MegBot/issues/31"
  92. # add a ticket number?
  93. sys.exit() # they can start me again if they still want to run me
  94. if "-d" in sys.argv and DaemonNotReady:
  95. # daemon process
  96. try:
  97. pid = os.fork()
  98. if pid > 0:
  99. sys.exit(0)
  100. except Exception:
  101. # failed to daemonise
  102. print "[ErrorLine] Failed to daemonise - quitting."
  103. sys.exit()
  104. bots = {}
  105. for network in configuration["networks"]:
  106. if not "active" in configuration["networks"][network].keys() or (
  107. configuration["networks"][network]["active"]):
  108. connection = {}
  109. connection["thread"] = Thread(target=Bot, args=(network, configuration, connection))
  110. connection["object"] = None
  111. connection["thread"].daemon = True
  112. connection["thread"].start()
  113. bots[network] = connection
  114. signal(SIGHUP, restart_connections)
  115. signal(SIGTSTP, restart_connections)
  116. try:
  117. while True:
  118. sleep(2)
  119. except KeyboardInterrupt:
  120. print "\nCtrl-C been hit, run for your lives!"
  121. sys.exit()