Skip to content

Commit

Permalink
增加 Web 管理页面
Browse files Browse the repository at this point in the history
  • Loading branch information
pjialin committed Jan 12, 2019
1 parent b1e826b commit a0bdc4c
Show file tree
Hide file tree
Showing 39 changed files with 4,785 additions and 23 deletions.
8 changes: 8 additions & 0 deletions env.docker.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ EMAIL_SERVER_HOST = 'localhost' # 邮件服务 host
EMAIL_SERVER_USER = ''
EMAIL_SERVER_PASSWORD = ''

# Web 管理
WEB_ENABLE = 1 # 是否打开 Web 管理
WEB_USER = { # 登录信息
'username': 'admin',
'password': 'password'
}
WEB_PORT = 8008 # 监听端口

# 查询任务
QUERY_JOBS = [
{
Expand Down
17 changes: 12 additions & 5 deletions env.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,22 @@ REDIS_HOST = 'localhost' # Redis host
REDIS_PORT = '6379' # Redis post
REDIS_PASSWORD = '' # # Redis 密码 没有可以留空


# 邮箱配置
EMAIL_ENABLED = 0 # 是否开启邮件通知
EMAIL_SENDER = '[email protected]' # 邮件发送者
EMAIL_RECEIVER = '[email protected]' # 邮件接受者 # 可以多个 [[email protected], [email protected]]
EMAIL_SERVER_HOST = 'localhost' # 邮件服务 host
EMAIL_ENABLED = 0 # 是否开启邮件通知
EMAIL_SENDER = '[email protected]' # 邮件发送者
EMAIL_RECEIVER = '[email protected]' # 邮件接受者 # 可以多个 [[email protected], [email protected]]
EMAIL_SERVER_HOST = 'localhost' # 邮件服务 host
EMAIL_SERVER_USER = ''
EMAIL_SERVER_PASSWORD = ''

# Web 管理
WEB_ENABLE = 1 # 是否打开 Web 管理
WEB_USER = { # 登录信息
'username': 'admin',
'password': 'password'
}
WEB_PORT = 8008 # 监听端口

# 查询任务
QUERY_JOBS = [
{
Expand Down
4 changes: 3 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from py12306.log.common_log import CommonLog
from py12306.query.query import Query
from py12306.user.user import User
from py12306.web.web import Web


def main():
Expand All @@ -18,13 +19,14 @@ def main():
Query.check_before_fun()

####### 运行任务
Web.run()
User.run()
Query.run()
if not Const.IS_TEST:
while True:
sleep(10000)
else:
if Config().is_cluster_enabled(): stay_second(5) # 等待接受完通知
if Config().is_cluster_enabled(): stay_second(5) # 等待接受完通知
CommonLog.print_test_complete()


Expand Down
1 change: 1 addition & 0 deletions py12306/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class Config:
WEB_ENABLE = 0
WEB_USER = {}
WEB_PORT = 8080
WEB_ENTER_HTML_PATH = PROJECT_DIR + 'py12306/web/static/index.html'

envs = []
retry_time = 5
Expand Down
5 changes: 5 additions & 0 deletions py12306/helpers/func.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ def get_file_modify_time(filePath):
return timestamp_to_time(timestamp)


def get_file_total_line_num(file, encoding='utf-8'):
with open(file, 'r', encoding=encoding) as f:
return len(f.readlines())


def str_to_time(str):
return datetime.datetime.strptime(str, '%Y-%m-%d %H:%M:%S.%f')

Expand Down
8 changes: 4 additions & 4 deletions py12306/log/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def add_quick_log(cls, content=''):
return self

def notification(self, title, content=''):
if sys.platform == 'darwin':
os.system(
'osascript -e \'tell app "System Events" to display notification "{content}" with title "{title}"\''.format(
title=title, content=content))
# if sys.platform == 'darwin': # 不太友好 先关闭,之前没考虑到 mac 下会请求权限
# os.system( 'osascript -e \'tell app "System Events" to display notification "{content}" with title "{title}"\''.format(
# title=title, content=content))
pass
2 changes: 2 additions & 0 deletions py12306/log/common_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class CommonLog(BaseLog):
MESSAGE_SEND_EMAIL_SUCCESS = '邮件发送成功,请检查收件箱'
MESSAGE_SEND_EMAIL_FAIL = '邮件发送失败,请手动检查配置,错误原因 {}'

MESSAGE_OUTPUT_TO_FILE_IS_UN_ENABLE = '请先打开配置:输出到文件'

def __init__(self):
super().__init__()
self.init_data()
Expand Down
5 changes: 3 additions & 2 deletions py12306/log/query_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ def print_query_error(cls, reason, code=None):
def print_job_start(cls, job_name):
self = cls()
self.add_log(
'=== 正在进行第 {query_count} 次查询 {job_name} === {time}'.format(query_count=self.data.get('query_count') + 1,
job_name=job_name, time=datetime.datetime.now()))
'=== 正在进行第 {query_count} 次查询 {job_name} === {time}'.format(
query_count=(self.data.get('query_count', 0)) + 1,
job_name=job_name, time=datetime.datetime.now()))
self.refresh_data()
if is_main_thread():
self.flush(publish=False)
Expand Down
2 changes: 1 addition & 1 deletion py12306/user/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def update_user_info(self, info):
self.info = {**self.info, **info}

def get_name(self):
return self.info.get('user_name')
return self.info.get('user_name', '')

def save_user(self):
if Config().is_cluster_enabled():
Expand Down
28 changes: 24 additions & 4 deletions py12306/web/handler/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from flask import Blueprint, request
import json
import re

from flask import Blueprint, request, send_file
from flask.json import jsonify
from flask_jwt_extended import (jwt_required)

Expand All @@ -9,6 +12,21 @@
app = Blueprint('app', __name__)


@app.route('/', methods=['GET', 'POST'])
def index():
file = Config().WEB_ENTER_HTML_PATH
result = ''
with open(file, 'r', encoding='utf-8') as f:
result = f.read()
config = {
'API_BASE_URL': '' # TODO 自定义 Host
}
result = re.sub(r'<script>[\s\S]*?<\/script>', '<script>window.config={}</script>'.format(json.dumps(config)),
result)

return result


@app.route('/app/menus', methods=['GET'])
@jwt_required
def menus():
Expand All @@ -17,8 +35,10 @@ def menus():
"""
menus = [
{"id": 10, "name": "首页", "url": "/", "icon": "fa fa-tachometer-alt"},
{"id": 40, "name": "数据分析", "url": "/analyze", "icon": "fa fa-signature"},
{"id": 50, "name": "帮助中心", "url": "/help", "icon": "fa fa-search"}
{"id": 20, "name": "用户管理", "url": "/user", "icon": "fa fa-user"},
{"id": 30, "name": "查询任务", "url": "/query", "icon": "fa fa-infinity"},
{"id": 40, "name": "实时日志", "url": "/log/realtime", "icon": "fa fa-signature"},
{"id": 50, "name": "帮助", "url": "/help", "icon": "fa fa-search"}
]
return jsonify(menus)

Expand All @@ -30,6 +50,6 @@ def actions():
操作列表
"""
actions = [
{"text": "退出登录", "link": "", "icon": "fa fa-sign-out-alt"}
{"text": "退出登录", "key": 'logout', "link": "", "icon": "fa fa-sign-out-alt"}
]
return jsonify(actions)
49 changes: 49 additions & 0 deletions py12306/web/handler/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import linecache

from flask import Blueprint, request
from flask.json import jsonify
from flask_jwt_extended import (jwt_required)

from py12306.config import Config
from py12306.helpers.func import get_file_total_line_num
from py12306.log.common_log import CommonLog
from py12306.query.query import Query
from py12306.user.user import User

log = Blueprint('log', __name__)


@log.route('/log/output', methods=['GET'])
@jwt_required
def log_output():
"""
日志
:return:
"""
last_line = int(request.args.get('line', 0))
limit = int(request.args.get('limit', 10))
max_old = 200 # 取最新时 往后再取的数
file = Config().OUT_PUT_LOG_TO_FILE_PATH
res = []

if last_line == -1:
total_line = get_file_total_line_num(file)
last_line = total_line - max_old if total_line > max_old else 0
ranges = range(max_old + limit)
else:
ranges = range(limit)

if Config().OUT_PUT_LOG_TO_FILE_ENABLED:
# with open(Config().OUT_PUT_LOG_TO_FILE_PATH, 'r', encoding='utf-8') as f:
# res = f.readlines()[last_line:limit]
linecache.updatecache(file)
for i in ranges:
tmp = linecache.getline(file, last_line + i)
if tmp != '': res.append(tmp)
last_line += len(res)
else:
res = CommonLog.MESSAGE_OUTPUT_TO_FILE_IS_UN_ENABLE
return jsonify({
'last_line': last_line,
'data': res
})
2 changes: 2 additions & 0 deletions py12306/web/handler/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def convert_job_to_info(job: Job):
'name': job.job_name,
'left_dates': job.left_dates,
'stations': job.stations,
'members': job.members,
'member_num': job.member_num,
'allow_seats': job.allow_seats,
'allow_train_numbers': job.allow_train_numbers,
'passengers': job.passengers,
Expand Down
18 changes: 16 additions & 2 deletions py12306/web/handler/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from flask_jwt_extended import (jwt_required, create_access_token)

from py12306.config import Config
from py12306.helpers.func import str_to_time, timestamp_to_time
from py12306.user.job import UserJob
from py12306.user.user import User

Expand All @@ -21,7 +22,7 @@ def login():
'password'):
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token)
return jsonify({"msg": "用户名或密码错误"}), 401
return jsonify({"msg": "用户名或密码错误"}), 422


@user.route('/users', methods=['GET'])
Expand All @@ -36,11 +37,24 @@ def users():
return jsonify(result)


@user.route('/user/info', methods=['GET'])
@jwt_required
def user_info():
"""
获取用户信息
:return:
"""
result = {
'name': Config().WEB_USER.get('username')
}
return jsonify(result)

def convert_job_to_info(job: UserJob):
return {
'key': job.key,
'user_name': job.user_name,
'name': job.get_name(),
'is_ready': job.is_ready,
'is_loaded': job.user_loaded, # 是否成功加载 ready 是当前是否可用
'last_heartbeat': job.last_heartbeat
'last_heartbeat': timestamp_to_time(job.last_heartbeat)
}
15 changes: 15 additions & 0 deletions py12306/web/static/css/app.dfb5ffed622907edd7c5f81709f2b782.css

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit a0bdc4c

Please sign in to comment.