-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.py
390 lines (337 loc) · 16.1 KB
/
main.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
'''
Descripttion:
version:
Author: Catop
Date: 2021-02-10 07:47:09
LastEditTime: 2021-02-18 07:40:13
'''
#coding:utf-8
from flask import Flask,request,jsonify
import json
import requests
import dbconn
import goapi
import time
import os
import compress
import urllib.parse
import random
import ocrplus
import inputFilter
import json
app = Flask(__name__)
@app.route('/', methods=['POST'])
def getEvent():
data = request.json
post_type = data.get('post_type')
if(post_type == 'message'):
message_type = data.get('message_type')
#print(data)
message = data.get('message')
user_id = str(data.get('user_id'))
if(message_type=='private' and (dbconn.check_register(user_id)==1 or '注册' in message)):
#仅接收注册用户的消息和注册消息
print(f"--------------------\n接收消息@{user_id}:{message[:20]}")
readMsg(user_id,message)
elif(post_type == 'request'):
request_type = data.get('request_type')
if(request_type=='friend'):
user_id = str(data.get('user_id'))
comment = str(data.get('comment'))
flag = str(data.get('flag'))
print(f"--------------------\n接收加好友请求@{user_id}:{comment[:20]}")
time.sleep(random.randint(5,10))
goapi.add_request(flag)
time.sleep(random.randint(5,10))
goapi.sendMsg(user_id,"欢迎!\n请先注册,例如'注册@小明@智科20-2'\n 班级请严格按格式输入,否则可能统计不上哦,另外特别注意'-'是减号不是破折号,也不要加空格")
else:
#暂不处理其他类型上报,为防止go-cq报错而设置
pass
return data
def readMsg(user_id,message):
#处理消息核心
user_id = str(user_id)
#管理员列表
admin_list = show_admin()
if('image' in message):
if(dbconn.check_register(user_id)):
#用户已注册
get_img(user_id,message)
else:
#用户未注册
goapi.sendMsg(user_id,'您还没注册呢,请输入例如"注册@小明@智科20-2"\n 班级请严格按格式输入,否则可能统计不上哦,另外特别注意'-'是减号不是破折号,也不要加空格')
return
if('注册' in message):
try:
user_name = message.split('@')[1]
user_class = message.split('@')[2]
#简单过滤用户输入
if not(inputFilter.is_Chinese(user_name) and inputFilter.check_length(user_name)):
goapi.sendMsg(user_id,'输入好像有点问题呢')
return
if not(inputFilter.is_valid(user_class) and inputFilter.check_length(user_class)):
goapi.sendMsg(user_id,'输入好像有点问题呢')
return
except:
goapi.sendMsg(user_id,'输入好像有点问题呢')
else:
if(dbconn.check_register(user_id)):
goapi.sendMsg(user_id,'您已注册过啦~')
re_register_user(user_id,user_name,user_class)
else:
register_user(user_id,user_name,user_class)
return
if('/admin' in message):
user_class = dbconn.get_user(user_id)['user_class']
upload_date = time.strftime("%Y-%m-%d", time.localtime())
print(user_id)
if(user_id in admin_list.keys()):
group_id = admin_list[user_id]
if('群提醒' in message):
send_alert(group_id,dbconn.get_user(user_id)['user_class'],'group')
elif('提醒'in message):
send_alert(user_id,dbconn.get_user(user_id)['user_class'],'private')
upload_date = time.strftime("%Y-%m-%d", time.localtime())
time.sleep(1)
#ocr_err_upload(user_id,user_class,upload_date)
ocr_err_upload(user_id,user_class,upload_date)
time.sleep(2)
send_images_info(user_id,user_class)
elif('打包'in message):
cmp_ret = compress.zip_file(upload_date,dbconn.get_user(user_id)['user_class'])
goapi.sendMsg(user_id,f"---打包完毕---\n共处理:{cmp_ret['file_num']}张照片")
goapi.sendMsg(user_id,'下载地址:'+urllib.parse.quote(cmp_ret['file_name']))
elif('成员'in message):
list_class_menbers(user_id,user_class)
elif('核对'in message):
goapi.sendMsg(user_id,'get')
err_imgid = message.split('@')[1]
ocr_times = message.split('@')[2]
ocr_scores = message.split('@')[3]
if(dbconn.err_check):
err_code = dbconn.err_check(err_imgid)
if(err_code):
dbconn.manual_update(ocr_times,ocr_scores,err_imgid)
goapi.sendMsg(user_id,f"人工校对完成:{dbconn.get_user_by_migid(err_imgid)}\n参赛次数:{ocr_times}\n积分:{ocr_scores}")
elif(err_code == 0):
goapi.sendMsg(user_id,'该图片无需校对,请重新检查输入的id')
elif(err_code == -1):goapi.sendMsg(user_id,f"已经人工校对过了,覆盖校对:\n{dbconn.get_user_by_migid(imgid)}\n参赛次数:{ocr_times}\n积分:{ocr_scores}")
else:
goapi.sendMsg(user_id,"目前支持以下管理指令呢:\n群提醒\n提醒\n打包\n成员\n")
else:
goapi.sendMsg(user_id,"无管理权限")
if('/sudo' in message and (user_id=='601179193' or user_id=="29242764" or user_id=="1476821890" or user_id=="3439911708")):
#try:
if('增加管理员' in message):
admin_id = message.split('@')[1]
group_id = message.split('@')[2]
goapi.sendMsg(user_id,str(add_admin(admin_id,group_id)))
elif('删除管理员' in message):
admin_id = message.split('@')[1]
goapi.sendMsg(user_id,str(del_admin(admin_id)))
elif('展示管理员' in message):
goapi.sendMsg(user_id,str(show_admin()))
else:
goapi.sendMsg(user_id,'增加管理员\n删除管理员\n展示管理员')
#except:
#goapi.sendMsg(user_id,'增加管理员\n删除管理员\n展示管理员')
#else:
#pass
return
def get_img(user_id,message):
#从message中解析到图片下载地址,并保存数据库,下载文件
try:
img_url = message.split('url=')[1][0:-1]
user_name = dbconn.get_user(user_id)['user_name']
user_class = dbconn.get_user(user_id)['user_class']
upload_date = time.strftime("%Y-%m-%d", time.localtime())
upload_time = time.strftime("%H:%M:%S", time.localtime())
#修改文件名格式(注意只保存文件名和数据库中显示的file_name改变,目录等名称不变)
file_date = time.strftime("%Y%m%d", time.localtime())
#安全过滤
if not(img_url[0:24] == 'http://c2cpicdw.qpic.cn/'):
goapi.sendMsg(user_id,'图片url解析错误')
return
#判断文件目录是否存在
if not(os.path.exists(f"images/{upload_date}")):
os.mkdir(f"images/{upload_date}")
if not(os.path.exists(f"images/{upload_date}/{user_class}")):
os.mkdir(f"images/{upload_date}/{user_class}")
file_name = f"/{upload_date}/{user_class}/{user_class}班-{user_name}-{file_date}.jpg"
if(dbconn.check_today_upload(user_id,upload_date)):
goapi.sendMsg(user_id,'您今天已经上传过照片啦,已覆盖之前的图片~')
download_img(img_url,file_name)
#print(img_url)
except Exception as err:
goapi.sendMsg(user_id,'图片下载出错了!')
print(err)
else:
print("成功处理图片:"+file_name)
goapi.sendMsg(user_id,"成功处理图片,正在识别...\n"+f"{user_class}班-{user_name}-{file_date}.jpg")
"""图片识别部分"""
try:
print(file_name)
ocr_ret = ocrplus.ocr_img("images"+file_name)
ocr_err_code = ocr_ret['err_code']
if(ocr_err_code == 0):
goapi.sendMsg(user_id,f"参赛次数:{ocr_ret['个人参赛次数']}\n个人积分:{ocr_ret['个人积分']}")
ocr_times = ocr_ret['个人参赛次数']
ocr_scores = ocr_ret['个人积分']
else:
print("图片无法识别:"+ocr_ret)
#图片识别接口返回无法识别
goapi.sendMsg(user_id,f"OCR无法识别,团支书将人工复核~")
dbconn.insert_img(user_id,file_name,upload_date,upload_time,'1','0','0')
return
except:
#图片识别接口出错
print("OCR接口出错:")
goapi.sendMsg(user_id,f"qwq图片识别出错了!可能是字体原因,请尝试更换字体后重试")
dbconn.insert_img(user_id,file_name,upload_date,upload_time,'1','0','0')
else:
dbconn.insert_img(user_id,file_name,upload_date,upload_time,ocr_err_code,ocr_times,ocr_scores)
return
def download_img(img_url,file_name):
res = requests.get(img_url, stream=True)
if res.status_code == 200:
open('images/'+file_name, 'wb').write(res.content)
#print("image"+file_name+"saved successfully.")
def register_user(user_id,user_name,user_class):
if(dbconn.register_user(user_id,user_name,user_class) == 1):
goapi.sendMsg(user_id,'注册成功,现在可以开始上传图片了~')
else:
goapi.sendMsg(user_id,'注册失败'+f"user_id={user_id},user_name={user_name},user_class={user_class}")
def re_register_user(user_id,user_name,user_class):
if(dbconn.re_register_user(user_id,user_name,user_class) == 1):
goapi.sendMsg(user_id,'已更新字段')
else:
goapi.sendMsg(user_id,'更新字段失败:'+f"user_id={user_id},user_name={user_name},user_class={user_class}")
def send_alert(group_id,user_class,type='private'):
group_menbers = dbconn.get_class_members(user_class)
current_date = time.strftime("%Y-%m-%d", time.localtime())
alert_users = {}
#user_id:last_date
for user_id in group_menbers:
#print(user_id)
try:
last_date = dbconn.check_status(user_id)
except TypeError:
#还没发过照片
alert_users[user_id] = '无记录'
else:
if(str(last_date)!=str(current_date)):
alert_users[user_id] = str(last_date)[5:]
#print(alert_users)
msg = f"今天还有{len(alert_users)}位小可爱未完成哦\n"
if(type=='private'):
for user_id in alert_users.keys():
last_date = alert_users[user_id]
msg += f"{dbconn.get_user(user_id)['user_name']}({alert_users[user_id]})\n"
msg+=f"{user_class} {current_date}\n完成情况:{len(group_menbers)-len(alert_users)}/{len(group_menbers)}"
goapi.sendMsg(group_id,msg)
elif(type=='group'):
for user_id in alert_users.keys():
last_date = alert_users[user_id]
msg += f"[CQ:at,qq={user_id}]({alert_users[user_id]})\n"
msg += f"{user_class} {current_date}\n完成情况:{len(group_menbers)-len(alert_users)}/{len(group_menbers)}"
goapi.sendGroupMsg(group_id,msg)
def list_class_menbers(user_id,user_class):
msg = f"{user_class}成员情况:\n"
ret = dbconn.get_class_members(user_class)
for i in range(0,len(ret)):
msg += f"{ret[i]} {dbconn.get_user(str(ret[i]))['user_name']}\n"
msg += f"共计{str(len(ret))}人"
goapi.sendMsg(user_id,msg)
def ocr_err_upload(user_id,user_class,upload_date):
"""为管理员上报ocr错误的图片"""
msg = "OCR无法识别以下图片:\n"
err_list = []
err_imgid = []
class_menbers = dbconn.get_class_members(user_class)
for i in range(0,len(class_menbers)):
img_date = dbconn.check_status(class_menbers[i])
if(str(img_date) == str(upload_date)):
img_info = dbconn.get_latest_img_info(class_menbers[i],upload_date)[0]
#print(img_info)
if(img_info['ocr_err_code'] == 1):
print(img_info)
err_list.append(img_info['file_name'])
err_imgid.append(img_info['imgid'])
for i in range(0,len(err_list)):
cqCode = f"[CQ:image,file=file:{os.getcwd()}/images{err_list[i]}]"
msg += f"id:{err_imgid[i]}\n"
msg += f"{cqCode}\n"
msg += f"数量:{len(err_list)}/{len(class_menbers)}\n"
msg += "可人工核对,操作格式: /admin 核对@id@次数@分数,例如:\n核对id为233,次数66,分数99则输入:/admin 核对@233@66@99"
goapi.sendMsg(user_id,msg)
return msg
######################################################################
# def manual_identify(user_id,user_class,upload_date):
# """管理员手动识别ocr错误的图片"""
# msg="OCR无法识别以下图片"
# goapi.sendMsg(user_id,msg)
# err_list = []
# user_info = []
# class_menbers = dbconn.get_class_members(user_class)
# for i in range(0,len(class_menbers)):
# img_date = dbconn.check_status(class_menbers[i])
# if(str(img_date) == str(upload_date)):
# img_info = dbconn.get_latest_img_info(class_menbers[i],upload_date)[0]
# #print(img_info)
# if(img_info['ocr_err_code'] == 1):
# print(img_info)
# err_list.append(img_info['file_name'])
# i = 0
# while i < len(err_list):
# cqCode = f"[CQ:image,file=file:{os.getcwd()}/images{err_list[i]}]"
# msg = f"{cqCode}\n"
# msg += f"请人工核对,格式:核对@答题次数@答题分数,例如:核对@43@505"
# goapi.sendMsg(user_id,msg)
# if ("核对" in message )
# ocr_times = message.split('@')[1]
# ocr_scores = message.split('@')[2]
######################################################################
def send_images_info(user_id,user_class):
"""上报班级图片情况(次数和成绩)"""
class_menbers = dbconn.get_class_members(user_class)
today_upload_count = 0
upload_date = time.strftime("%Y-%m-%d", time.localtime())
msg = f"{user_class} {upload_date}情况:\n"
for i in range(0,len(class_menbers)):
if(str(dbconn.check_status(class_menbers[i])) == str(upload_date)):
today_upload_count += 1
img_info = dbconn.get_latest_img_info(class_menbers[i],upload_date)[0]
if(img_info['ocr_err_code'] == 0):
msg += f"·{dbconn.get_user(class_menbers[i])['user_name']} 次数{img_info['ocr_times']} 分数{img_info['ocr_scores']}\n"
else:
msg += f"·{dbconn.get_user(class_menbers[i])['user_name']} 未识别到\n"
msg += f"共计{today_upload_count}张照片"
goapi.sendMsg(user_id,msg)
return msg
def add_admin(user_id,class_id):
admin_list = show_admin()
admin_list[str(user_id)] = str(class_id)
with open("admin_list.txt","w") as f:
json.dump(admin_list,f)
return admin_list
def del_admin(user_id):
admin_list = show_admin()
del admin_list[str(user_id)]
with open("admin_list.txt","w") as f:
json.dump(admin_list,f)
return admin_list
return admin_list
def show_admin():
with open("admin_list.txt","r") as f:
admin_list = json.load(f)
return admin_list
if __name__ == '__main__':
app.run(host='127.0.0.1',port='5000',debug=False)
#send_alert('1038368144','信安20-2','group')
#goapi.sendMsg('29242764','[CQ:image,file=file:/Users/catop/Desktop/ChangZhengBot/go-cq/res1.png]')
#print(ocr_err_upload('29242764','信安20-2','2021-02-13'))
#goapi.sendMsg('29242764','[CQ:image,file=file:/Users/catop/Desktop/ChangZhengBot/images/2021-02-13/信安20-2/信安20-2班-张宏远-20210213.jpg]')
#ocr_err_upload('601179193','信安20-2','2021-02-13')
#print(send_images_info('29242764','信安20-2'))
#print(show_admin())
#print(del_admin('1234567890'))