170 lines
6.0 KiB
Python
170 lines
6.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
import signal
|
|
import sys
|
|
|
|
from py12306.helpers.func import *
|
|
from py12306.config import Config
|
|
from py12306.helpers.notification import Notification
|
|
from py12306.log.common_log import CommonLog
|
|
from py12306.log.order_log import OrderLog
|
|
|
|
|
|
def app_available_check():
|
|
# return True # Debug
|
|
if Config().IS_DEBUG:
|
|
return True
|
|
now = time_now()
|
|
if now.hour >= 23 or now.hour < 6:
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_12306_IS_CLOSED.format(time_now())).flush()
|
|
open_time = datetime.datetime(now.year, now.month, now.day, 6)
|
|
if open_time < now:
|
|
open_time += datetime.timedelta(1)
|
|
sleep((open_time - now).seconds)
|
|
return True
|
|
|
|
|
|
@singleton
|
|
class App:
|
|
"""
|
|
程序主类
|
|
TODO 代码需要优化
|
|
"""
|
|
|
|
@classmethod
|
|
def run(cls):
|
|
self = cls()
|
|
self.register_sign()
|
|
self.start()
|
|
|
|
def start(self):
|
|
Config().run()
|
|
self.init_class()
|
|
|
|
@classmethod
|
|
def did_start(cls):
|
|
self = cls()
|
|
from py12306.helpers.station import Station
|
|
Station() # 防止多线程时初始化出现问题
|
|
# if Config.is_cluster_enabled():
|
|
# from py12306.cluster.cluster import Cluster
|
|
# Cluster().run()
|
|
|
|
def init_class(self):
|
|
from py12306.cluster.cluster import Cluster
|
|
if Config.is_cluster_enabled():
|
|
Cluster().run()
|
|
|
|
def register_sign(self):
|
|
is_windows = os.name == 'nt'
|
|
# if is_windows:
|
|
signs = [signal.SIGINT, signal.SIGTERM]
|
|
# else:
|
|
# signs = [signal.SIGINT, signal.SIGHUP, signal.SIGTERM] # SIGHUP 会导致终端退出,程序也退出,暂时去掉
|
|
for sign in signs:
|
|
signal.signal(sign, self.handler_exit)
|
|
|
|
pass
|
|
|
|
def handler_exit(self, *args, **kwargs):
|
|
"""
|
|
程序退出
|
|
:param args:
|
|
:param kwargs:
|
|
:return:
|
|
"""
|
|
if Config.is_cluster_enabled():
|
|
from py12306.cluster.cluster import Cluster
|
|
Cluster().left_cluster()
|
|
|
|
sys.exit()
|
|
|
|
@classmethod
|
|
def check_auto_code(cls):
|
|
if Config().AUTO_CODE_PLATFORM == 'free': return True
|
|
if not Config().AUTO_CODE_ACCOUNT.get('user') or not Config().AUTO_CODE_ACCOUNT.get('pwd'):
|
|
return False
|
|
return True
|
|
|
|
@classmethod
|
|
def check_user_account_is_empty(cls):
|
|
if Config().USER_ACCOUNTS:
|
|
for account in Config().USER_ACCOUNTS:
|
|
if account:
|
|
return False
|
|
return True
|
|
|
|
@staticmethod
|
|
def check_data_dir_exists():
|
|
os.makedirs(Config().QUERY_DATA_DIR, exist_ok=True)
|
|
os.makedirs(Config().USER_DATA_DIR, exist_ok=True)
|
|
touch_file(Config().OUT_PUT_LOG_TO_FILE_PATH)
|
|
|
|
@classmethod
|
|
def test_send_notifications(cls):
|
|
if Config().NOTIFICATION_BY_VOICE_CODE: # 语音通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_VOICE_CODE).flush()
|
|
if Config().NOTIFICATION_VOICE_CODE_TYPE == 'dingxin':
|
|
voice_content = {'left_station': '广州', 'arrive_station': '深圳', 'set_type': '硬座', 'orderno': 'E123542'}
|
|
else:
|
|
voice_content = OrderLog.MESSAGE_ORDER_SUCCESS_NOTIFICATION_OF_VOICE_CODE_CONTENT.format('北京',
|
|
'深圳')
|
|
Notification.voice_code(Config().NOTIFICATION_VOICE_CODE_PHONE, '张三', voice_content)
|
|
if Config().EMAIL_ENABLED: # 邮件通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_EMAIL).flush()
|
|
Notification.send_email(Config().EMAIL_RECEIVER, '测试发送邮件', 'By py12306')
|
|
|
|
if Config().DINGTALK_ENABLED: # 钉钉通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_DINGTALK).flush()
|
|
Notification.dingtalk_webhook('测试发送信息')
|
|
|
|
if Config().TELEGRAM_ENABLED: # Telegram通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_TELEGRAM).flush()
|
|
Notification.send_to_telegram('测试发送信息')
|
|
|
|
if Config().SERVERCHAN_ENABLED: # ServerChan通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_SERVER_CHAN).flush()
|
|
Notification.server_chan(Config().SERVERCHAN_KEY, '测试发送消息', 'By py12306')
|
|
|
|
if Config().PUSHBEAR_ENABLED: # PushBear通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_PUSH_BEAR).flush()
|
|
Notification.push_bear(Config().PUSHBEAR_KEY, '测试发送消息', 'By py12306')
|
|
|
|
if Config().BARK_ENABLED: # Bark通知
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_PUSH_BARK).flush()
|
|
Notification.push_bark('测试发送信息')
|
|
|
|
@classmethod
|
|
def run_check(cls):
|
|
"""
|
|
待优化
|
|
:return:
|
|
"""
|
|
cls.check_data_dir_exists()
|
|
if not cls.check_user_account_is_empty():
|
|
# CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_EMPTY_USER_ACCOUNT).flush(exit=True, publish=False) # 不填写用户则不自动下单
|
|
if not cls.check_auto_code():
|
|
CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_AUTO_CODE_FAIL).flush(exit=True, publish=False)
|
|
if Const.IS_TEST_NOTIFICATION: cls.test_send_notifications()
|
|
|
|
|
|
# Expand
|
|
class Dict(dict):
|
|
def get(self, key, default=None, sep='.'):
|
|
keys = key.split(sep)
|
|
for i, key in enumerate(keys):
|
|
try:
|
|
value = self[key]
|
|
if len(keys[i + 1:]) and isinstance(value, Dict):
|
|
return value.get(sep.join(keys[i + 1:]), default=default, sep=sep)
|
|
return value
|
|
except:
|
|
return self.dict_to_dict(default)
|
|
|
|
def __getitem__(self, k):
|
|
return self.dict_to_dict(super().__getitem__(k))
|
|
|
|
@staticmethod
|
|
def dict_to_dict(value):
|
|
return Dict(value) if isinstance(value, dict) else value
|