-
Notifications
You must be signed in to change notification settings - Fork 4
/
ActivityInfo.py
131 lines (117 loc) · 5.47 KB
/
ActivityInfo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- coding: utf-8 -*-
from util import *
from itchat.content import *
from ProcessInterface import ProcessInterface
import itchat
import numpy as np
# from matplotlib.font_manager import FontProperties
from matplotlib.dates import HourLocator, DateFormatter
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as pp
from time import time
from datetime import datetime, timedelta
from collections import Counter
class ActivityInfo(ProcessInterface):
timestampSubtract = 3600 * 24 # 1 day
maxActivityInfoCount = 10
imgDir = 'Temp'
def __init__(self):
# self.coll = DbClient[dbName][collName]
# self.prop = FontProperties(fname=FontPath)
logging.info('ActivityInfo initialized.')
def process(self, msg, type):
if type != TEXT:
return
if msg['Content'] == '/activity':
group_id, group_name = get_group_info(msg)
logging.info('Generating activity info for {0}.'.format(group_name))
fn = self.generateActivityInfoForGroup(group_name)
itchat.send_image(fn, group_id)
elif msg['Content'] == '/myactive':
group_id, group_name = get_group_info(msg)
user = msg['ActualNickName']
logging.info('Generating activity info for {}-{}.'.format(group_name, user))
fn = self.generateActivityInfoForPerson(group_name, user)
itchat.send_image(fn, group_id)
def generateActivityInfoForPerson(self, group_name, user):
hour_data = [0] * 24
records = select_item_with_sql("select * from msg where group_name='{}' and from='{}'".format(group_name, user))
for r in records:
rtime = datetime.strptime(r['time'], '%Y-%m-%d %H:%M:%S')
hour = rtime.hour
hour_data[hour] += 1
n = 24
x = np.arange(n)
bar_width = 0.5
opacity = 1
pp.figure()
pp.bar(x, hour_data, bar_width, alpha=opacity, color='#87CEFA') #, label='发言数量'
pp.xlabel('小时', fontproperties=FontProp)
pp.ylabel('数量', fontproperties=FontProp)
pp.title('{} 发言数24小时统计图'.format(user), fontproperties=FontProp)
pp.xticks(x, list(range(n)))
# plt.ylim(0, max(hour_data[2]) * 1.2)
pp.legend()
pp.tight_layout()
fn = generateTmpFileName(self.imgDir)
pp.savefig(fn)
return fn
def generateActivityInfoForGroup(self, group_name):
timestamp_yesterday = int(time()) - self.timestampSubtract #北京时间
records = select_item_with_sql("select * from msg where group_name='{}' and timestamp>{} ORDER BY timestamp desc".format(group_name, timestamp_yesterday))
# list(HisColl.find({'to': group_name, 'timestamp': {'$gt': timestamp_yesterday}}).sort([('timestamp', DESCENDING)]))
# Get histogram for activity
hist, bins = np.histogram([x['timestamp'] for x in records], bins=24)
center = (bins[:-1] + bins[1:]) / 2
datex = [datetime.fromtimestamp(x, time_zone) for x in center]
pp.figure(figsize=(6, 16))
# pp.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0, hspace=0.5)
pp.subplots_adjust(bottom=0.05, top=0.95, hspace=0.4)
ax = pp.subplot(3, 1, 1)
pp.plot_date(datex, hist, '.-')
pp.gcf().autofmt_xdate()
pp.xlabel('时间', fontproperties=FontProp)
pp.ylabel('每小时消息数', fontproperties=FontProp)
ax.xaxis.set_major_formatter(DateFormatter('%m-%d %H:%M'))
# Get bar chart for active users
self.get_activitydata(records)
self.get_activitydata2(group_name)
fn = generateTmpFileName(self.imgDir)
pp.savefig(fn)
return fn
def get_activitydata(self, records):
pieDat = Counter([x['from'] for x in records])
pieDatSorted = sorted([(k, pieDat[k]) for k in pieDat], key=lambda x: x[1], reverse=True)
if len(pieDatSorted) > self.maxActivityInfoCount:
pieDatSorted = pieDatSorted[:self.maxActivityInfoCount]
ax = pp.subplot(3, 1, 2)
width = 0.7
x = np.arange(len(pieDatSorted)) + width
xText = [xx[0] for xx in pieDatSorted]
y = [xx[1] for xx in pieDatSorted]
pp.bar(x, y, width)
a = pp.gca()
a.set_xticklabels(a.get_xticks(), {'fontProperties': FontProp})
pp.xticks(x, xText, rotation='vertical')
pp.xlabel('用户', fontproperties=FontProp)
pp.ylabel('24小时消息数', fontproperties=FontProp)
ax.set_xlim([0, len(xText) + 1 - width])
def get_activitydata2(self, group_name):
records = select_item_with_sql("select * from msg where group_name='{}'".format(group_name))
pieDat = Counter([x['from'] for x in records])
pieDatSorted = sorted([(k, pieDat[k]) for k in pieDat], key=lambda x: x[1], reverse=True)
if len(pieDatSorted) > self.maxActivityInfoCount:
pieDatSorted = pieDatSorted[:self.maxActivityInfoCount]
ax = pp.subplot(3, 1, 3)
width = 0.7
x = np.arange(len(pieDatSorted)) + width
xText = [xx[0] for xx in pieDatSorted]
y = [xx[1] for xx in pieDatSorted]
pp.bar(x, y, width)
a = pp.gca()
a.set_xticklabels(a.get_xticks(), {'fontProperties': FontProp})
pp.xticks(x, xText, rotation='vertical')
pp.xlabel('用户', fontproperties=FontProp)
pp.ylabel('总消息数', fontproperties=FontProp)
ax.set_xlim([0, len(xText) + 1 - width])