stats.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # encoding=utf-8
  2. '''Stats information'''
  3. import json
  4. from terroroftinytown.event import Bus
  5. __all__ = ['Stats', 'stats_bus']
  6. stats_bus = Bus()
  7. class Stats:
  8. def __init__(self, redis, redis_prefix, count=30):
  9. global stats
  10. self.redis = redis
  11. self.prefix = redis_prefix
  12. self.count = count
  13. Stats.instance = self
  14. def update(self, stats):
  15. # live stats
  16. key = self.get_key()
  17. self.redis.lpush(key, json.dumps(stats))
  18. self.redis.ltrim(key, 0, self.count)
  19. # users lifetime stat
  20. self.redis.hincrby(key+':s', stats['username'], stats['scanned'])
  21. self.redis.hincrby(key+':f', stats['username'], stats['found'])
  22. # total stats
  23. self.redis.incrby(key+':ts', stats['scanned'])
  24. self.redis.incrby(key+':tf', stats['found'])
  25. # project stats
  26. self.redis.hincrby(key+':pf', stats['project'], stats['found'])
  27. self.redis.hincrby(key+':ps', stats['project'], stats['scanned'])
  28. stats_bus.fire(**stats)
  29. def get_live(self):
  30. '''Return live item results, for format of output see model.checkin_item'''
  31. return [json.loads(item.decode('utf-8')) for item in self.redis.lrange(self.get_key(), 0, self.count)]
  32. def get_lifetime(self):
  33. '''
  34. Return lifetime stats for all users.
  35. Output:
  36. {
  37. 'username': [found, scanned],
  38. ...
  39. }
  40. '''
  41. key = self.get_key()
  42. scanned = self.redis.hgetall(key+':s')
  43. found = self.redis.hgetall(key+':f')
  44. out = {}
  45. for user, count in scanned.items():
  46. out[user.decode('utf-8')] = [int(found[user]), int(count)]
  47. return out
  48. def get_user_lifetime(self, user):
  49. '''Return user lifetime stats as array of [found, scanned]'''
  50. key = self.get_key()
  51. scanned = self.redis.hget(key+':s', user) or 0
  52. found = self.redis.hget(key+':f', user) or 0
  53. return [int(found), int(scanned)]
  54. def get_global(self):
  55. '''Return total stats as array of [found, scanned]'''
  56. found = self.redis.get(self.get_key()+':tf')
  57. scanned = self.redis.get(self.get_key()+':ts')
  58. return [
  59. int(found) if found else 0,
  60. int(scanned) if scanned else 0
  61. ]
  62. def get_project(self):
  63. key = self.get_key()
  64. scanned = self.redis.hgetall(key+':ps')
  65. found = self.redis.hgetall(key+':pf')
  66. out = {}
  67. for project, count in scanned.items():
  68. out[project.decode('utf-8')] = [int(found[project]), int(count)]
  69. return out
  70. def get_key(self):
  71. return self.prefix + 'stats'
  72. def clear(self):
  73. key = self.get_key()
  74. self.redis.delete(
  75. key, key + ':s', key + ':f', key + ':ts', key + ':tf',
  76. key + ':pf', key + ':ps'
  77. )
  78. Stats.instance = None