Files
py12306/old_py12306/config.py
2019-05-14 13:21:25 +08:00

236 lines
6.9 KiB
Python

# -*- coding: utf-8 -*-
import json
import re
from os import path
# 12306 账号
from py12306.helpers.func import *
@singleton
class Config:
IS_DEBUG = False
USER_ACCOUNTS = []
# 查询任务
QUERY_JOBS = []
# 查询间隔
QUERY_INTERVAL = 1
# 用户心跳检测间隔
USER_HEARTBEAT_INTERVAL = 120
# 多线程查询
QUERY_JOB_THREAD_ENABLED = 0
# 打码平台账号
AUTO_CODE_PLATFORM = ''
AUTO_CODE_ACCOUNT = {'user': '', 'pwd': ''}
# 输出日志到文件
OUT_PUT_LOG_TO_FILE_ENABLED = 0
OUT_PUT_LOG_TO_FILE_PATH = 'runtime/12306.log'
SEAT_TYPES = {'特等座': 25, '商务座': 32, '一等座': 31, '二等座': 30, '软卧': 23, '硬卧': 28, '硬座': 29, '无座': 26, }
ORDER_SEAT_TYPES = {'特等座': 'P', '商务座': 9, '一等座': 'M', '二等座': 'O', '软卧': 4, '硬卧': 3, '硬座': 1, '无座': 1}
PROJECT_DIR = path.dirname(path.dirname(path.abspath(__file__))) + '/'
# Query
RUNTIME_DIR = PROJECT_DIR + 'runtime/'
QUERY_DATA_DIR = RUNTIME_DIR + 'query/'
USER_DATA_DIR = RUNTIME_DIR + 'user/'
USER_PASSENGERS_FILE = RUNTIME_DIR + 'user/%s_passengers.json'
STATION_FILE = PROJECT_DIR + 'data/stations.txt'
CONFIG_FILE = PROJECT_DIR + 'env.py'
# 语音验证码
NOTIFICATION_BY_VOICE_CODE = 0
NOTIFICATION_VOICE_CODE_TYPE = ''
NOTIFICATION_VOICE_CODE_PHONE = ''
NOTIFICATION_API_APP_CODE = ''
# 集群配置
CLUSTER_ENABLED = 0
NODE_SLAVE_CAN_BE_MASTER = 1
NODE_IS_MASTER = 1
NODE_NAME = ''
REDIS_HOST = ''
REDIS_PORT = '6379'
REDIS_PASSWORD = ''
# 钉钉配置
DINGTALK_ENABLED = 0
DINGTALK_WEBHOOK = ''
# Telegram推送配置
TELEGRAM_ENABLED = 0
TELEGRAM_BOT_API_URL = ''
# Bark 推送配置
BARK_ENABLED = 0
BARK_PUSH_URL = ''
# ServerChan和PushBear配置
SERVERCHAN_ENABLED = 0
SERVERCHAN_KEY = '8474-ca071ADSFADSF'
PUSHBEAR_ENABLED = 0
PUSHBEAR_KEY = 'SCUdafadsfasfdafdf45234234234'
# 邮箱配置
EMAIL_ENABLED = 0
EMAIL_SENDER = ''
EMAIL_RECEIVER = ''
EMAIL_SERVER_HOST = ''
EMAIL_SERVER_USER = ''
EMAIL_SERVER_PASSWORD = ''
WEB_ENABLE = 0
WEB_USER = {}
WEB_PORT = 8080
WEB_ENTER_HTML_PATH = PROJECT_DIR + 'py12306/web/static/index.html'
# CDN
CDN_ENABLED = 0
CDN_CHECK_TIME_OUT = 2
CDN_ITEM_FILE = PROJECT_DIR + 'data/cdn.txt'
CDN_ENABLED_AVAILABLE_ITEM_FILE = QUERY_DATA_DIR + 'available.json'
# Default time out
TIME_OUT_OF_REQUEST = 5
envs = []
retry_time = 5
last_modify_time = 0
disallow_update_configs = [
'CLUSTER_ENABLED',
'NODE_IS_MASTER',
'NODE_NAME',
'REDIS_HOST',
'REDIS_PORT',
'REDIS_PASSWORD',
]
def __init__(self):
self.init_envs()
self.last_modify_time = get_file_modify_time(self.CONFIG_FILE)
if Config().is_slave():
self.refresh_configs(True)
else:
create_thread_and_run(self, 'watch_file_change', False)
@classmethod
def run(cls):
self = cls()
self.start()
# @classmethod
# def keep_work(cls):
# self = cls()
def start(self):
self.save_to_remote()
create_thread_and_run(self, 'refresh_configs', wait=Const.IS_TEST)
def refresh_configs(self, once=False):
if not self.is_cluster_enabled(): return
while True:
remote_configs = self.get_remote_config()
self.update_configs_from_remote(remote_configs, once)
if once or Const.IS_TEST: return
stay_second(self.retry_time)
def get_remote_config(self):
if not self.is_cluster_enabled(): return
from py12306.cluster.cluster import Cluster
return Cluster().session.get_pickle(Cluster().KEY_CONFIGS, {})
def save_to_remote(self):
if not self.is_master(): return
from py12306.cluster.cluster import Cluster
Cluster().session.set_pickle(Cluster().KEY_CONFIGS, self.envs)
def init_envs(self):
self.envs = EnvLoader.load_with_file(self.CONFIG_FILE)
self.update_configs(self.envs)
def update_configs(self, envs):
for key, value in envs:
setattr(self, key, value)
def watch_file_change(self):
"""
监听配置文件修改
:return:
"""
if Config().is_slave(): return
from py12306.log.common_log import CommonLog
while True:
value = get_file_modify_time(self.CONFIG_FILE)
if value > self.last_modify_time:
self.last_modify_time = value
CommonLog.add_quick_log(CommonLog.MESSAGE_CONFIG_FILE_DID_CHANGED).flush()
envs = EnvLoader.load_with_file(self.CONFIG_FILE)
self.update_configs_from_remote(envs)
if Config().is_master(): # 保存配置
self.save_to_remote()
stay_second(self.retry_time)
def update_configs_from_remote(self, envs, first=False):
if envs == self.envs: return
from py12306.query.query import Query
from py12306.user.user import User
from py12306.helpers.cdn import Cdn
self.envs = envs
for key, value in envs:
if key in self.disallow_update_configs: continue
if value != -1:
old = getattr(self, key)
setattr(self, key, value)
if not first and old != value:
if key == 'USER_ACCOUNTS':
User().update_user_accounts(auto=True, old=old)
elif key == 'QUERY_JOBS':
Query().update_query_jobs(auto=True) # 任务修改
elif key == 'QUERY_INTERVAL':
Query().update_query_interval(auto=True)
elif key == 'CDN_ENABLED':
Cdn().update_cdn_status(auto=True)
@staticmethod
def is_master(): # 是不是 主
from py12306.cluster.cluster import Cluster
return Config().CLUSTER_ENABLED and (Config().NODE_IS_MASTER or Cluster().is_master)
@staticmethod
def is_slave(): # 是不是 从
return Config().CLUSTER_ENABLED and not Config.is_master()
@staticmethod
def is_cluster_enabled():
return Config().CLUSTER_ENABLED
@staticmethod
def is_cdn_enabled():
return Config().CDN_ENABLED
class EnvLoader:
envs = []
def __init__(self):
self.envs = []
@classmethod
def load_with_file(cls, file):
self = cls()
if path.exists(file):
env_content = open(file, encoding='utf8').read()
content = re.sub(r'^([A-Z]+)_', r'self.\1_', env_content, flags=re.M)
exec(content)
return self.envs
def __setattr__(self, key, value):
super().__setattr__(key, value)
if re.search(r'^[A-Z]+_', key):
self.envs.append(([key, value]))