i just come out and take a bubble, haha \O^O/

This commit is contained in:
urinx
2017-04-16 21:55:51 +08:00
parent 504cc4f0f6
commit c1e702aafd
38 changed files with 3809 additions and 50 deletions
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/env python
# coding: utf-8
from config_manager import ConfigManager
from constant import Constant
from log import Log
@@ -0,0 +1,105 @@
#!/usr/bin/env python
# coding: utf-8
#===================================================
from constant import Constant
#---------------------------------------------------
import ConfigParser
import os
#===================================================
class ConfigManager(object):
def __init__(self):
self.config = Constant.WECHAT_CONFIG_FILE
self.cp = ConfigParser.ConfigParser()
self.cp.read(self.config)
data_dir = self.get('setting', 'prefix')
upload_dir = self.getpath('uploaddir')
if not os.path.exists(data_dir):
os.makedirs(data_dir)
if not os.path.exists(upload_dir):
os.makedirs(upload_dir)
def get(self, section, option):
return self.cp.get(section, option)
def set(self, section, option, value):
self.cp.set(section, option, value)
self.cp.write(open(self.config, 'w'))
def getpath(self, dir):
prefix = self.get('setting', 'prefix')
return prefix + self.get('setting', dir)
def setup_database(self):
path = self.get('setting', 'prefix')
conf = [
path + self.get('setting', 'uploaddir'),
path + self.get('setting', 'datadir'),
path + self.get('setting', 'logdir'),
]
return conf
def set_wechat_config(self, conf):
for [key, value] in conf.items():
self.cp.set('wechat', key, value)
self.cp.write(open(self.config, 'w'))
def get_wechat_config(self):
uin = self.cp.get('wechat', 'uin')
last_login = self.cp.get('wechat', 'last_login')
conf = [
self.cp.get('wechat', 'uuid'),
self.cp.get('wechat', 'redirect_uri'),
int(uin if uin else 0),
self.cp.get('wechat', 'sid'),
self.cp.get('wechat', 'skey'),
self.cp.get('wechat', 'pass_ticket'),
self.cp.get('wechat', 'synckey'),
self.cp.get('wechat', 'device_id'),
float(last_login if last_login else 0),
]
return conf
def get_wechat_media_dir(self):
prefix = self.get('setting', 'prefix')
path = prefix + self.cp.get('setting', 'mediapath')
return {
'webwxgeticon': path + '/icons',
'webwxgetheadimg': path + '/headimgs',
'webwxgetmsgimg': path + '/msgimgs',
'webwxgetvideo': path + '/videos',
'webwxgetvoice': path + '/voices',
'_showQRCodeImg': path + '/qrcodes',
}
def get_pickle_files(self):
prefix = self.get('setting', 'prefix')
return {
'User': prefix + self.get('setting', 'contact_user'),
'MemberList': prefix + self.get('setting', 'contact_member_list'),
'GroupList': prefix + self.get('setting', 'contact_group_list'),
'GroupMemeberList': prefix + self.get('setting', 'contact_group_memeber_list'),
'SpecialUsersList': prefix + self.get('setting', 'contact_special_users_list'),
}
def get_cookie(self):
prefix = self.get('setting', 'prefix')
path = prefix + self.get('setting', 'cookie')
basedir = os.path.dirname(path)
if not os.path.exists(basedir):
os.makedirs(basedir)
return path
def mysql(self):
mysql = {
'host': self.get('mysql', 'host'),
'port': self.cp.getint('mysql', 'port'),
'user': self.get('mysql', 'user'),
'passwd': self.get('mysql', 'passwd'),
'database': self.get('mysql', 'database'),
}
return mysql
+215
View File
@@ -0,0 +1,215 @@
#!/usr/bin/env python
# coding: utf-8
import time
class Constant(object):
"""
@brief All used constants are listed here
"""
WECHAT_CONFIG_FILE = 'config/wechat.conf'
LOGGING_LOGGER_NAME = 'WeChat'
QRCODE_BLACK = '\033[40m \033[0m'
QRCODE_WHITE = '\033[47m \033[0m'
HTTP_HEADER_USERAGENT = [('User-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36')]
HTTP_HEADER_CONTENTTYPE = ['ContentType', 'application/json; charset=UTF-8']
HTTP_HEADER_CONNECTION = ['Connection', 'keep-alive']
HTTP_HEADER_REFERER = ['Referer', 'https://wx.qq.com/']
HTTP_HEADER_RANGE = ['Range', 'bytes=0-']
REGEX_EMOJI = r'<span class="emoji emoji(\w+)"></span>'
SERVER_LOG_FORMAT = '%(asctime)s - %(pathname)s:%(lineno)d - %(name)s - %(levelname)s - %(message)s'
SERVER_UPLOAD_ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
SERVER_PAGE_UPLOAD = 'Server/upload.html'
SERVER_PAGE_INDEX = 'Server/index.html'
RUN_RESULT_SUCCESS = '成功 %ds\n'
RUN_RESULT_FAIL = '失败\n[*] 退出程序\n'
MAIN_RESTART = '[*] wait for restart'
LOG_MSG_FILE = 'WeChat-Msgs-%Y-%m-%d.json'
LOG_MSG_GROUP_LIST_FILE = 'group_list.json'
LOG_MSG_QUIT = '\n[*] Force quit.\n'
LOG_MSG_FAIL = '失败\n'
LOG_MSG_SUCCESS = '成功\n'
LOG_MSG_START = '[*] 微信网页版 ... 开动\n'
LOG_MSG_RECOVER = '[*] 从配置文件中恢复 ... '
LOG_MSG_RECOVER_CONTACT = '[*] 从文件中恢复联系人数据 ... '
LOG_MSG_TRY_INIT = '[*] 尝试初始化 ... '
LOG_MSG_ASSOCIATION_LOGIN = '[*] 通过关联登录 ... '
LOG_MSG_GET_UUID = '[*] 正在获取 uuid ... '
LOG_MSG_GET_QRCODE = '[*] 正在获取二维码 ... 成功\n'
LOG_MSG_SCAN_QRCODE = '[*] 请使用微信扫描二维码以登录 ... \n'
LOG_MSG_CONFIRM_LOGIN = '[*] 请在手机上点击确认以登录 ... \n'
LOG_MSG_WAIT_LOGIN_ERR1 = '[登陆超时] \n'
LOG_MSG_WAIT_LOGIN_ERR2 = '[登陆异常] \n'
LOG_MSG_LOGIN = '[*] 正在登录 ... '
LOG_MSG_INIT = '[*] 微信初始化 ... '
LOG_MSG_STATUS_NOTIFY = '[*] 开启状态通知 ... '
LOG_MSG_GET_CONTACT = '[*] 获取联系人 ... '
LOG_MSG_CONTACT_COUNT = '[*] 应有 %s 个联系人,读取到联系人 %d\n'
LOG_MSG_OTHER_CONTACT_COUNT = '[*] 共有 %d 个群 | %d 个直接联系人 | %d 个特殊账号 %d 公众号或服务号\n'
LOG_MSG_GET_GROUP_MEMBER = '[*] 拉取群聊成员 ... '
LOG_MSG_SNAPSHOT = '[*] 保存配置 ... '
LOG_MSG_LOGOUT = '[*] 你在手机上登出了微信\n'
LOG_MSG_LOGIN_OTHERWHERE = '[*] 你在其他地方登录了 WEB 版微信\n'
LOG_MSG_QUIT_ON_PHONE = '[*] 你在手机上主动退出了\n'
LOG_MSG_RUNTIME = '[*] Total run: %s\n'
LOG_MSG_KILL_PROCESS = 'kill %d'
LOG_MSG_NEW_MSG = '>>> %d 条新消息\n'
LOG_MSG_LOCATION = '[位置] %s'
LOG_MSG_PICTURE = '[图片] %s'
LOG_MSG_VOICE = '[语音] %s'
LOG_MSG_RECALL = '撤回了一条消息'
LOG_MSG_ADD_FRIEND = '%s 请求添加你为好友'
LOG_MSG_UNKNOWN_MSG = '[*] 该消息类型为: %d,内容: %s'
LOG_MSG_VIDEO = '[小视频] %s'
LOG_MSG_NOTIFY_PHONE = '[*] 提示手机网页版微信登录状态\n'
LOG_MSG_EMOTION = '[表情] %s'
LOG_MSG_NAME_CARD = (
'[名片]\n'
'=========================\n'
'= 昵称: %s\n'
'= 微信号: %s\n'
'= 地区: %s %s\n'
'= 性别: %s\n'
'========================='
)
LOG_MSG_SEX_OPTION = ['未知', '', '']
LOG_MSG_APP_LINK = (
'[%s]\n'
'=========================\n'
'= 标题: %s\n'
'= 描述: %s\n'
'= 链接: %s\n'
'= 来自: %s\n'
'========================='
)
LOG_MSG_APP_LINK_TYPE = {5: '链接', 3: '音乐', 7: '微博'}
LOG_MSG_APP_IMG = (
'[图片]\n'
'=========================\n'
'= 文件: %s\n'
'= 来自: %s\n'
'========================='
)
LOG_MSG_SYSTEM = '系统消息'
LOG_MSG_UNKNOWN_NAME = '未知_'
LOG_MSG_UNKNOWN_GROUP_NAME = '未知群_'
TABLE_GROUP_MSG_LOG = 'WeChatRoomMessage'
TABLE_GROUP_MSG_LOG_COL = """
MsgID text,
RoomOwnerID text,
RoomName text,
UserCount text,
FromUserName text,
ToUserName text,
AttrStatus text,
DisplayName text,
Name text,
MsgType text,
FaceMsg text,
TextMsg text,
ImageMsg text,
VideoMsg text,
SoundMsg text,
LinkMsg text,
NameCardMsg text,
LocationMsg text,
RecallMsgID text,
SysMsg text,
MsgTime text,
MsgTimestamp text
"""
@staticmethod
def TABLE_GROUP_LIST():
return 'WeChatRoom_' + time.strftime('%Y%m%d', time.localtime())
TABLE_GROUP_LIST_COL = """
RoomName text,
RoomID text,
RoomOwnerID text,
UserCount text,
RoomIcon text
"""
@staticmethod
def TABLE_GROUP_USER_LIST():
return 'WeChatRoomMember_' + time.strftime('%Y%m%d', time.localtime())
TABLE_GROUP_USER_LIST_COL = """
RoomID text,
MemberID text,
MemberNickName text,
MemberDisplayName text,
MemberAttrStatus text
"""
TABLE_RECORD_ENTER_GROUP = 'WeChatEnterGroupRecord'
TABLE_RECORD_ENTER_GROUP_COL = """
MsgID text,
RoomName text,
FromUserName text,
ToUserName text,
Name text,
EnterTime text
"""
TABLE_RECORD_RENAME_GROUP = 'WeChatRenameGroupRecord'
TABLE_RECORD_RENAME_GROUP_COL = """
MsgID text,
FromName text,
ToName text,
ModifyPeople text,
ModifyTime text
"""
API_APPID = 'wx782c26e4c19acffb'
API_WXAPPID = 'wx299208e619de7026' # Weibo
# 'wxeb7ec651dd0aefa9' # Weixin
API_LANG = 'zh_CN'
API_USER_AGENT = (
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/48.0.2564.109 Safari/537.36'
)
API_SPECIAL_USER = [
'newsapp', 'filehelper', 'weibo', 'qqmail',
'fmessage', 'tmessage', 'qmessage', 'qqsync',
'floatbottle', 'lbsapp', 'shakeapp', 'medianote',
'qqfriend', 'readerapp', 'blogapp', 'facebookapp',
'masssendapp', 'meishiapp', 'feedsapp', 'voip',
'blogappweixin', 'brandsessionholder', 'weixin',
'weixinreminder', 'officialaccounts', 'wxitil',
'notification_messages', 'wxid_novlwrv3lqwv11',
'gh_22b87fa7cb3c', 'userexperience_alarm',
]
EMOTICON = [
'[Smile]', '[Grimace]', '[Drool]', '[Scowl]', '[CoolGuy]', '[Sob]', '[Shy]',
'[Silent]', '[Sleep]', '[Cry]', '[Awkward]', '[Angry]', '[Tongue]', '[Grin]',
'[Surprise]', '[Frown]', '[Ruthless]', '[Blush]', '[Scream]', '[Puke]',
'[Chuckle]', '[Joyful]', '[Slight]', '[Smug]', '[Hungry]', '[Drowsy]', '[Panic]',
'[Sweat]', '[Laugh]', '[Commando]', '[Determined]', '[Scold]', '[Shocked]', '[Shhh]',
'[Dizzy]', '[Tormented]', '[Toasted]', '[Skull]', '[Hammer]', '[Wave]',
'[Relief]', '[DigNose]', '[Clap]', '[Shame]', '[Trick]',' [BahL]','[BahR]',
'[Yawn]', '[Lookdown]', '[Wronged]', '[Puling]', '[Sly]', '[Kiss]', '[Uh-oh]',
'[Whimper]', '[Cleaver]', '[Melon]', '[Beer]', '[Basketball]', '[PingPong]',
'[Coffee]', '[Rice]', '[Pig]', '[Rose]', '[Wilt]', '[Lip]', '[Heart]',
'[BrokenHeart]', '[Cake]', '[Lightning]', '[Bomb]', '[Dagger]', '[Soccer]', '[Ladybug]',
'[Poop]', '[Moon]', '[Sun]', '[Gift]', '[Hug]', '[Strong]',
'[Weak]', '[Shake]', '[Victory]', '[Admire]', '[Beckon]', '[Fist]', '[Pinky]',
'[Love]', '[No]', '[OK]', '[InLove]', '[Blowkiss]', '[Waddle]', '[Tremble]',
'[Aaagh!]', '[Twirl]', '[Kotow]', '[Lookback]', '[Jump]', '[Give-in]',
u'\U0001f604', u'\U0001f637', u'\U0001f639', u'\U0001f61d', u'\U0001f632', u'\U0001f633',
u'\U0001f631', u'\U0001f64d', u'\U0001f609', u'\U0001f60c', u'\U0001f612', u'\U0001f47f',
u'\U0001f47b', u'\U0001f49d', u'\U0001f64f', u'\U0001f4aa', u'\U0001f4b5', u'\U0001f382',
u'\U0001f388', u'\U0001f4e6',
]
BOT_ZHIHU_URL_LATEST = 'http://news-at.zhihu.com/api/4/news/latest'
BOT_ZHIHU_URL_DAILY = 'http://daily.zhihu.com/story/'
BOT_TULING_API_KEY = '55e7f30895a0a10535984bae5ad294d1'
BOT_TULING_API_URL = 'http://www.tuling123.com/openapi/api?key=%s&info=%s&userid=%s'
BOT_TULING_BOT_REPLY = u'麻烦说的清楚一点,我听不懂你在说什么'
+23
View File
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# coding: utf-8
#===================================================
from constant import Constant
from config import ConfigManager
#---------------------------------------------------
import logging
import logging.config
#===================================================
cm = ConfigManager()
logging.config.fileConfig(Constant.WECHAT_CONFIG_FILE)
# create logger
Log = logging.getLogger(Constant.LOGGING_LOGGER_NAME)
# 'application' code
# Log.debug('debug message')
# Log.info('info message')
# Log.warn('warn message')
# Log.error('error message')
# Log.critical('critical message')
@@ -0,0 +1,5 @@
qrcode
flask
requests
requests_toolbelt
pymysql
@@ -0,0 +1,72 @@
[wechat]
host = wx.qq.com
uuid =
redirect_uri =
uin =
sid =
skey =
pass_ticket =
device_id =
last_login =
[setting]
prefix = tmp_data/
database = WeChat.db
datadir = Data/infos/
logdir = Logs
mediapath = Data
uploaddir = Data/upload
qrcodedir = Data/qrcode
server_port = 8080
cookie = Cookie/WeChat.cookie
contact_user = Pickle/User.pkl
contact_member_list = Pickle/MemberList.pkl
contact_group_list = Pickle/GroupList.pkl
contact_group_memeber_list = Pickle/GroupMemeberList.pkl
contact_special_users_list = Pickle/SpecialUsersList.pkl
server_mode = False
server_log_file = server.log
log_mode = False
[mysql]
host = localhost
port = 3306
user = root
passwd = root
database = wechat
[loggers]
keys = root,WeChat
[handlers]
keys = consoleHandler,fileHandler
[formatters]
keys = simpleFormatter
[logger_root]
level = DEBUG
handlers = consoleHandler
[logger_WeChat]
level = DEBUG
handlers = fileHandler
qualname = WeChat
propagate = 0
[handler_consoleHandler]
class = StreamHandler
level = DEBUG
formatter = simpleFormatter
args = (sys.stdout,)
[handler_fileHandler]
class = FileHandler
level = DEBUG
formatter = simpleFormatter
args = ('tmp_data/wechat.log',)
[formatter_simpleFormatter]
format = %(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt =