/python3/berrymq/adapter/growl/netgrowl.py

https://bitbucket.org/shibu/berrymq · Python · 139 lines · 102 code · 18 blank · 19 comment · 8 complexity · 0df728e7e3af40dcc874fadd1a54834e MD5 · raw file

  1. #!/usr/bin/env python
  2. """Growl 0.6 Network Protocol Client for Python
  3. modified by SHIBUKAWA Yoshiki to follow PEP-8 and remove deprecate warning.
  4. """
  5. __version__ = "0.6" # will always match Growl version
  6. __author__ = "Rui Carmo (http://the.taoofmac.com)"
  7. __copyright__ = "(C) 2004 Rui Carmo. Code under BSD License."
  8. __contributors__ = "Ingmar J Stein (Growl Team)"
  9. import struct
  10. from hashlib import md5
  11. from socket import AF_INET, SOCK_DGRAM, socket
  12. GROWL_UDP_PORT=9887
  13. GROWL_PROTOCOL_VERSION=1
  14. GROWL_TYPE_REGISTRATION=0
  15. GROWL_TYPE_NOTIFICATION=1
  16. class GrowlRegistrationPacket:
  17. """Builds a Growl Network Registration packet.
  18. Defaults to emulating the command-line growlnotify utility."""
  19. def __init__(self, application="growlnotify", password = None ):
  20. self.notifications = []
  21. self.defaults = [] # array of indexes into notifications
  22. self.application = application.encode("utf-8")
  23. self.password = password
  24. # end def
  25. def addNotification(self, notification="Command-Line Growl Notification",
  26. enabled=True):
  27. """Adds a notification type and sets whether it is enabled on the GUI"""
  28. self.notifications.append(notification)
  29. if enabled:
  30. self.defaults.append(len(self.notifications)-1)
  31. # end def
  32. def payload(self):
  33. """Returns the packet payload."""
  34. self.data = struct.pack( "!BBH",
  35. GROWL_PROTOCOL_VERSION,
  36. GROWL_TYPE_REGISTRATION,
  37. len(self.application) )
  38. self.data += struct.pack( "BB",
  39. len(self.notifications),
  40. len(self.defaults) )
  41. self.data += self.application
  42. for notification in self.notifications:
  43. encoded = notification.encode("utf-8")
  44. self.data += struct.pack("!H", len(encoded))
  45. self.data += encoded
  46. for default in self.defaults:
  47. self.data += struct.pack("B", default)
  48. self.checksum = md5()
  49. self.checksum.update(self.data)
  50. if self.password:
  51. self.checksum.update(self.password)
  52. self.data += self.checksum.digest()
  53. return self.data
  54. # end def
  55. # end class
  56. class GrowlNotificationPacket:
  57. """Builds a Growl Network Notification packet.
  58. Defaults to emulating the command-line growlnotify utility."""
  59. def __init__(self, application="growlnotify",
  60. notification="Command-Line Growl Notification", title="Title",
  61. description="Description", priority = 0, sticky = False,
  62. password = None ):
  63. self.application = application.encode("utf-8")
  64. self.notification = notification.encode("utf-8")
  65. self.title = title.encode("utf-8")
  66. self.description = description.encode("utf-8")
  67. flags = (priority & 0x07) * 2
  68. if priority < 0:
  69. flags |= 0x08
  70. if sticky:
  71. flags = flags | 0x0001
  72. self.data = struct.pack( "!BBHHHHH",
  73. GROWL_PROTOCOL_VERSION,
  74. GROWL_TYPE_NOTIFICATION,
  75. flags,
  76. len(self.notification),
  77. len(self.title),
  78. len(self.description),
  79. len(self.application) )
  80. self.data += self.notification
  81. self.data += self.title
  82. self.data += self.description
  83. self.data += self.application
  84. self.checksum = md5()
  85. self.checksum.update(self.data)
  86. if password:
  87. self.checksum.update(password)
  88. self.data += self.checksum.digest()
  89. # end def
  90. def payload(self):
  91. """Returns the packet payload."""
  92. return self.data
  93. # end def
  94. # end class
  95. if __name__ == '__main__':
  96. print("Starting Unit Test")
  97. print(" - please make sure Growl is listening for network notifications")
  98. addr = ("localhost", GROWL_UDP_PORT)
  99. s = socket(AF_INET,SOCK_DGRAM)
  100. print("Assembling registration packet like growlnotify's (no password)")
  101. p = GrowlRegistrationPacket()
  102. p.addNotification()
  103. print("Sending registration packet")
  104. s.sendto(p.payload(), addr)
  105. import time
  106. time.sleep(3)
  107. print("Assembling standard notification packet")
  108. p = GrowlNotificationPacket()
  109. print("Sending standard notification packet")
  110. s.sendto(p.payload(), addr)
  111. print("Assembling priority -2 (Very Low) notification packet")
  112. p = GrowlNotificationPacket(priority=-2)
  113. print("Sending priority -2 notification packet")
  114. s.sendto(p.payload(), addr)
  115. print("Assembling priority 2 (Very High) sticky notification packet")
  116. p = GrowlNotificationPacket(priority=2,sticky=True)
  117. print("Sending priority 2 (Very High) sticky notification packet")
  118. s.sendto(p.payload(), addr)
  119. s.close()
  120. print("Done.")