Skip to content

Commit cdc218e

Browse files
feature/backup (#61)
* feat: 增加定时备份功能
1 parent d6fcb22 commit cdc218e

5 files changed

Lines changed: 119 additions & 24 deletions

File tree

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ requests>=2.32.3
44
rcon>=2.1.1
55
tcping==0.1.1rc1
66
gevent>=24.2.1
7-
prettytable>=0.2.13
7+
prettytable>=0.2.13
8+
crontab>=1.0.1

weauth/constants/core_constant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
CLI_COMMAND = PACKAGE_NAME
1919

2020
# WeAuth Version Storage
21-
VERSION_PYPI: str = '1.6.1'
22-
VERSION: str = '1.6.1'
21+
VERSION_PYPI: str = '1.7.0'
22+
VERSION: str = '1.7.0'
2323

2424

2525
# URLs

weauth/utils/backup.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env python3.10
2+
# -*- coding: utf-8 -*-
3+
# author: NearlyHeadlessJack
4+
# email: wang@rjack.cn
5+
# datetime: 2025/1/21 15:41
6+
# ide: PyCharm
7+
# file: backup.py
8+
from crontab import CronTab
9+
from datetime import datetime
10+
import time
11+
import warnings
12+
import os
13+
import shutil
14+
15+
16+
class BackUp:
17+
def __init__(self, cron: str):
18+
self.entry = CronTab(cron)
19+
self.__flag = False
20+
os.makedirs('backup', exist_ok=True)
21+
22+
def next(self) -> float:
23+
with warnings.catch_warnings():
24+
warnings.simplefilter("ignore")
25+
return self.entry.next()
26+
27+
def run(self):
28+
while True:
29+
next = self.next()
30+
if next < 60.0 and not self.__flag:
31+
try:
32+
self.backup()
33+
self.__flag = True
34+
except FileNotFoundError:
35+
print('-未找到备份文件!')
36+
elif next >= 60.0:
37+
self.__flag = False
38+
time.sleep(40)
39+
40+
def backup(self):
41+
print('-准备开始备份...')
42+
now = datetime.now().strftime("%Y_%m_%d_%H%M")
43+
path = 'backup/' + now
44+
os.makedirs(path, exist_ok=True)
45+
self.copy('config.yaml', path)
46+
self.copy('WeAuth.db', path)
47+
self.copy('ops.yaml', path)
48+
self.copy('cdkey.yaml', path)
49+
self.copy('gift_list.yaml', path)
50+
print('-备份完成,./backup/' + path)
51+
52+
def copy(self, filename: str, path: str) -> None:
53+
try:
54+
shutil.copyfile(filename, path + '/' + filename)
55+
except FileNotFoundError:
56+
print(f'-未找到{filename}!')
57+
58+
59+
if __name__ == '__main__':
60+
backup = BackUp('* * * * *')
61+
backup.backup()

weauth/utils/create_config_yaml.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ def create_config_yaml(config: dict, default_config:dict) -> int:
1414

1515
required_keys = [
1616
'server_connect',
17+
'backup',
18+
'backup_cron',
1719
'welcome',
1820
'mcsm_adr',
1921
'mcsm_api',
@@ -39,6 +41,8 @@ def create_config_yaml(config: dict, default_config:dict) -> int:
3941

4042
config_dict = {
4143
'version': VERSION_PYPI,
44+
'backup': config['backup'],
45+
'backup_cron': config['backup_cron'],
4246
'server_connect': config['server_connect'],
4347
'welcome': config['welcome'],
4448
'mcsm_adr': config['mcsm_adr'],
@@ -63,6 +67,8 @@ def create_config_yaml(config: dict, default_config:dict) -> int:
6367
# 生成 comment 字典
6468
comment_dict = {
6569
'version': '版本号,请勿修改',
70+
'backup': '是否开启配置及数据库备份 0 为不开启,1 为开启',
71+
'backup_cron': '备份系统定时,crontab格式,默认为每天2:00进行备份',
6672
'server_connect': '游戏服务器连接方式,0 为MCSManager,1 为rcon',
6773
'welcome': '玩家成功加入白名单后,微信的回复消息',
6874
'mcsm_adr': 'MCSM的url地址',

weauth/weauth_boostrap.py

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# WeAuth is released under the GNU GENERAL PUBLIC LICENSE v3 (GPLv3.0) license.
44
# https://github.com/nearlyheadlessjack/weauth
55
# 程序总入口
6+
import time
67
from email.policy import default
78
import sys
89
from http.client import responses
@@ -20,7 +21,9 @@
2021
from weauth.constants.core_constant import *
2122
from weauth.constants import exit_code
2223
from weauth.mc_server import MCServerConnection
23-
24+
from multiprocessing import Process
25+
import threading
26+
from weauth.utils.backup import BackUp
2427

2528
def main(args) -> None:
2629
"""应用程序入口"""
@@ -44,6 +47,8 @@ def main(args) -> None:
4447
DB.check_database()
4548
default_config = {
4649
'server_connect': 0,
50+
'backup': 1,
51+
'backup_cron': '0 2 * * *',
4752
'welcome': '欢迎加入我的服务器!\\n如果仍然无法加入服务器, 请联系管理员。\\n祝您游戏愉快!',
4853
'mcsm_adr': 'http://127.0.0.1:23333/',
4954
'mcsm_api': '12345',
@@ -109,6 +114,9 @@ def main(args) -> None:
109114

110115

111116
url = config['url']
117+
backup_ = config['backup']
118+
cron = config['backup_cron']
119+
112120
if args.url != '/wx':
113121
url = args.url
114122

@@ -120,27 +128,17 @@ def main(args) -> None:
120128
'welcome': config['welcome'] # 玩家注册白名单成功
121129
}
122130

123-
# 创建Flask实例
124-
print("-正在启动监听......\n")
125-
listener = Listener(wx_user_name=config['WxUserName'], responses=responses, url=url, game_server=game_server)
131+
# 创建监听进程
132+
weauth_server = Process(target=server_start, args=(config, responses, url, game_server))
126133

127-
if config['ssl'] == 1:
128-
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
129-
try:
130-
ssl_context.load_cert_chain(certfile=config['ssl_cer'], keyfile=config['ssl_key'])
131-
except FileNotFoundError:
132-
print('-未找到ssl证书文件!')
133-
sys.exit(0)
134-
server = pywsgi.WSGIServer(('0.0.0.0', 443), listener.wx_service,
135-
ssl_context=ssl_context)
136-
print(f"-开始在 https://0.0.0.0{url} 进行监听")
137-
server.serve_forever()
138-
else:
139-
# 核心监听程序运行
140-
server = pywsgi.WSGIServer(('0.0.0.0', 80), listener.wx_service)
141-
print(f"-开始在 http://0.0.0.0{url} 进行监听")
142-
server.serve_forever()
134+
if backup_ == 1:
135+
# 创建备份管理系统线程
136+
print('-正在创建备份任务')
137+
backup_thread = threading.Thread(target=backup_server, args=(cron,))
138+
weauth_server.daemon = True
139+
backup_thread.start()
143140

141+
weauth_server.start()
144142

145143

146144
# 读取配置文件
@@ -190,6 +188,35 @@ def check_config_version(config:dict,default_config:dict):
190188
create_config_yaml(config=config,default_config=default_config)
191189

192190

191+
def server_start(config: dict, responses: dict, url: str, game_server: MCServerConnection) -> None:
192+
# 创建Flask实例
193+
print("-正在启动监听......\n")
194+
listener = Listener(wx_user_name=config['WxUserName'], responses=responses, url=url, game_server=game_server)
193195

196+
if config['ssl'] == 1:
197+
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
198+
try:
199+
ssl_context.load_cert_chain(certfile=config['ssl_cer'], keyfile=config['ssl_key'])
200+
except FileNotFoundError:
201+
print('-未找到ssl证书文件!')
202+
sys.exit(0)
203+
server = pywsgi.WSGIServer(('0.0.0.0', 443), listener.wx_service,
204+
ssl_context=ssl_context)
205+
print(f"-开始在 https://0.0.0.0{url} 进行监听")
206+
server.serve_forever()
207+
else:
208+
# 核心监听程序运行
209+
server = pywsgi.WSGIServer(('0.0.0.0', 80), listener.wx_service)
210+
print(f"-开始在 http://0.0.0.0{url} 进行监听")
211+
server.serve_forever()
212+
213+
214+
def backup_server(cron: str) -> None:
215+
try:
216+
backup_task = BackUp(cron)
217+
print(backup_task.next())
218+
backup_task.run()
194219

195-
220+
except ValueError:
221+
print('\033[31m-备份系统计划设置错误,请检查config.yaml中的backup_cron设置是否正确\033[0m')
222+
sys.exit(0)

0 commit comments

Comments
 (0)