微信提醒打卡小工具

在公司辛辛苦苦工作一天,加班到晚上八点,急匆匆赶上最后一辆班车,回到公寓。洗一个热水澡,躺在床上刷微博、知乎,真想大声说一句,”这一刻是最舒服的!”。然而,有时你会触电般惊起,呆坐在床边,心中一万头草泥马飘过,没打卡就回来了呀!!!
相信很多同学也遇到过这样的问题,辛苦工作一个月,发工资那天还要看工资条上会扣几百大洋,简直不能忍。

其实我的记性也算不错,一直没有忘记打卡,并且公司也推出了三次补打卡的机会。直到那天,那是一个恬静的午后,我喝这下午茶(其实是冰红茶),打着fifa,突然想到查一查我的考勤记录。然后我就没心情完游戏了。周五下午没打卡。那赶紧去OA上补打卡啊。打开页面找了半天终于找到,此刻的我已是内流满面,感谢公司,感谢行政的同事,感谢……什么?!超过24小时不能补打卡?!
好了,这就是我写这个小工具的全部背景。

思路

公司有面向员工的考勤记录系统,这是基础。没有这个就不要想了,还是老老实实定个闹钟每天按时打卡把。
考勤记录系统是个简单的网页,用工号登录,考勤记录是json格式。那直接post登录,看json的最后一行就ok了。感谢IT部门的同事写的简单后台。
用什么提醒,刚开始想的是自己给自己发邮件。后来想到不是工作时间,我应该不会看邮件。其实到这个时候我想着服务的人还只是我自己。
后来在github上发现了itchat,一个个人微信接口,而且还是用python写的(窃喜),看了一下他的源码,是模仿公众号的官方接口写的,登录的是网页版的微信。
大致思路就是定时爬取考勤系统的打卡记录,如果当天记录没有两次,就发送微信提醒。

分两部分

爬考勤系统

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
#-*- coding:utf-8 -*-
#!/usr/bin/python

import HTMLParser
import urlparse
import urllib
import urllib2
import cookielib
import string
import re
import sys
import simplejson as json
import commands

__author__ = 'yangguang'

def spider_clock(work_num):#登录考勤系统,保存打卡记录
date_time = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
date = date_time.split(" ")[0]
year_moth = "-".join(date.split("-")[:2])
hosturl = 'http://kq.novogene.com:8080'
posturl = 'http://kq.novogene.com:8080/selfservice/login/?next=selfservice/'
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)
urllib2.install_opener(opener)
h = urllib2.urlopen(hosturl)
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1'}
postData = {'username' : work_num,'password' : '123456','template9' : '','finnger10' : '','finnger9' : '','template10' : '','login_type' : 'pwd','client_language' : 'zh-cn'}
postData = urllib.urlencode(postData)
request = urllib2.Request(posturl, postData, headers)
response = urllib2.urlopen(request)
##
postData_table = {'page':'1','rp':'100','sortname':'undefined','sortorder':'undefined','query':'','qtype':'','UserIDs':'1940','ComeTime': year_moth+'-01','EndTime':date}
table_url = 'http://kq.novogene.com:8080/selfatt/grid/selfatt/CardTimes/'
postData_table = urllib.urlencode(postData_table)
req = urllib2.Request(table_url, postData_table, headers)
text = urllib2.urlopen(req).read()
##
if text.split('"')[1] != 'rows':
return "Error passwd"
else:
Clock_dic = json.loads(text)
return Clock_dic

def check_clock(date_time,work_num):#检查最后一行是不是今天的,且打卡时间是否正确
date = date_time.split(" ")[0]
year_moth = "-".join(date.split("-")[:2])
time = date_time.split(" ")[1].split(":")[0].strip("0")
#
Clock_dic = spider_clock(work_num)
if Clock_dic == "Error passwd":
return "Error_passwd+"+work_num
if len(Clock_dic['rows']) == 0:
return work_num
else:
clock_time = Clock_dic['rows'][-1]['ClockInTime']
clock_count = len(clock_time.strip().split(","))
clock_list = clock_time.strip().split(",")
if date != Clock_dic['rows'][-1]['card_date']:
return work_num
else:
if int(time)<=10:
if int(clock_list[0].split(":")[0].strip("0")) > 10:
return work_num
elif int(time)>10:
if len(clock_list[-2].strip()) == 0 or int(clock_list[-2].split(":")[0].strip("0")) < 18 :
return work_num

发送微信提醒

先安装itchat微信接口,是个python包

1
sudo pip install itchat

然后看看源码吧,这个github页面介绍的也不是很清楚

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
# -*- coding: utf-8 -*-
#!/usr/bin/python
import itchat
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import commands

def get_UserName(friends_name):#用备注名找UserName,但是如果是我自己的话是没有备注名的,需要判断一下.这里要注意微信是通过UserName进行通信的,而且这个UserName还一直会变,所以要找一个固定的识别flag,这里选备注名
if friends_name == "杨光":
flag = 'PYQuanPin'
else:
flag = 'RemarkName'
for friend in itchat.get_friends():
if flag in friend.keys():
if friend[flag] == friends_name:
return friend['UserName']
break

def get_remarkname(UserName):
for un in itchat.get_friends():
if 'RemarkName' in un.keys():
if un['UserName'] == UserName:
remarkname = un['RemarkName']
return remarkname
break

def send_wechat(warning_people_list):#提醒打卡
date = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
itchat.auto_login(hotReload=True,enableCmdQR=2)
for people in warning_people_list:
UserName = get_UserName(people)
itchat.send(people+',请注意,今天还没有打卡哟~\n'+date+'\n本消息自动发送,请勿回复\n如若信息有误,请联系yangguang@novogene.com', toUserName=UserName)

def send_erro_info(warning_people_list):#发送考勤系统密码不正确的信息
date = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
itchat.auto_login(hotReload=True,enableCmdQR=2)
for people in warning_people_list:
UserName = get_UserName(people)
itchat.send(people+',请注意,考勤密码错误,请改回初始密码123456\n'+date+'\n本消息自动发送,请勿回复\n如若信息有误,请联系yangguang@novogene.com', toUserName=UserName)

check clock

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
wfile = open("/home/yangguang/Clock_reminder/work_num.txt",'r')
# 将姓名与工号保存于文件中,check_clock返回工号,然后用工号找姓名然后用姓名作备注名获得UserName
date = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
wechat_users = []
erro_passwd = []
for line in wfile:
work_num = line.strip().split("\t")[0]
friend_name = line.strip().split("\t")[1].strip("\n")
clock_status = check_clock.check_clock(date,work_num)
# 检查是否打卡
if clock_status != None and clock_status.split("+")[0] == "Error_passwd":
erro_passwd.append(friend_name)
elif clock_status != None:
wechat_users.append(friend_name)
wfile.close()
send_wechat.send_wechat(wechat_users)
#发送打卡提醒
send_wechat.send_erro_info(erro_passwd)
#发送密码错误提醒

至此,这个打卡提醒基本完成。每天9:45和晚上18:50,19:55定时运行此脚本即可。
crontab -e 添加如下命令

1
2
3
45 9 * * 1,2,3,4,5 /usr/bin/python /home/yangguang/Clock_reminder/Clock_reminder.py >> /home/yangguang/Clock_reminder/Clock_reminder.py.log  2>&1
50 18 * * 1,2,3,4,5 /usr/bin/python /home/yangguang/Clock_reminder/Clock_reminder.py >> /home/yangguang/Clock_reminder/Clock_reminder.py.log 2>&1
55 19 * * 1,2,3,4,5 /usr/bin/python /home/yangguang/Clock_reminder/Clock_reminder.py >> /home/yangguang/Clock_reminder/Clock_reminder.py.log 2>&1

进阶

每天提醒三次还是感觉像定了个闹钟(其实还是装X感不足,不能拿出去炫耀)。于是想到为啥不加个可以随时随地查询打卡时间的方法,因为itchat这个接口真的是功能强大。
于是乎,加个获取打卡时间

1
2
3
4
5
6
7
8
9
10
11
def get_clock(work_num):
date_time = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')
date = date_time.split(" ")[0]
Clock_dic = spider_clock(work_num)
if len(Clock_dic['rows']) == 0:
return
elif date != Clock_dic['rows'][-1]['card_date']:
return
else:
clock_time = Clock_dic['rows'][-1]['ClockInTime']
return clock_time

再写个自动回复微信的脚本,大功告成

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
# -*- coding: utf-8 -*-
#!/usr/bin/python
import itchat, time
from itchat.content import *
import sys
reload(sys)
sys.setdefaultencoding('utf8')
import check_clock

@itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING])
def text_reply(msg):
if msg['Content'] == "clock":
people = open("/home/yangguang/Clock_reminder/work_num.txt",'r')
friend_num = {}
for line in people:
friend_num[unicode(line.split("\t")[1].strip("\n"),"utf-8")] = line.split("\t")[0]
if msg['User']['RemarkName'] != '':
friend_name = msg['User']['RemarkName']
else:
friend_name = msg['User']['NickName']
work_num = friend_num[friend_name]
text_content = check_clock.get_clock(work_num)
if text_content == None:
text_content = "今天还未打卡"
else:
text_content = "今天的打卡时间为:"+text_content
itchat.send(text_content, msg['FromUserName'])

这样给我的微信发个clock就可以获得当天的打卡时间了。因为考勤系统需要内网才能登陆,所以这个功能真是受到了很多人的喜爱。这样一个场景是经常发生的:在班车上好不容易找到了一个座位,坐定,掏出耳机。不知道刚才出来是否打过卡了。以前没办法,为了保险起见你只能跑回公司打个卡再回来。

推广

推广时遇到了问题,我的把每个人的工号,姓名加到那个work_num.list中去,我得经常登陆服务器,这小服务器也要公司内网才行。最重要的是这个过程很low,哈哈哈哈哈。
于是乎,好吧,在那个自动回复的脚本中加上自动加好友吧

1
2
3
4
5
6
7
8
@itchat.msg_register(FRIENDS)
def add_friend(msg):
each = msg['RecommendInfo']['Content'].split("+")
if each[0] == 'novo':
itchat.add_friend(**msg['Text'])
itchat.set_alias(msg['RecommendInfo']['UserName'],each[2])
itchat.send_msg('亡羊补牢不如未雨绸缪(・ิϖ・ิ)っ\n打卡提醒每天两次,分别在上午9:40和下午18:45,此消息只发给未打卡的旁友\n忘记有没有打卡可以发送clock获取当天的打卡记录\n发送 help 获取其他用法\n请确保考勤系统密码还是初始的123456( •̀∀•́ )', msg['RecommendInfo']['UserName'])
os.system('echo "%s %s" >> /home/yangguang/Clock_reminder/work_num.txt'%(each[1],each[2]))

这样别人在加我的时候,只要在验证消息里输入novo+工号+姓名,就可以自动加上,并且收到一条说明消息。

后记

后面我在实际运行中,还加了一些其他功能,比如帮其他人查打卡时间,查其他同事的电话号码等。
这种小项目还是蛮有趣的,我想主要是能直接解决一些生活问题(其实我感觉很多小妹妹加我微信才是我的动力来源)。