def restore_items(self): """ 恢复已有数据 :return: bool """ result = False if path.exists(Config().CDN_ENABLED_AVAILABLE_ITEM_FILE): with open(Config().CDN_ENABLED_AVAILABLE_ITEM_FILE, encoding='utf-8') as f: result = f.read() try: result = json.loads(result) except json.JSONDecodeError as e: result = {} # if Config.is_cluster_enabled(): # 集群不用同步 cdn # result = self.get_data_from_cluster() if result: self.last_check_at = result.get('last_check_at', '') if self.last_check_at: self.last_check_at = str_to_time(self.last_check_at) self.available_items = result.get('items', []) self.unavailable_items = result.get('fail_items', []) CommonLog.add_quick_log( CommonLog.MESSAGE_CDN_RESTORE_SUCCESS.format( self.last_check_at)).flush() return True return False
def destroy(self): """ 关闭 CDN :return: """ CommonLog.add_quick_log(CommonLog.MESSAGE_CDN_CLOSED).flush() self.is_alive = False self.init_data()
def get_coordinate(img_str): # 储存最终坐标结果 result = '' orc_dir = '%spy12306/helpers/ocr/' % Config.PROJECT_DIR try: # 读取并预处理验证码 img = cv2.imdecode(np.fromstring(img_str, np.uint8), cv2.IMREAD_COLOR) text = get_text(img) imgs = np.array(list(_get_imgs(img))) imgs = preprocess_input(imgs) # 识别文字 model = models.load_model('%smodel.v2.0.h5' % orc_dir, compile=False) label = model.predict(text) label = label.argmax() fp = open('%stexts.txt' % orc_dir, encoding='utf-8') texts = [text.rstrip('\n') for text in fp] text = texts[label] # list放文字 titles = [text] position = [] # 获取下一个词 # 根据第一个词的长度来定位第二个词的位置 if len(text) == 1: offset = 27 elif len(text) == 2: offset = 47 else: offset = 60 text2 = get_text(img, offset=offset) if text2.mean() < 0.95: label = model.predict(text2) label = label.argmax() text2 = texts[label] titles.append(text2) # 加载图片分类器 model = models.load_model('%s12306.image.model.h5' % orc_dir, compile=False) labels = model.predict(imgs) labels = labels.argmax(axis=1) for pos, label in enumerate(labels): if texts[label] in titles: position.append(pos + 1) # 没有识别到结果 if len(position) == 0: return result result = position except: CommonLog.print_auto_code_fail( CommonLog.MESSAGE_GET_RESPONSE_FROM_FREE_AUTO_CODE) return result
def send_pushbear(self, skey, title, content): from lightpush import lightpush lgp = lightpush() lgp.set_group_push(key=skey) try: lgp.group_push(title, content) CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_PUSH_BEAR_SUCCESS).flush() except Exception as e: CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_PUSH_BEAR_SUCCESS.format(e)).flush()
def send_serverchan(self, skey, title, content): from lightpush import lightpush lgp = lightpush() lgp.set_single_push(key=skey) try: lgp.single_push(title, content) CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_SERVER_CHAN_SUCCESS).flush() except Exception as e: CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_SERVER_CHAN_FAIL.format(e)).flush()
def test_send_notifications(cls): if config.NOTIFICATION_BY_VOICE_CODE: # 语音通知 CommonLog.add_quick_log( CommonLog.MESSAGE_TEST_SEND_VOICE_CODE).flush() Notification.voice_code( config.NOTIFICATION_VOICE_CODE_PHONE, '张三', OrderLog. MESSAGE_ORDER_SUCCESS_NOTIFICATION_OF_VOICE_CODE_CONTENT. format('北京', '深圳'))
def get_img_position_by_ruokuai(self, img): ruokuai_account = Config().AUTO_CODE_ACCOUNT soft_id = '119671' soft_key = '6839cbaca1f942f58d2760baba5ed987' rc = RKClient(ruokuai_account.get('user'), ruokuai_account.get('pwd'), soft_id, soft_key) result = rc.rk_create(img, 6113) if "Result" in result: return self.get_image_position_by_offset(list(result['Result'])) CommonLog.print_auto_code_fail(result.get("Error", CommonLog.MESSAGE_RESPONSE_EMPTY_ERROR)) return None
def run_check(cls): """ 待优化 :return: """ if not cls.check_auto_code(): CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_AUTO_CODE_FAIL).flush(exit=True) if not cls.check_user_account_is_empty(): CommonLog.add_quick_log(CommonLog.MESSAGE_CHECK_EMPTY_USER_ACCOUNT).flush(exit=True) if Const.IS_TEST_NOTIFICATION: cls.test_send_notifications()
def app_available_check(): # return True # Debug 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
def start(self): if not Config.is_cdn_enabled(): return self.load_items() CommonLog.add_quick_log( CommonLog.MESSAGE_CDN_START_TO_CHECK.format(len( self.items))).flush() self.restore_items() for i in range(self.thread_num): # 多线程 create_thread_and_run(jobs=self, callback_name='check_available', wait=False)
def get_image_by_free_site(self, img): data = {'img': img} response = self.session.post(API_FREE_CODE_QCR_API, data=data) result = response.json() if result.get('msg') == 'success': pos = result.get('result') return self.get_image_position_by_offset(pos) CommonLog.print_auto_code_fail( CommonLog.MESSAGE_GET_RESPONSE_FROM_FREE_AUTO_CODE) return None
def get_img_position_by_ruokuai(self, img): ruokuai_account = Config().AUTO_CODE_ACCOUNT soft_id = '121426' soft_key = '1033017e34594d74b354da89f18717db' rc = RKClient(ruokuai_account.get('user'), ruokuai_account.get('pwd'), soft_id, soft_key) result = rc.rk_create(img, 6113) if "Result" in result: return self.get_image_position_by_offset(list(result['Result'])) CommonLog.print_auto_code_fail( result.get("Error", CommonLog.MESSAGE_RESPONSE_EMPTY_ERROR)) return None
def main(): if '--test' in sys.argv or '-t' in sys.argv: test() CommonLog.print_welcome().print_configs() App.run_check() User.run() Query.run() if not Const.IS_TEST: while True: sleep(10000) CommonLog.print_test_complete()
def get_img_position_by_ruokuai(self, img_path): ruokuai_account = config.AUTO_CODE_ACCOUNT soft_id = '119671' soft_key = '6839cbaca1f942f58d2760baba5ed987' rc = RKClient(ruokuai_account.get('user'), ruokuai_account.get('pwd'), soft_id, soft_key) im = open(img_path, 'rb').read() result = rc.rk_create(im, 6113) if "Result" in result: return self.get_image_position_by_offset(list(result['Result'])) CommonLog.print_auto_code_fail(result.get("Error", '-')) return None
def push_to_bark(self, content): bark_url = Config().BARK_PUSH_URL if not bark_url: return False response = self.session.request(url=bark_url + '/' + content, method='get') result = response.json() response_status = result.get('code') if response_status == 200: CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_BARK_SUCCESS).flush() else: response_error_message = result.get('message') CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_BARK_FAIL.format(response_error_message)).flush()
def test_send_notifications(cls): if Config().NOTIFICATION_BY_VOICE_CODE: # 语音通知 CommonLog.add_quick_log( CommonLog.MESSAGE_TEST_SEND_VOICE_CODE).flush() Notification.voice_code( Config().NOTIFICATION_VOICE_CODE_PHONE, '张三', OrderLog. MESSAGE_ORDER_SUCCESS_NOTIFICATION_OF_VOICE_CODE_CONTENT. format('北京', '深圳')) if Config().EMAIL_ENABLED: # 语音通知 CommonLog.add_quick_log(CommonLog.MESSAGE_TEST_SEND_EMAIL).flush() Notification.send_email(Config().EMAIL_RECEIVER, '测试发送邮件', 'By py12306')
def check_did_finished(self): self.is_ready = True if not self.is_finished: self.is_finished = True if self.is_recheck: self.is_recheck = False self.available_items = self.recheck_available_items self.unavailable_items = self.recheck_unavailable_items self.recheck_available_items = [] self.recheck_unavailable_items = [] CommonLog.add_quick_log( CommonLog.MESSAGE_CDN_CHECKED_SUCCESS.format( len(self.available_items))).flush() self.save_available_items()
def app_available_check(): if Config().IS_DEBUG: return True now = time_now() if now.weekday() == 1 and (now.hour > 23 and now.minute > 30 or now.hour < 5): CommonLog.add_quick_log(CommonLog.MESSAGE_12306_IS_CLOSED.format(time_now())).flush() open_time = datetime.datetime(now.year, now.month, now.day, 5) if open_time < now: open_time += datetime.timedelta(1) sleep((open_time - now).seconds) elif 1 < now.hour < 5: CommonLog.add_quick_log(CommonLog.MESSAGE_12306_IS_CLOSED.format(time_now())).flush() open_time = datetime.datetime(now.year, now.month, now.day, 5) sleep((open_time - now).seconds) return True
def send_to_telegram_bot(self, content): bot_api_url = Config().TELEGRAM_BOT_API_URL if not bot_api_url: return False data = { 'text': content } response = self.session.request(url=bot_api_url, method='POST', data=data) result = response.json().get('result') response_status = result.get('statusCode') if response_status == 200: CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_TELEGRAM_SUCCESS).flush() else: response_error_message = result.get('description') CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_TELEGRAM_FAIL.format(response_error_message)).flush()
def get_image_by_free_site(self, img): data = { 'img': img } if Config().AUTO_CODE_PLATFORM == 'free': response = self.session.post(API_FREE_CODE_QCR_API, data=data, timeout=30) else: response = self.session.post(Config().API_USER_CODE_QCR_API, data=data, timeout=30) result = response.json() if result.get('msg') == 'success': pos = result.get('result') return self.get_image_position_by_offset(pos) CommonLog.print_auto_code_fail(CommonLog.MESSAGE_GET_RESPONSE_FROM_FREE_AUTO_CODE) return None
def send_email_by_smtp(self, to, title, content): import smtplib from email.message import EmailMessage to = to if isinstance(to, list) else [to] message = EmailMessage() message['Subject'] = title message['From'] = Config().EMAIL_SENDER message['To'] = to message.set_content(content) try: server = smtplib.SMTP(Config().EMAIL_SERVER_HOST) server.login(Config().EMAIL_SERVER_USER, Config().EMAIL_SERVER_PASSWORD) server.send_message(message) server.quit() CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_EMAIL_SUCCESS).flush() except Exception as e: CommonLog.add_quick_log(CommonLog.MESSAGE_SEND_EMAIL_FAIL.format(e)).flush()
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 watch_cdn(self): """ 监控 cdn 状态,自动重新检测 :return: """ while True: if self.is_alive and not self.is_recheck and self.is_need_to_recheck( ): # 重新检测 self.is_recheck = True self.is_finished = False CommonLog.add_quick_log( CommonLog.MESSAGE_CDN_START_TO_RECHECK.format( len(self.items), time_now())).flush() for i in range(self.thread_num): # 多线程 create_thread_and_run(jobs=self, callback_name='check_available', wait=False) stay_second(self.retry_num)
def send_email_by_smtp_with_qrcode(self, to, title, qrcode_path): import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.image import MIMEImage to = to if isinstance(to, list) else [to] message = MIMEMultipart() message['Subject'] = title message['From'] = Config().EMAIL_SENDER message['To'] = ", ".join(to) htmlFile = """ <html> <head></head> <body> <p> 这是你的二维码 </p> <p> <br /><img src="cid:0", width=200, height=200 ></p> </body> </html> """ htmlApart = MIMEText(htmlFile, 'html') imageFile = qrcode_path imageApart = MIMEImage( open(imageFile, 'rb').read(), imageFile.split('.')[-1]) imageApart.add_header('Content-ID', '<0>') message.attach(imageApart) message.attach(htmlApart) try: server = smtplib.SMTP(Config().EMAIL_SERVER_HOST) server.ehlo() server.starttls() server.login(Config().EMAIL_SERVER_USER, Config().EMAIL_SERVER_PASSWORD) server.send_message(message) server.quit() CommonLog.add_quick_log( CommonLog.MESSAGE_SEND_EMAIL_WITH_QRCODE_SUCCESS).flush() self.push_bark(CommonLog.MESSAGE_SEND_EMAIL_WITH_QRCODE_SUCCESS) except Exception as e: CommonLog.add_quick_log( CommonLog.MESSAGE_SEND_EMAIL_FAIL.format(e)).flush()
def get_image_by_free_site(self, img): data = {'base64': img} response = self.session.post(API_FREE_CODE_QCR_API, json=data) result = response.json() if result.get('success') and result.get('check'): check_data = { 'check': result.get('check'), 'img_buf': img, 'logon': 1, 'type': 'D' } check_response = self.session.post(API_FREE_CODE_QCR_API_CHECK, json=check_data) check_result = check_response.json() if check_result.get('res'): position = check_result.get('res') return position.replace('(', '').replace(')', '').split(',') CommonLog.print_auto_code_fail(result.get("Error", '-')) return None
def main(): load_argvs() CommonLog.print_welcome() # 初始化配置 App.run() CommonLog.print_configs() # 加载站点信息 App.did_start() #print('App.did_start() done.') # 检查运行环境的相关目录以及验证码校验的api用户名密码设置是否正确 App.run_check() #print('App.run_check() done') # 初始化查询任务,获取余票查询url Query.check_before_run() #print('Query.check_before_run() done') ####### 运行任务 Web.run() Cdn.run() #12306账号登录 User.run() Query.run() if not Const.IS_TEST: while True: sleep(10000) else: if Config().is_cluster_enabled(): stay_second(5) # 等待接受完通知 CommonLog.print_test_complete()
def send_voice_code_of_dingxin(self, phone, name='', info={}): """ 发送语音验证码 ( 鼎信 ) 购买地址 https://market.aliyun.com/products/56928004/cmapi026600.html?spm=5176.2020520132.101.2.51547218rkAXxy :return: """ appcode = Config().NOTIFICATION_API_APP_CODE if not appcode: CommonLog.add_quick_log(CommonLog.MESSAGE_EMPTY_APP_CODE).flush() return False data = { 'tpl_id': 'TP1901174', 'phone': phone, 'param': 'name:{name},job_name:{left_station}到{arrive_station}{set_type},orderno:{orderno}'.format( name=name, left_station=info.get('left_station'), arrive_station=info.get('arrive_station'), set_type=info.get('set_type'), orderno=info.get('orderno')) } response = self.session.request(url=API_NOTIFICATION_BY_VOICE_CODE_DINGXIN, method='POST', data=data, headers={'Authorization': 'APPCODE {}'.format(appcode)}) result = response.json() response_message = result.get('return_code') if response.status_code in [400, 401, 403]: return CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_FORBID).flush() if response.status_code == 200 and result.get('return_code') == '00000': CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_SEND_SUCCESS.format(response_message)).flush() return True else: return CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_SEND_FAIL.format(response_message)).flush()
def send_voice_code_of_yiyuan(self, phone, name='', content=''): """ 发送语音验证码 购买地址 https://market.aliyun.com/products/57126001/cmapi019902.html?spm=5176.2020520132.101.5.37857218O6iJ3n :return: """ appcode = Config().NOTIFICATION_API_APP_CODE if not appcode: CommonLog.add_quick_log(CommonLog.MESSAGE_EMPTY_APP_CODE).flush() return False body = { 'userName': name, 'mailNo': content } params = { 'content': body, 'mobile': phone, 'sex': 2, 'tNum': 'T170701001056' } response = self.session.request(url=API_NOTIFICATION_BY_VOICE_CODE + urllib.parse.urlencode(params), method='GET', headers={ 'Authorization': 'APPCODE {}'.format(appcode) }) result = response.json() response_message = result.get('showapi_res_body.remark') if response.status_code in [400, 401, 403]: return CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_FORBID).flush() if response.status_code == 200 and result.get('showapi_res_body.flag'): CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_SEND_SUCCESS.format(response_message)).flush() return True else: return CommonLog.add_quick_log(CommonLog.MESSAGE_VOICE_API_SEND_FAIL.format(response_message)).flush()
def main(): load_argvs() CommonLog.print_welcome() App.run() CommonLog.print_configs() App.did_start() App.run_check() User.run() Query.run() if not Const.IS_TEST: while True: sleep(10000) else: if Config().is_cluster_enabled(): stay_second(5) # 等待接受完通知 CommonLog.print_test_complete()
def test_send_notifications(cls): if Config().NOTIFICATION_BY_VOICE_CODE: # 语音通知 CommonLog.add_quick_log( CommonLog.MESSAGE_TEST_SEND_VOICE_CODE).flush() Notification.voice_code( Config().NOTIFICATION_VOICE_CODE_PHONE, '张三', OrderLog. MESSAGE_ORDER_SUCCESS_NOTIFICATION_OF_VOICE_CODE_CONTENT. format('北京', '深圳')) 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('测试发送信息')