Skip to content

Commit

Permalink
实装日期限制与流量限制
Browse files Browse the repository at this point in the history
  • Loading branch information
ermaozi committed Jul 5, 2021
1 parent 7d0b7bd commit 62878c0
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 38,14 @@ trojan-go 多用户多节点管理面板

## 画大饼

- [x] 实装日期限制与流量限制 2021-07-05
- [ ] 主节点启用 trojan
- [ ] 子节点分组与子节点查询
- [ ] 子节点简要信息(目前节点信息占用空间太大,节点一多就很乱)
- [ ] 主节点与子节点改用 https 协议
- [ ] 监控子节点 trojan 状态
- [ ] 面板控制节点升级、重启
- [ ] 删除子节点
- [ ] 实装日期限制与流量限制
- [ ] 各节点可选独立部署数据库,减少主节点IO压力
- [ ] 用户权限自由配置
- [ ] 通过面板自动部署子节点
Expand Down
3 changes: 3 additions & 0 deletions conf/flask/private/private_template.py
Original file line number Diff line number Diff line change
@@ -1,3 1,5 @@
from main.libs.task import jobs

"""
警告:
本文件内所有内容均属于敏感信息
Expand Down Expand Up @@ -25,6 27,7 @@ class Base(object):
MAIL_USERNAME = "[email protected]" # 邮箱账户
MAIL_PASSWORD = "" # 邮箱密码或授权码

JOBS = jobs

class PriProduction(Base):
"""
Expand Down
17 changes: 16 additions & 1 deletion main/libs/db_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 94,21 @@ def del_user(self, username):
def del_node(self, node_name):
self.db.delete({"node_name": node_name})

def limit_user_traffic(self, user_name, nodes):
sql = f'UPDATE users SET quota=0 where username="{user_name}";'
print(sql)
for node_name in nodes:
with DBApi(node_name) as db:
db.cur.execute(sql) # 执行sql语句
db.db.commit()

def restore_user_traffic(self, user_name, nodes):
sql = f'UPDATE users SET quota=-1 where username="{user_name}";'
for node_name in nodes:
with DBApi(node_name) as db:
db.cur.execute(sql) # 执行sql语句
db.db.commit()


class NodeInfoTable(object):
def __init__(self) -> None:
Expand Down Expand Up @@ -147,4 162,4 @@ def get_node_for_nodename(self, node_name):

def set_node_usernumber(self, node_name, usernumber):
self.db.update({"node_name": node_name},
{"node_usernumber": usernumber})
{"node_usernumber": usernumber})
33 changes: 33 additions & 0 deletions main/libs/task.py
Original file line number Diff line number Diff line change
@@ -0,0 1,33 @@
import datetime

from main.models.exts import scheduler
from main.libs.db_api import UserNodesTable, UserTable


def check_user():
with scheduler.app.app_context():
user_api = UserTable()
user_node_api = UserNodesTable()

for i in user_api.get_all_user():
username = i["username"]
quota = i.get("quota")
expiry_date = i.get("expiry_date")
nodes = user_node_api.get_node_for_user_name(username)
user_node_api.restore_user_traffic(username, nodes)
if expiry_date and expiry_date < datetime.datetime.now():
if expiry_date < datetime.datetime.now():
user_node_api.limit_user_traffic(username, nodes)
if quota > 0:
total = user_api.get_user_use(username, nodes)
if (quota * 1024 * 1024 * 1024) < total:
user_node_api.limit_user_traffic(username, nodes)


jobs = [{
'id': 'check_user',
'func': check_user,
'trigger': 'cron',
'hour': 21,
'minute': 33
}]
5 changes: 4 additions & 1 deletion main/models/exts.py
Original file line number Diff line number Diff line change
@@ -1,5 1,8 @@
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_apscheduler import APScheduler


bcrypt = Bcrypt()
db = SQLAlchemy()
bcrypt = Bcrypt()
scheduler = APScheduler()
1 change: 0 additions & 1 deletion main/urls/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 6,6 @@
def init_url(app):
app.add_url_rule('/', view_func=Index.as_view('index'))
app.add_url_rule('/user/login', view_func=Login.as_view('login'))
app.add_url_rule('/login', view_func=Login.as_view('login'))
app.add_url_rule('/user/register', view_func=Register.as_view('register'))
app.add_url_rule('/user/get_all_user',
view_func=GetAllUser.as_view('get_all_user'))
Expand Down
5 changes: 3 additions & 2 deletions main/views/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 26,9 @@ def post(self):

if ret:
rep = f"source <(curl -sL https://git.io/install-trojan)"\
f" --worknode {data['']} {current_app.config['DOMAIN']}"\
f" {data['']} 主节点数据库密码"
f" --worknode {data['node_domain']}"\
f" {current_app.config['DOMAIN']} {data['node_name']} "\
f"主节点数据库密码"
return jsonify({'code': 200, 'data': rep})
else:
return jsonify({'code': 500, 'data': msg})
Expand Down
27 changes: 25 additions & 2 deletions main/views/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 2,17 @@
import json
import random
import string
import datetime

from flask import Response, jsonify, render_template, request

from flask import Response, jsonify, request
from flask.views import MethodView
from main.libs.auth_api import create_token, login_required, constant
from main.libs.db_api import NodeInfoTable, UserNodesTable, UserTable

__all__ = [
"Login", "Logout", "Register", "GetAllUser", "SetUser", "DelUser",
"GetTrojanUrl", "UpdateSubscribe"
"GetTrojanUrl", "Subscribe"
]


Expand All @@ -32,6 34,25 @@ def create_random_str(nummin, nummax):
random.choice(chars) for _ in range(random.randint(nummin, nummax)))


def check_user(username):
user_api = UserTable()
user_node_api = UserNodesTable()

user_data = user_api.get_user(username)
username = user_data["username"]
quota = user_data.get("quota")
expiry_date = user_data.get("expiry_date")
nodes = user_node_api.get_node_for_user_name(username)
user_node_api.restore_user_traffic(username, nodes)
if expiry_date and expiry_date < datetime.datetime.now():
if expiry_date < datetime.datetime.now():
user_node_api.limit_user_traffic(username, nodes)
if quota > 0:
total = user_api.get_user_use(username, nodes)
if (quota * 1024 * 1024 * 1024) < total:
user_node_api.limit_user_traffic(username, nodes)


class Login(MethodView):
def post(self):
user_api = UserTable()
Expand Down Expand Up @@ -176,6 197,8 @@ def post(self):
node_usernumber = len(user_node_api.get_username_for_nodename(node_name))
node_api.set_node_usernumber(node_name, node_usernumber)

check_user(user_name)

return jsonify({"code": 200, "data": {}})


Expand Down
7 changes: 6 additions & 1 deletion manage.py
Original file line number Diff line number Diff line change
@@ -1,7 1,8 @@
from flask.app import Flask
from flask_cors import CORS
from flask_apscheduler import APScheduler

from main.models.exts import bcrypt, db
from main.models.exts import bcrypt, db, scheduler
from main.models.modetool import create_db
from main.urls.main import init_url

Expand All @@ -20,6 21,10 @@ def create_app(config_path):
with app.app_context():
create_db()
init_url(app)

scheduler.init_app(app)
scheduler.start()

return app


Expand Down
1 change: 1 addition & 0 deletions requirements_manage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 2,7 @@ Flask
Flask-Bcrypt
Flask-Cors
Flask-SQLAlchemy
Flask-Apscheduler
PyMySQL
requests
uWSGI

0 comments on commit 62878c0

Please sign in to comment.