alert_bot.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. SleekXMPP: The Sleek XMPP Library
  5. Copyright (C) 2010 Nathanael C. Fritz
  6. This file is part of SleekXMPP.
  7. See the file LICENSE for copying permission.
  8. """
  9. import sys, traceback
  10. import json
  11. import logging
  12. import ConfigParser
  13. from time import sleep
  14. import time, datetime
  15. import sleekxmpp
  16. import redis
  17. from threading import Lock
  18. from redisQueue import RedisQueue
  19. import threading
  20. # Python versions before 3.0 do not use UTF-8 encoding
  21. # by default. To ensure that Unicode is handled properly
  22. # throughout SleekXMPP, we will set the default encoding
  23. # ourselves to UTF-8.
  24. if sys.version_info < (3, 0):
  25. from sleekxmpp.util.misc_ops import setdefaultencoding
  26. setdefaultencoding('utf8')
  27. else:
  28. raw_input = input
  29. class AlertMsgBot(sleekxmpp.ClientXMPP):
  30. """
  31. A basic SleekXMPP bot that will log in, send a message,
  32. and then log out.
  33. """
  34. config = None
  35. rsq= None
  36. recipients = None
  37. quit = False
  38. tlock = None
  39. def __init__(self, config):
  40. self.config = config
  41. host = config.get("redis", "redis.server").strip('"').strip("'")
  42. port = config.get("redis", "redis.port")
  43. db = config.get("redis", "redis.db")
  44. qname = config.get("alert_bot", "msg_bot.redis_mq").strip('"').strip("'")
  45. qprefix = config.get("alert_bot", "msg_bot.redis_prefix").strip('"').strip("'")
  46. self.rsq = RedisQueue(qname, qprefix, host, port, db)
  47. logging.info('Connect to redis on server->%s:%s db->%s qname->%s:%s' % (host, port, db, qprefix, qname))
  48. jid = config.get("alert_bot", "msg_bot.jid").strip('"').strip("'")
  49. password = config.get("alert_bot", "msg_bot.pass").strip('"').strip("'")
  50. sleekxmpp.ClientXMPP.__init__(self, jid, password)
  51. self.recipients = eval(config.get("alert_bot", "msg_bot.recipients").strip('"').strip("'"))
  52. self.tlock = Lock()
  53. # The session_start event will be triggered when
  54. # the bot establishes its connection with the server
  55. # and the XML streams are ready for use. We want to
  56. # listen for this event so that we we can initialize
  57. # our roster.
  58. self.add_event_handler("session_start", self.start, threaded=True)
  59. def start(self, event):
  60. """
  61. Process the session_start event.
  62. Typical actions for the session_start event are
  63. requesting the roster and broadcasting an initial
  64. presence stanza.
  65. Arguments:
  66. event -- An empty dictionary. The session_start
  67. event does not provide any additional
  68. data.
  69. """
  70. self.send_presence()
  71. self.get_roster()
  72. self.rsq.put("Greetings! The alert bot has just started!")
  73. t = threading.Thread(target = self.process_alerts(), args=())
  74. t.start()
  75. # self.send_message(mto=self.recipient,
  76. # mbody=self.msg,
  77. # mtype='chat')
  78. def process_alerts(self):
  79. self.quit = False
  80. while self.quit <> True:
  81. if not self.rsq.empty():
  82. msg = self.rsq.get()
  83. logging.debug('process_alerts: received msg: {%s}' % msg)
  84. self.send_msg(msg)
  85. sleep(1)
  86. # Using wait=True ensures that the send queue will be
  87. # emptied before ending the session.
  88. self.disconnect(wait=True)
  89. def send_msg(self, msg):
  90. self.tlock.acquire()
  91. try:
  92. for r in self.recipients:
  93. self.send_message(r, msg, mtype='chat')
  94. finally:
  95. self.tlock.release()
  96. #
  97. # alert helper doesn't care whether the xmpp server
  98. # has started or not, all it cares is being able to put the message
  99. # into redisQueue
  100. class AlertHelper():
  101. q = None
  102. def __init__(self, config):
  103. rhost = config.get("redis", "redis.server").strip('"').strip("'")
  104. rport = config.get("redis", "redis.port")
  105. rdb = config.get("redis", "redis.db")
  106. chatq = config.get("alert_bot", "msg_bot.redis_mq").strip('"').strip("'")
  107. prefix = config.get("alert_bot", "msg_bot.redis_prefix").strip('"').strip("'")
  108. self.q = RedisQueue(chatq, prefix, rhost, rport, rdb)
  109. def post_msg(self, msg):
  110. self.q.put(msg)
  111. def flush_all(self):
  112. i = 0
  113. while not self.q.empty():
  114. self.q.get()
  115. i+=1
  116. return i
  117. if __name__ == '__main__':
  118. if len(sys.argv) != 2:
  119. print("Usage: %s <config file>" % sys.argv[0])
  120. exit(-1)
  121. cfg_path= sys.argv[1:]
  122. config = ConfigParser.SafeConfigParser()
  123. if len(config.read(cfg_path)) == 0:
  124. raise ValueError, "Failed to open config file"
  125. logconfig = eval(config.get("alert_bot", "msg_bot.logconfig").strip('"').strip("'"))
  126. logconfig['format'] = '%(asctime)s %(levelname)-8s %(message)s'
  127. logging.basicConfig(**logconfig)
  128. xmpp = AlertMsgBot(config)
  129. xmpp.register_plugin('xep_0030') # Service Discovery
  130. xmpp.register_plugin('xep_0199') # XMPP Ping
  131. if xmpp.connect(): #('192.168.1.1', 5222), True, True, False):
  132. xmpp.process(block=False)
  133. logging.info('Complete initialization...Bot will now run forever')
  134. a = AlertHelper(config)
  135. i = a.flush_all()
  136. a.post_msg('from AlertHelper: flushed %d old messages.' % i)
  137. else:
  138. print("Unable to connect.")