i just come out and take a bubble, haha \O^O/
This commit is contained in:
@@ -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
|
||||
@@ -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]',' [Bah!L]','[Bah!R]',
|
||||
'[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'麻烦说的清楚一点,我听不懂你在说什么'
|
||||
@@ -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 =
|
||||
|
||||
Reference in New Issue
Block a user