/jsb/plugs/common/karma.py

https://code.google.com/p/boty/ · Python · 183 lines · 121 code · 35 blank · 27 comment · 43 complexity · 1cf52ea43f17c5ed8a59dd0e46ed9695 MD5 · raw file

  1. # jsb/plugs/common/karma.py
  2. #
  3. #
  4. """ maintain karma! """
  5. ## jsb imports
  6. from jsb.utils.name import stripname
  7. from jsb.lib.callbacks import callbacks
  8. from jsb.lib.commands import cmnds
  9. from jsb.lib.examples import examples
  10. from jsb.lib.persist import PlugPersist, PlugPersistCollection
  11. from jsb.utils.statdict import StatDict
  12. from jsb.lib.persistconfig import PersistConfig
  13. ## basic imports
  14. import logging
  15. import re
  16. ## defines
  17. RE_KARMA = re.compile(r'^(?P<item>\([^\)]+\)|\[[^\]]+\]|\w+)(?P<mod>\+\+|--)( |$)')
  18. cfg = PersistConfig()
  19. cfg.define('verbose', '1')
  20. ## KarmaItem class
  21. class KarmaItem(PlugPersist):
  22. """ Item holding karma data. """
  23. def __init__(self, name, default={}):
  24. PlugPersist.__init__(self, name)
  25. self.data.name = name
  26. self.data.count = self.data.count or 0
  27. self.data.whoup = self.data.whoup or {}
  28. self.data.whodown = self.data.whodown or {}
  29. self.data.whyup = self.data.whyup or []
  30. self.data.whydown = self.data.whydown or []
  31. ## karma-precondition
  32. def prekarma(bot, event):
  33. # if not event.iscmnd(): return False
  34. # we want to catch all the ++ and to avoid cheating
  35. if event.userhost in bot.ignore: return False
  36. karmastring = re.search(RE_KARMA, event.txt)
  37. if karmastring:
  38. # ignore the karma from the same user
  39. if karmastring.group('item') == event.nick : return False
  40. else: return True
  41. return False
  42. ## karma-callbacks
  43. def karmacb(bot, event):
  44. """ karma callback. """
  45. event.bind(bot)
  46. if bot.type == "convore" and not event.chan.data.enable: return
  47. targets = re.findall(RE_KARMA, event.txt)
  48. karma = []
  49. try: reason = event.txt.split('#', 1)[1] ; reason = reason.strip()
  50. except IndexError: reason = None
  51. for target in targets:
  52. try: item, what, bogus = target
  53. except ValueError: logging.debug("%s not in (iten, what, bogus) form" % target) ; continue
  54. item = item.lower()
  55. if what == "++":
  56. i = KarmaItem(event.channel.lower() + "-" + item)
  57. i.data.count += 1
  58. if event.nick not in i.data.whoup: i.data.whoup[event.nick] = 0
  59. i.data.whoup[event.nick] += 1
  60. if reason and reason not in i.data.whyup: i.data.whyup.append(reason)
  61. i.save()
  62. else:
  63. i = KarmaItem(event.channel.lower() + "-" + item)
  64. i.data.count -= 1
  65. if event.nick not in i.data.whodown: i.data.whodown[event.nick] = 0
  66. i.data.whodown[event.nick] -= 1
  67. if reason and reason not in i.data.whyup: i.data.whydown.append(reason)
  68. i.save()
  69. karma.append("%s: %s" % (item, i.data.count))
  70. got = item or item2
  71. if karma:
  72. if cfg.get('verbose') == '1': event.reply("karma - ", karma)
  73. event.ready()
  74. callbacks.add('PRIVMSG', karmacb, prekarma)
  75. callbacks.add('MESSAGE', karmacb, prekarma)
  76. callbacks.add('CONSOLE', karmacb, prekarma)
  77. callbacks.add('CONVORE', karmacb, prekarma)
  78. callbacks.add('TORNADO', karmacb, prekarma)
  79. ## karma command
  80. def handle_karma(bot, event):
  81. """ arguments: <item> - show karma of item. """
  82. if not event.rest: event.missing("<item>") ; return
  83. k = event.rest.lower()
  84. item = KarmaItem(event.channel.lower() + "-" + k)
  85. if item.data.count: event.reply("karma of %s is %s" % (k, item.data.count))
  86. else: event.reply("%s doesn't have karma yet." % k)
  87. cmnds.add('karma', handle_karma, ['OPER', 'USER', 'GUEST'])
  88. examples.add('karma', 'show karma', 'karma jsb')
  89. ## karma-whyup command
  90. def handle_karmawhyup(bot, event):
  91. """ arguments: <item> - show reason for karma increase. """
  92. k = event.rest.lower()
  93. item = KarmaItem(event.channel + "-" + k)
  94. if item.data.whyup: event.reply("reasons for karma up are: ", item.data.whyup)
  95. else: event.reply("no reasons for karmaup of %s known yet" % k)
  96. cmnds.add("karma-whyup", handle_karmawhyup, ['OPER', 'USER', 'GUEST'])
  97. examples.add("karma-whyup", "show why a karma item is upped", "karma-whyup jsb")
  98. ## karma-whoup command
  99. def handle_karmawhoup(bot, event):
  100. """ arguments: <item> - show who increased the karma of an item. """
  101. k = event.rest.lower()
  102. item = KarmaItem(event.channel.lower() + "-" + k)
  103. sd = StatDict(item.data.whoup)
  104. res = []
  105. for i in sd.top():
  106. res.append("%s: %s" % i)
  107. if res: event.reply("uppers of %s are: " % k, res)
  108. else: event.reply("nobody upped %s yet" % k)
  109. cmnds.add("karma-whoup", handle_karmawhoup, ['OPER', 'USER', 'GUEST'])
  110. examples.add("karma-whoup", "show who upped an item", "karma-whoup jsb")
  111. ## karma-whydown command
  112. def handle_karmawhydown(bot, event):
  113. """ arguments: <item> - show reason why karma was lowered. """
  114. k = event.rest.lower()
  115. item = KarmaItem(event.channel.lower() + "-" + k)
  116. if item.data.whydown: event.reply("reasons for karmadown are: ", item.data.whydown)
  117. else: event.reply("no reasons for karmadown of %s known yet" % k)
  118. cmnds.add("karma-whydown", handle_karmawhydown, ['OPER', 'USER', 'GUEST'])
  119. examples.add("karma-whydown", "show why a karma item is downed", "karma-whydown jsb")
  120. ## karma-whodown command
  121. def handle_karmawhodown(bot, event):
  122. """ arguments: <item> - show who lowered the karma of an item. """
  123. k = event.rest.lower()
  124. item = KarmaItem(event.channel.lower() + "-" + k)
  125. sd = StatDict(item.data.whodown)
  126. res = []
  127. for i in sd.down():
  128. res.append("%s: %s" % i)
  129. if res: event.reply("downers of %s are: " % k, res)
  130. else: event.reply("nobody downed %s yet" % k)
  131. cmnds.add("karma-whodown", handle_karmawhodown, ['OPER', 'USER', 'GUEST'])
  132. examples.add("karma-whodown", "show who downed an item", "karma-whodown jsb")
  133. ## karma-good command
  134. def handle_karmagood(bot, event):
  135. """ arguments: none - show top karma items of a channel. """
  136. collection = PlugPersistCollection()
  137. stats = StatDict()
  138. objs = collection.objects(event.channel.lower())
  139. for name, obj in objs.iteritems():
  140. if not obj.data: logging.warn("%s is empty" % name) ; continue
  141. item = stripname(name).split("-")[-1]
  142. stats.upitem(item, obj.data.count)
  143. res = []
  144. for item in stats.top():
  145. res.append("%s - %s" % item)
  146. event.reply("top karma items of %s: " % event.channel, res)
  147. cmnds.add("karma-good", handle_karmagood, ["OPER", "USER", "GUEST"])
  148. examples.add("karma-good", "show top karma items of a channel", "karma-good")