Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit 0ebe86f

Browse files
committed
feat: support record relay rule traffic
1 parent ddd7477 commit 0ebe86f

File tree

5 files changed

+191
-93
lines changed

5 files changed

+191
-93
lines changed

apps/api/views.py

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import uuid
2+
from typing import List
23

34
import pendulum
45
from django.conf import settings
@@ -50,7 +51,11 @@ def post(self, request):
5051
if success := request.user.update_proxy_config_from_dict(
5152
data=dict(request.POST.items())
5253
):
53-
data = {"title": "修改成功!", "status": "success", "subtitle": "请及时更换客户端配置!"}
54+
data = {
55+
"title": "修改成功!",
56+
"status": "success",
57+
"subtitle": "请及时更换客户端配置!",
58+
}
5459
else:
5560
data = {
5661
"title": "修改失败!",
@@ -167,6 +172,10 @@ def post(self, request, node_id):
167172
class EhcoRelayConfigView(View):
168173
"""中转机器"""
169174

175+
@csrf_exempt
176+
def dispatch(self, *args, **kwargs):
177+
return super(EhcoRelayConfigView, self).dispatch(*args, **kwargs)
178+
170179
@method_decorator(api_authorized)
171180
def get(self, request, node_id):
172181
node: m.RelayNode = m.RelayNode.get_or_none(node_id)
@@ -176,6 +185,28 @@ def get(self, request, node_id):
176185
else HttpResponseBadRequest()
177186
)
178187

188+
@method_decorator(handle_json_request)
189+
@method_decorator(api_authorized)
190+
def post(self, request, node_id):
191+
node: m.RelayNode = m.RelayNode.get_or_none(node_id)
192+
if not node:
193+
return HttpResponseBadRequest()
194+
if not request.json:
195+
return JsonResponse(data={})
196+
197+
# TODO make this async
198+
rules: List[m.RelayRule] = node.relay_rules.all()
199+
name_rule_map = {rule.name: rule for rule in rules}
200+
for data in request.json:
201+
name = data["relay_label"]
202+
if name in name_rule_map:
203+
rule = name_rule_map[name]
204+
rule.up_traffic += data["stats"]["up"]
205+
rule.down_traffic += data["stats"]["down"]
206+
for rule in rules:
207+
rule.save()
208+
return JsonResponse(data={})
209+
179210

180211
class UserCheckInView(View):
181212
@method_decorator(login_required)
@@ -190,7 +221,11 @@ def post(self, request):
190221
"status": "success",
191222
}
192223
else:
193-
data = {"title": "签到失败!", "subtitle": "今天已经签到过了", "status": "error"}
224+
data = {
225+
"title": "签到失败!",
226+
"subtitle": "今天已经签到过了",
227+
"status": "error",
228+
}
194229
return JsonResponse(data)
195230

196231

@@ -200,9 +235,17 @@ def get(self, request):
200235
user = request.user
201236
order = UserOrder.get_and_check_recent_created_order(user)
202237
if order and order.status != UserOrder.STATUS_CREATED:
203-
info = {"title": "充值成功!", "subtitle": "请去商品界面购买商品!", "status": "success"}
238+
info = {
239+
"title": "充值成功!",
240+
"subtitle": "请去商品界面购买商品!",
241+
"status": "success",
242+
}
204243
else:
205-
info = {"title": "支付查询失败!", "subtitle": "亲,确认支付了么?", "status": "error"}
244+
info = {
245+
"title": "支付查询失败!",
246+
"subtitle": "亲,确认支付了么?",
247+
"status": "error",
248+
}
206249
return JsonResponse({"info": info})
207250

208251
@method_decorator(login_required)
@@ -213,7 +256,13 @@ def post(self, request):
213256
raise ValueError
214257
except ValueError:
215258
return JsonResponse(
216-
{"info": {"title": "校验失败", "subtitle": "请保证金额正确", "status": "error"}},
259+
{
260+
"info": {
261+
"title": "校验失败",
262+
"subtitle": "请保证金额正确",
263+
"status": "error",
264+
}
265+
},
217266
)
218267

219268
if settings.CHECK_PAY_REQ_IP_FROM_CN:
@@ -247,7 +296,13 @@ def purchase(request):
247296
good_id = request.POST.get("goodId")
248297
good = Goods.objects.get(id=good_id)
249298
return (
250-
JsonResponse({"title": "购买成功", "status": "success", "subtitle": "重新订阅即可获取所有节点"})
299+
JsonResponse(
300+
{
301+
"title": "购买成功",
302+
"status": "success",
303+
"subtitle": "重新订阅即可获取所有节点",
304+
}
305+
)
251306
if good.purchase_by_user(request.user)
252307
else JsonResponse({"title": "余额不足", "status": "error", "subtitle": "先去捐赠充值那充值"})
253308
)
@@ -262,7 +317,11 @@ def change_theme(request):
262317
user = request.user
263318
user.theme = theme
264319
user.save()
265-
res = {"title": "修改成功!", "subtitle": "主题更换成功,刷新页面可见", "status": "success"}
320+
res = {
321+
"title": "修改成功!",
322+
"subtitle": "主题更换成功,刷新页面可见",
323+
"status": "success",
324+
}
266325
return JsonResponse(res)
267326

268327

@@ -273,7 +332,11 @@ def reset_sub_uid(request):
273332
"""
274333
user = request.user
275334
user.reset_sub_uid()
276-
res = {"title": "修改成功!", "subtitle": "订阅更换成功,刷新页面可见", "status": "success"}
335+
res = {
336+
"title": "修改成功!",
337+
"subtitle": "订阅更换成功,刷新页面可见",
338+
"status": "success",
339+
}
277340
return JsonResponse(res)
278341

279342

apps/proxy/admin.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,6 @@ def get_formset(self, request, obj=None, **kwargs):
5151
return super().get_formset(request, obj, **kwargs)
5252

5353

54-
class RelayRuleInline(admin.TabularInline):
55-
model = models.RelayRule
56-
verbose_name = "中转规则配置"
57-
extra = 0
58-
fields = [
59-
"rule_name",
60-
"proxy_node",
61-
"relay_node",
62-
"relay_port",
63-
"listen_type",
64-
"transport_type",
65-
]
66-
67-
6854
class ProxyNodeAdmin(admin.ModelAdmin):
6955
list_display = [
7056
"__str__",
@@ -78,11 +64,10 @@ class ProxyNodeAdmin(admin.ModelAdmin):
7864
"sequence",
7965
"api_endpoint",
8066
]
81-
inlines = [RelayRuleInline, OccupancyConfigInline]
67+
inlines = [OccupancyConfigInline]
8268
all_inlines = [
8369
TrojanConfigInline,
8470
SSConfigInline,
85-
RelayRuleInline,
8671
OccupancyConfigInline,
8772
]
8873
list_filter = ["provider_remark", "country"]
@@ -181,6 +166,20 @@ def duplicate(self, request, queryset):
181166
duplicate.type = "warning"
182167

183168

169+
class RelayRuleInline(admin.TabularInline):
170+
model = models.RelayRule
171+
verbose_name = "中转规则配置"
172+
extra = 0
173+
fields = [
174+
"name",
175+
"relay_node",
176+
"relay_port",
177+
"proxy_nodes",
178+
"listen_type",
179+
"transport_type",
180+
]
181+
182+
184183
class RelayNodeAdmin(admin.ModelAdmin):
185184
list_display = [
186185
"__str__",
@@ -219,6 +218,24 @@ def toggle_enable(self, request, queryset):
219218
toggle_enable.type = "danger"
220219

221220

221+
class RelayRuleAdmin(admin.ModelAdmin):
222+
list_display = [
223+
"name",
224+
"relay_node",
225+
"relay_port",
226+
"listen_type",
227+
"transport_type",
228+
"traffic_info",
229+
]
230+
list_filter = ["relay_node"]
231+
list_per_page = 10
232+
show_full_result_count = False
233+
234+
@admin.display(description="流量")
235+
def traffic_info(self, instance):
236+
return f"up:{traffic_format(instance.up_traffic) }/down:{traffic_format(instance.down_traffic)}"
237+
238+
222239
class UserTrafficLogAdmin(admin.ModelAdmin):
223240
list_display = [
224241
"username",
@@ -334,6 +351,8 @@ def get_form(self, request, obj=None, **kwargs):
334351
# Register your models here.
335352
admin.site.register(models.ProxyNode, ProxyNodeAdmin)
336353
admin.site.register(models.RelayNode, RelayNodeAdmin)
354+
admin.site.register(models.RelayRule, RelayRuleAdmin)
355+
337356
admin.site.register(models.UserTrafficLog, UserTrafficLogAdmin)
338357
admin.site.register(models.UserProxyNodeOccupancy, UserProxyNodeOccupancyAdmin)
339358
admin.site.register(models.OccupancyConfig, OccupancyConfigAdmin)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Generated by Django 4.2.6 on 2024-02-05 01:48
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("proxy", "0026_alter_userproxynodeoccupancy_options_and_more"),
9+
]
10+
11+
operations = [
12+
migrations.RemoveField(
13+
model_name="relayrule",
14+
name="proxy_node",
15+
),
16+
migrations.RemoveField(
17+
model_name="relayrule",
18+
name="rule_name",
19+
),
20+
migrations.AddField(
21+
model_name="relayrule",
22+
name="down_traffic",
23+
field=models.BigIntegerField(default=0, verbose_name="下载流量"),
24+
),
25+
migrations.AddField(
26+
model_name="relayrule",
27+
name="name",
28+
field=models.CharField(
29+
blank=True, default="", max_length=64, unique=True, verbose_name="规则名"
30+
),
31+
),
32+
migrations.AddField(
33+
model_name="relayrule",
34+
name="proxy_nodes",
35+
field=models.ManyToManyField(
36+
related_name="relay_rules", to="proxy.proxynode", verbose_name="代理节点"
37+
),
38+
),
39+
migrations.AddField(
40+
model_name="relayrule",
41+
name="up_traffic",
42+
field=models.BigIntegerField(default=0, verbose_name="上传流量"),
43+
),
44+
]

0 commit comments

Comments
 (0)