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

175 lines
5.2 KiB
Python

from py12306.config import Config
from py12306.cluster.cluster import Cluster
from py12306.app import app_available_check
from py12306.helpers.func import *
from py12306.helpers.request import Request
from py12306.log.query_log import QueryLog
from py12306.query.job import Job
from py12306.helpers.api import API_QUERY_INIT_PAGE
@singleton
class Query:
"""
余票查询
"""
jobs = []
query_jobs = []
session = {}
# 查询间隔
interval = {}
cluster = None
is_in_thread = False
retry_time = 3
is_ready = False
api_type = None # Query api url, Current know value leftTicket/queryX | leftTicket/queryZ
def __init__(self):
self.session = Request()
self.cluster = Cluster()
self.update_query_interval()
self.update_query_jobs()
self.get_query_api_type()
def update_query_interval(self, auto=False):
self.interval = init_interval_by_number(Config().QUERY_INTERVAL)
if auto:
jobs_do(self.jobs, 'update_interval')
def update_query_jobs(self, auto=False):
self.query_jobs = Config().QUERY_JOBS
if auto:
QueryLog.add_quick_log(QueryLog.MESSAGE_JOBS_DID_CHANGED).flush()
self.refresh_jobs()
if not Config().is_slave():
jobs_do(self.jobs, 'check_passengers')
@classmethod
def run(cls):
self = cls()
app_available_check()
self.start()
pass
@classmethod
def check_before_run(cls):
self = cls()
self.init_jobs()
self.is_ready = True
def start(self):
# return # DEBUG
QueryLog.init_data()
stay_second(3)
# 多线程
while True:
if Config().QUERY_JOB_THREAD_ENABLED: # 多线程
if not self.is_in_thread:
self.is_in_thread = True
create_thread_and_run(jobs=self.jobs, callback_name='run', wait=Const.IS_TEST)
if Const.IS_TEST: return
stay_second(self.retry_time)
else:
if not self.jobs: break
self.is_in_thread = False
jobs_do(self.jobs, 'run')
if Const.IS_TEST: return
# while True:
# app_available_check()
# if Config().QUERY_JOB_THREAD_ENABLED: # 多线程
# create_thread_and_run(jobs=self.jobs, callback_name='run')
# else:
# for job in self.jobs: job.run()
# if Const.IS_TEST: return
# self.refresh_jobs() # 刷新任务
def refresh_jobs(self):
"""
更新任务
:return:
"""
allow_jobs = []
for job in self.query_jobs:
id = md5(job)
job_ins = objects_find_object_by_key_value(self.jobs, 'id', id) # [1 ,2]
if not job_ins:
job_ins = self.init_job(job)
if Config().QUERY_JOB_THREAD_ENABLED: # 多线程重新添加
create_thread_and_run(jobs=job_ins, callback_name='run', wait=Const.IS_TEST)
allow_jobs.append(job_ins)
for job in self.jobs: # 退出已删除 Job
if job not in allow_jobs: job.destroy()
QueryLog.print_init_jobs(jobs=self.jobs)
def init_jobs(self):
for job in self.query_jobs:
self.init_job(job)
QueryLog.print_init_jobs(jobs=self.jobs)
def init_job(self, job):
job = Job(info=job, query=self)
self.jobs.append(job)
return job
@classmethod
def wait_for_ready(cls):
self = cls()
if self.is_ready: return self
stay_second(self.retry_time)
return self.wait_for_ready()
@classmethod
def job_by_name(cls, name) -> Job:
self = cls()
for job in self.jobs:
if job.job_name == name: return job
return None
@classmethod
def job_by_name(cls, name) -> Job:
self = cls()
return objects_find_object_by_key_value(self.jobs, 'job_name', name)
@classmethod
def job_by_account_key(cls, account_key) -> Job:
self = cls()
return objects_find_object_by_key_value(self.jobs, 'account_key', account_key)
@classmethod
def get_query_api_type(cls):
import re
self = cls()
if self.api_type:
return self.api_type
response = self.session.get(API_QUERY_INIT_PAGE)
if response.status_code == 200:
res = re.search(r'var CLeftTicketUrl = \'(.*)\';', response.text)
try:
self.api_type = res.group(1)
except IndexError:
pass
return cls.get_query_api_type()
# def get_jobs_from_cluster(self):
# jobs = self.cluster.session.get_dict(Cluster.KEY_JOBS)
# return jobs
#
# def update_jobs_of_cluster(self):
# if config.CLUSTER_ENABLED and config.NODE_IS_MASTER:
# return self.cluster.session.set_dict(Cluster.KEY_JOBS, self.query_jobs)
#
# def refresh_jobs(self):
# if not config.CLUSTER_ENABLED: return
# jobs = self.get_jobs_from_cluster()
# if jobs != self.query_jobs:
# self.jobs = []
# self.query_jobs = jobs
# QueryLog.add_quick_log(QueryLog.MESSAGE_JOBS_DID_CHANGED).flush()
# self.init_jobs()