add task logger
This commit is contained in:
16
config.toml
16
config.toml
@@ -0,0 +1,16 @@
|
||||
[app]
|
||||
env = "dev"
|
||||
|
||||
[web]
|
||||
ip = "0.0.0.0"
|
||||
port = 8081
|
||||
|
||||
[users]
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
|
||||
[redis]
|
||||
host = "127.0.0.1"
|
||||
port = 6379
|
||||
db = 1
|
||||
password = "local_redis_dd"
|
||||
|
||||
0
py12306/__init__.py
Normal file
0
py12306/__init__.py
Normal file
0
py12306/app/__init__.py
Normal file
0
py12306/app/__init__.py
Normal file
59
py12306/app/app.py
Normal file
59
py12306/app/app.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
|
||||
class Config:
|
||||
class AppEnvType:
|
||||
DEV = 'dev'
|
||||
PRODUCTION = 'production'
|
||||
|
||||
APP_NAME = 'py12306'
|
||||
APP_ENV = AppEnvType.PRODUCTION
|
||||
LOADED = False
|
||||
TEST_MODE = False
|
||||
|
||||
PROJECT_DIR = os.path.abspath(__file__ + '/../../../') + '/'
|
||||
CONFIG_FILE = PROJECT_DIR + 'config.toml'
|
||||
|
||||
# Config
|
||||
REDIS = {
|
||||
'host': '127.0.0.1',
|
||||
'port': 6379,
|
||||
'db': 0,
|
||||
'password': None,
|
||||
'decode_responses': True
|
||||
}
|
||||
|
||||
# Redis keys
|
||||
REDIS_PREFIX_KEY_TASKS = 'tasks:'
|
||||
|
||||
# REDIS_KEY_USER_TASKS = 'user_jobs'
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
"""
|
||||
Load configs from toml file
|
||||
:return:
|
||||
"""
|
||||
import toml
|
||||
configs = toml.load(cls.CONFIG_FILE)
|
||||
|
||||
redis = configs.get('redis')
|
||||
if redis:
|
||||
cls.REDIS.update(redis)
|
||||
|
||||
app = configs.get('app')
|
||||
if app:
|
||||
cls.APP_ENV = app.get('env', cls.APP_ENV)
|
||||
|
||||
|
||||
if not Config.LOADED:
|
||||
Config.load()
|
||||
|
||||
# Logger
|
||||
Logger = logging.getLogger(Config.APP_NAME)
|
||||
Logger.setLevel('DEBUG' if Config.APP_ENV == Config.AppEnvType.DEV else 'ERROR')
|
||||
handler = logging.StreamHandler()
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
Logger.addHandler(handler)
|
||||
34
py12306/app/task.py
Normal file
34
py12306/app/task.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from py12306.app.app import Logger, Config
|
||||
from py12306.lib.func import new_thread_with_jobs
|
||||
from py12306.lib.redis_lib import Redis
|
||||
|
||||
|
||||
def get_routes() -> dict:
|
||||
from py12306.app.user import User
|
||||
return {
|
||||
'user': User.task_user,
|
||||
'query': User.task_user,
|
||||
}
|
||||
|
||||
|
||||
class Task:
|
||||
routes: dict = None
|
||||
|
||||
@classmethod
|
||||
def listen(cls):
|
||||
routes = get_routes()
|
||||
keys = [Config.REDIS_PREFIX_KEY_TASKS + key for key, _ in routes.items()]
|
||||
while True:
|
||||
key, job = Redis.share().get_task_sync(keys)
|
||||
Logger.info('获得新任务 %s' % key)
|
||||
if Config.TEST_MODE: # ignore when in test env
|
||||
return job
|
||||
self = cls()
|
||||
self.routes = routes
|
||||
self.deal_job(key, job)
|
||||
|
||||
def deal_job(self, key: str, task: dict):
|
||||
handler = self.routes.get(key)
|
||||
if not handler:
|
||||
return
|
||||
new_thread_with_jobs(handler, wait=True, kwargs={'task': task})
|
||||
12
py12306/app/user.py
Normal file
12
py12306/app/user.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from py12306.lib.helper import ShareInstance
|
||||
|
||||
|
||||
class User(ShareInstance):
|
||||
|
||||
@classmethod
|
||||
def task_user(cls, task: dict):
|
||||
print(111)
|
||||
a = 1
|
||||
pass
|
||||
|
||||
pass
|
||||
0
py12306/lib/__init__.py
Normal file
0
py12306/lib/__init__.py
Normal file
24
py12306/lib/func.py
Normal file
24
py12306/lib/func.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import threading
|
||||
|
||||
|
||||
def new_thread_with_jobs(jobs, wait=True, daemon=True, args=(), kwargs={}):
|
||||
"""
|
||||
Run each job with a new thread
|
||||
:param jobs:
|
||||
:param wait:
|
||||
:param daemon:
|
||||
:param args:
|
||||
:param kwargs:
|
||||
:return:
|
||||
"""
|
||||
threads = []
|
||||
if not isinstance(jobs, list):
|
||||
jobs = [jobs]
|
||||
for job in jobs:
|
||||
thread = threading.Thread(target=job, args=args, kwargs=kwargs)
|
||||
thread.setDaemon(daemon)
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
if wait:
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
10
py12306/lib/helper.py
Normal file
10
py12306/lib/helper.py
Normal file
@@ -0,0 +1,10 @@
|
||||
class ShareInstance():
|
||||
__session = None
|
||||
|
||||
@classmethod
|
||||
def share(cls):
|
||||
if not cls.__session:
|
||||
cls.__session = cls()
|
||||
return cls.__session
|
||||
|
||||
|
||||
27
py12306/lib/redis_lib.py
Normal file
27
py12306/lib/redis_lib.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from redis import Redis as PyRedis
|
||||
|
||||
from py12306.app.app import Config
|
||||
from py12306.lib.helper import ShareInstance
|
||||
|
||||
import json
|
||||
|
||||
|
||||
class Redis(PyRedis, ShareInstance):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if not kwargs:
|
||||
kwargs = Config.REDIS
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def push_task(self, key: str, tasks: dict):
|
||||
return self.rpush(key, json.dumps(tasks))
|
||||
|
||||
def get_task_sync(self, keys: list) -> tuple:
|
||||
tasks = self.brpop(keys)
|
||||
return tasks[0][len(Config.REDIS_PREFIX_KEY_TASKS):], json.loads(tasks[1])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
res = Redis.share().keys('*')
|
||||
print(res)
|
||||
pass
|
||||
@@ -1,3 +1,4 @@
|
||||
toml
|
||||
-i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
|
||||
appdirs==1.4.3
|
||||
beautifulsoup4==4.7.0
|
||||
|
||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
15
tests/helper.py
Normal file
15
tests/helper.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from py12306.app.app import Config
|
||||
from py12306.lib.redis_lib import Redis
|
||||
|
||||
|
||||
class BaseTest(TestCase):
|
||||
redis: Redis = None
|
||||
config: Config = None
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
Config.TEST_MODE = True
|
||||
self.config = Config
|
||||
self.redis = Redis.share()
|
||||
9
tests/test_redis.py
Normal file
9
tests/test_redis.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from py12306.lib.redis_lib import Redis
|
||||
from tests.helper import BaseTest
|
||||
|
||||
|
||||
class TestRedis(BaseTest):
|
||||
|
||||
def test_connection(self):
|
||||
res = Redis.share().info()
|
||||
self.assertIsInstance(res, dict)
|
||||
20
tests/test_task.py
Normal file
20
tests/test_task.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from tests.helper import BaseTest
|
||||
from py12306.app.task import Task
|
||||
|
||||
|
||||
class TestTask(BaseTest):
|
||||
def test_push_task(self):
|
||||
tasks = {
|
||||
'query': {
|
||||
'name': 'admin',
|
||||
},
|
||||
'user': {
|
||||
'name': 'admin',
|
||||
'password': 'password'
|
||||
}
|
||||
}
|
||||
for key, task in tasks.items():
|
||||
self.redis.push_task(self.config.REDIS_PREFIX_KEY_TASKS + key, task)
|
||||
|
||||
res = Task.listen()
|
||||
self.assertIsInstance(res, dict)
|
||||
5
tests/test_user.py
Normal file
5
tests/test_user.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from tests.helper import BaseTest
|
||||
|
||||
|
||||
class TestUser(BaseTest):
|
||||
pass
|
||||
Reference in New Issue
Block a user