hiddifypanel 10.50.4__py3-none-any.whl → 10.50.6.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hiddifypanel/VERSION +1 -1
- hiddifypanel/VERSION.py +2 -2
- hiddifypanel/drivers/user_driver.py +11 -7
- hiddifypanel/hutils/flask.py +5 -3
- hiddifypanel/hutils/network/net.py +22 -11
- hiddifypanel/hutils/proxy/shared.py +10 -3
- hiddifypanel/hutils/proxy/xray.py +1 -1
- hiddifypanel/hutils/proxy/xrayjson.py +11 -0
- hiddifypanel/models/config_enum.py +117 -114
- hiddifypanel/models/proxy.py +1 -0
- hiddifypanel/panel/admin/Actions.py +1 -1
- hiddifypanel/panel/admin/DomainAdmin.py +4 -3
- hiddifypanel/panel/admin/ProxyAdmin.py +1 -1
- hiddifypanel/panel/admin/SettingAdmin.py +2 -2
- hiddifypanel/panel/admin/templates/config.html +129 -1
- hiddifypanel/panel/commercial/restapi/v1/__init__.py +1 -1
- hiddifypanel/panel/commercial/restapi/v1/tgbot.py +6 -0
- hiddifypanel/panel/commercial/restapi/v2/admin/user_api.py +2 -2
- hiddifypanel/panel/commercial/restapi/v2/user/configs_api.py +9 -1
- hiddifypanel/panel/commercial/telegrambot/__init__.py +1 -1
- hiddifypanel/panel/common.py +3 -1
- hiddifypanel/panel/custom_widgets.py +3 -0
- hiddifypanel/panel/hiddify.py +7 -4
- hiddifypanel/panel/init_db.py +58 -2
- hiddifypanel/panel/usage.py +30 -16
- hiddifypanel/panel/user/user.py +38 -0
- hiddifypanel/templates/fake.html +4 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/en/LC_MESSAGES/messages.po +21 -2
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po +19 -2
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po +19 -2
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po +19 -2
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po +19 -2
- hiddifypanel/translations.i18n/en.json +10 -1
- hiddifypanel/translations.i18n/fa.json +10 -1
- hiddifypanel/translations.i18n/pt.json +10 -1
- hiddifypanel/translations.i18n/ru.json +10 -1
- hiddifypanel/translations.i18n/zh.json +10 -1
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/METADATA +1 -1
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/RECORD +48 -48
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/WHEEL +1 -1
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/LICENSE.md +0 -0
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/entry_points.txt +0 -0
- {hiddifypanel-10.50.4.dist-info → hiddifypanel-10.50.6.dev0.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,8 @@
|
|
26
26
|
|
27
27
|
|
28
28
|
<div class="card">
|
29
|
-
<div class="card-header"><input id="search_settings" type="text" class="form-control" placeholder="{{_(" Search
|
29
|
+
<div class="card-header"><input id="search_settings" type="text" class="form-control" placeholder="{{_(" Search
|
30
|
+
Settings")}}">
|
30
31
|
</div>
|
31
32
|
<div class="card-body">
|
32
33
|
<div class="row">
|
@@ -81,6 +82,133 @@
|
|
81
82
|
|
82
83
|
{% block tail %}
|
83
84
|
{{super()}}
|
85
|
+
<link rel="stylesheet" href="https://cdn.ckeditor.com/ckeditor5/42.0.2/ckeditor5.css">
|
86
|
+
<style>
|
87
|
+
.ck.ck-editor {
|
88
|
+
color: black !important;
|
89
|
+
}
|
90
|
+
</style>
|
91
|
+
<script src="https://cdn.ckeditor.com/ckeditor5/42.0.2/ckeditor5.js"></script>
|
92
|
+
|
93
|
+
<script type="importmap">
|
94
|
+
{
|
95
|
+
"imports": {
|
96
|
+
"ckeditor5": "https://cdn.ckeditor.com/ckeditor5/42.0.2/ckeditor5.js",
|
97
|
+
"ckeditor5/": "https://cdn.ckeditor.com/ckeditor5/42.0.2/"
|
98
|
+
}
|
99
|
+
}
|
100
|
+
</script>
|
101
|
+
<script type="module">
|
102
|
+
import {
|
103
|
+
ClassicEditor,
|
104
|
+
AccessibilityHelp,
|
105
|
+
Autosave,
|
106
|
+
BalloonToolbar,
|
107
|
+
Bold,
|
108
|
+
Code,
|
109
|
+
Essentials,
|
110
|
+
FontBackgroundColor,
|
111
|
+
FontColor,
|
112
|
+
FontFamily,
|
113
|
+
FontSize,
|
114
|
+
FullPage,
|
115
|
+
GeneralHtmlSupport,
|
116
|
+
Highlight,
|
117
|
+
HtmlComment,
|
118
|
+
HtmlEmbed,
|
119
|
+
Italic,
|
120
|
+
Paragraph,
|
121
|
+
SelectAll,
|
122
|
+
ShowBlocks,
|
123
|
+
SourceEditing,
|
124
|
+
SpecialCharacters,
|
125
|
+
Strikethrough,
|
126
|
+
ImageBlock,
|
127
|
+
ImageInsert,
|
128
|
+
ImageInsertViaUrl,
|
129
|
+
ImageToolbar,
|
130
|
+
|
131
|
+
Underline,
|
132
|
+
Undo
|
133
|
+
} from 'ckeditor5';
|
134
|
+
|
135
|
+
const editorConfig = {
|
136
|
+
toolbar: {
|
137
|
+
items: [
|
138
|
+
'undo',
|
139
|
+
'redo',
|
140
|
+
'|',
|
141
|
+
'bold',
|
142
|
+
'italic',
|
143
|
+
'underline',
|
144
|
+
'strikethrough',
|
145
|
+
'code',
|
146
|
+
'insertImage',
|
147
|
+
'|',
|
148
|
+
'fontSize',
|
149
|
+
'fontColor',
|
150
|
+
'fontBackgroundColor',
|
151
|
+
'|',
|
152
|
+
'sourceEditing',
|
153
|
+
|
154
|
+
],
|
155
|
+
shouldNotGroupWhenFull: false
|
156
|
+
},
|
157
|
+
plugins: [
|
158
|
+
AccessibilityHelp,
|
159
|
+
Autosave,
|
160
|
+
BalloonToolbar,
|
161
|
+
Bold,
|
162
|
+
Code,
|
163
|
+
Essentials,
|
164
|
+
FontBackgroundColor,
|
165
|
+
FontColor,
|
166
|
+
FontFamily,
|
167
|
+
FontSize,
|
168
|
+
FullPage,
|
169
|
+
GeneralHtmlSupport,
|
170
|
+
Highlight,
|
171
|
+
HtmlComment,
|
172
|
+
HtmlEmbed,
|
173
|
+
Italic,
|
174
|
+
Paragraph,
|
175
|
+
SelectAll,
|
176
|
+
ShowBlocks,
|
177
|
+
SourceEditing,
|
178
|
+
ImageBlock,
|
179
|
+
ImageInsertViaUrl,
|
180
|
+
|
181
|
+
Strikethrough,
|
182
|
+
Underline,
|
183
|
+
Undo
|
184
|
+
],
|
185
|
+
balloonToolbar: ['bold', 'italic'],
|
186
|
+
fontFamily: {
|
187
|
+
supportAllValues: true
|
188
|
+
},
|
189
|
+
fontSize: {
|
190
|
+
options: [10, 12, 14, 'default', 18, 20, 22],
|
191
|
+
supportAllValues: true
|
192
|
+
},
|
193
|
+
htmlSupport: {
|
194
|
+
allow: [
|
195
|
+
{
|
196
|
+
name: /^.*$/,
|
197
|
+
styles: true,
|
198
|
+
attributes: true,
|
199
|
+
classes: true
|
200
|
+
}
|
201
|
+
]
|
202
|
+
},
|
203
|
+
|
204
|
+
placeholder: 'Type or paste your content here!'
|
205
|
+
};
|
206
|
+
|
207
|
+
ClassicEditor.create(document.querySelector('.ckeditor'), editorConfig);
|
208
|
+
|
209
|
+
|
210
|
+
</script>
|
211
|
+
|
84
212
|
<script>
|
85
213
|
// $("fieldset .form-group").hide()
|
86
214
|
|
@@ -5,7 +5,7 @@ from marshmallow import Schema, fields
|
|
5
5
|
|
6
6
|
from apiflask import APIBlueprint
|
7
7
|
from flask_restful import Api
|
8
|
-
from .tgbot import bot, register_bot, TGBotResource
|
8
|
+
from .tgbot import bot, register_bot, register_bot_cached, TGBotResource
|
9
9
|
from . import tgbot
|
10
10
|
from .tgmsg import SendMsgResource
|
11
11
|
from .resources import *
|
@@ -5,6 +5,7 @@ from flask_restful import Resource
|
|
5
5
|
|
6
6
|
from hiddifypanel.models import *
|
7
7
|
from hiddifypanel import Events
|
8
|
+
from hiddifypanel.cache import cache
|
8
9
|
logger = telebot.logger
|
9
10
|
|
10
11
|
|
@@ -17,6 +18,11 @@ bot = telebot.TeleBot("", parse_mode="HTML", threaded=False, exception_handler=E
|
|
17
18
|
bot.username = ''
|
18
19
|
|
19
20
|
|
21
|
+
@cache.cache(1000)
|
22
|
+
def register_bot_cached(set_hook=False, remove_hook=False):
|
23
|
+
return register_bot(set_hook, remove_hook)
|
24
|
+
|
25
|
+
|
20
26
|
def register_bot(set_hook=False, remove_hook=False):
|
21
27
|
try:
|
22
28
|
global bot
|
@@ -35,8 +35,8 @@ class UserApi(MethodView):
|
|
35
35
|
for field in User.__table__.columns.keys(): # type: ignore
|
36
36
|
if field in ['id', 'expiry_time']:
|
37
37
|
continue
|
38
|
-
if field
|
39
|
-
|
38
|
+
# if field in data:
|
39
|
+
# setattr(user, field, data[field])
|
40
40
|
data['old_uuid'] = uuid
|
41
41
|
user_driver.remove_client(user)
|
42
42
|
dbuser = User.add_or_update(**data) or abort(502, "Unknown issue! User is not patched")
|
@@ -108,7 +108,15 @@ class AllConfigsAPI(MethodView):
|
|
108
108
|
)
|
109
109
|
)
|
110
110
|
|
111
|
-
|
111
|
+
if hconfig(ConfigEnum.wireguard_enable):
|
112
|
+
items.append(
|
113
|
+
create_item(
|
114
|
+
"Wireguard", "Wireguard", "", "", "", "",
|
115
|
+
# f"{base_url}singbox.json?name={c['db_domain'].alias or c['db_domain'].domain}-{c['asn']}&asn={c['asn']}&mode={c['mode']}"
|
116
|
+
f"{base_url}wireguard/#{config_name}"
|
117
|
+
)
|
118
|
+
)
|
119
|
+
# Add Singbox: SSh
|
112
120
|
if hconfig(ConfigEnum.sub_singbox_ssh_enable) and hconfig(ConfigEnum.ssh_server_enable):
|
113
121
|
items.append(
|
114
122
|
create_item(
|
hiddifypanel/panel/common.py
CHANGED
@@ -10,6 +10,7 @@ import hiddifypanel.auth as auth
|
|
10
10
|
from hiddifypanel.auth import current_account
|
11
11
|
from apiflask import APIFlask, HTTPError, abort
|
12
12
|
from hiddifypanel import hutils
|
13
|
+
from loguru import logger
|
13
14
|
|
14
15
|
|
15
16
|
def init_app(app: APIFlask):
|
@@ -36,6 +37,7 @@ def init_app(app: APIFlask):
|
|
36
37
|
|
37
38
|
@app.errorhandler(Exception)
|
38
39
|
def internal_server_error(e):
|
40
|
+
logger.exception(e)
|
39
41
|
if isinstance(e, Exception):
|
40
42
|
if hutils.flask.is_api_call(request.path):
|
41
43
|
return {
|
@@ -181,4 +183,4 @@ def init_app(app: APIFlask):
|
|
181
183
|
with app.app_context():
|
182
184
|
import hiddifypanel.panel.commercial.telegrambot as telegrambot
|
183
185
|
if (not telegrambot.bot) or (not telegrambot.bot.username): # type: ignore
|
184
|
-
telegrambot.
|
186
|
+
telegrambot.register_bot_cached(set_hook=True)
|
@@ -47,6 +47,8 @@ class LastResetField(IntegerField):
|
|
47
47
|
|
48
48
|
|
49
49
|
class CKTextAreaWidget(TextArea):
|
50
|
+
extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']
|
51
|
+
|
50
52
|
def __call__(self, field, **kwargs):
|
51
53
|
if kwargs.get('class'):
|
52
54
|
kwargs['class'] += ' ckeditor'
|
@@ -56,6 +58,7 @@ class CKTextAreaWidget(TextArea):
|
|
56
58
|
|
57
59
|
|
58
60
|
class CKTextAreaField(TextAreaField):
|
61
|
+
extra_js = ['//cdn.ckeditor.com/4.6.0/standard/ckeditor.js']
|
59
62
|
widget = CKTextAreaWidget()
|
60
63
|
|
61
64
|
|
hiddifypanel/panel/hiddify.py
CHANGED
@@ -110,17 +110,20 @@ def reinstall_action(complete_install=False, domain_changed=False, do_update=Fal
|
|
110
110
|
def check_need_reset(old_configs, do=False):
|
111
111
|
restart_mode = ApplyMode.nothing
|
112
112
|
for c in old_configs:
|
113
|
+
if c.apply_mode == ApplyMode.nothing:
|
114
|
+
continue
|
113
115
|
# c=ConfigEnum(c)
|
114
|
-
if
|
115
|
-
|
116
|
-
|
116
|
+
if restart_mode == ApplyMode.reinstall:
|
117
|
+
break
|
118
|
+
if old_configs[c] != hconfig(c):
|
119
|
+
restart_mode = c.apply_mode
|
117
120
|
if old_configs[ConfigEnum.proxy_path_admin] != hconfig(ConfigEnum.proxy_path_admin):
|
118
121
|
g.new_proxy_path = hconfig(ConfigEnum.proxy_path_admin)
|
119
122
|
g.force_proxy_path = g.proxy_path
|
120
123
|
# do_full_install=old_config[ConfigEnum.telegram_lib]!=hconfig(ConfigEnum.telegram_lib)
|
121
124
|
if old_configs[ConfigEnum.package_mode] != hconfig(ConfigEnum.package_mode):
|
122
125
|
return reinstall_action(do_update=True)
|
123
|
-
if not (do and restart_mode == ApplyMode.
|
126
|
+
if not (do and restart_mode == ApplyMode.reinstall):
|
124
127
|
return hutils.flask.flash_config_success(restart_mode=restart_mode, domain_changed=False)
|
125
128
|
|
126
129
|
return reinstall_action(complete_install=True, domain_changed=False)
|
hiddifypanel/panel/init_db.py
CHANGED
@@ -12,12 +12,55 @@ from hiddifypanel.models import *
|
|
12
12
|
from hiddifypanel.panel import hiddify
|
13
13
|
from hiddifypanel.database import db, db_execute
|
14
14
|
from flask import g
|
15
|
-
from sqlalchemy import text
|
15
|
+
from sqlalchemy import func, text
|
16
16
|
from loguru import logger
|
17
17
|
MAX_DB_VERSION = 100
|
18
18
|
|
19
19
|
|
20
|
-
def
|
20
|
+
def _v91(child_id):
|
21
|
+
db.session.bulk_save_objects(get_proxy_rows_v1())
|
22
|
+
|
23
|
+
|
24
|
+
def _v90(child_id):
|
25
|
+
result = (
|
26
|
+
db.session.query(
|
27
|
+
DailyUsage.child_id,
|
28
|
+
DailyUsage.admin_id,
|
29
|
+
DailyUsage.date,
|
30
|
+
func.max(DailyUsage.online).label('online'),
|
31
|
+
func.sum(DailyUsage.usage).label('usage'),
|
32
|
+
func.count(DailyUsage.usage).label('count'),
|
33
|
+
)
|
34
|
+
.group_by(DailyUsage.child_id, DailyUsage.admin_id, DailyUsage.date)
|
35
|
+
.all()
|
36
|
+
)
|
37
|
+
|
38
|
+
for r in result:
|
39
|
+
if r.count > 1:
|
40
|
+
# Delete existing records for this group
|
41
|
+
db.session.query(DailyUsage).filter(
|
42
|
+
DailyUsage.child_id == r.child_id,
|
43
|
+
DailyUsage.admin_id == r.admin_id,
|
44
|
+
DailyUsage.date == r.date
|
45
|
+
).delete()
|
46
|
+
|
47
|
+
# Add the aggregated record
|
48
|
+
new_record = DailyUsage(
|
49
|
+
child_id=r.child_id,
|
50
|
+
admin_id=r.admin_id,
|
51
|
+
date=r.date,
|
52
|
+
online=r.online,
|
53
|
+
usage=r.usage
|
54
|
+
)
|
55
|
+
db.session.add(new_record)
|
56
|
+
|
57
|
+
# Commit the changes to the database
|
58
|
+
db.session.commit()
|
59
|
+
|
60
|
+
|
61
|
+
def _v89(child_id):
|
62
|
+
set_hconfig(ConfigEnum.path_splithttp, hutils.random.get_random_string(7, 15))
|
63
|
+
set_hconfig(ConfigEnum.splithttp_enable, False)
|
21
64
|
pass
|
22
65
|
|
23
66
|
|
@@ -471,6 +514,9 @@ def get_proxy_rows_v1():
|
|
471
514
|
"httpupgrade direct vless",
|
472
515
|
# "httpupgrade direct trojan",
|
473
516
|
"httpupgrade direct vmess",
|
517
|
+
"splithttp direct vless",
|
518
|
+
"splithttp direct trojan",
|
519
|
+
"splithttp direct vmess",
|
474
520
|
"tcp direct vless",
|
475
521
|
"tcp direct trojan",
|
476
522
|
"tcp direct vmess",
|
@@ -487,6 +533,11 @@ def get_proxy_rows_v1():
|
|
487
533
|
"httpupgrade relay vless",
|
488
534
|
# "httpupgrade relay trojan",
|
489
535
|
"httpupgrade relay vmess",
|
536
|
+
|
537
|
+
"splithttp relay vless",
|
538
|
+
"splithttp relay trojan",
|
539
|
+
"splithttp relay vmess",
|
540
|
+
|
490
541
|
"tcp relay vless",
|
491
542
|
"tcp relay trojan",
|
492
543
|
"tcp relay vmess",
|
@@ -506,6 +557,11 @@ def get_proxy_rows_v1():
|
|
506
557
|
"httpupgrade CDN vless",
|
507
558
|
# "httpupgrade CDN trojan",
|
508
559
|
"httpupgrade CDN vmess",
|
560
|
+
|
561
|
+
"splithttp CDN vless",
|
562
|
+
"splithttp CDN trojan",
|
563
|
+
"splithttp CDN vmess",
|
564
|
+
|
509
565
|
"grpc CDN vless",
|
510
566
|
"grpc CDN trojan",
|
511
567
|
"grpc CDN vmess",
|
hiddifypanel/panel/usage.py
CHANGED
@@ -7,14 +7,24 @@ from hiddifypanel.drivers import user_driver
|
|
7
7
|
from hiddifypanel.models import *
|
8
8
|
from hiddifypanel.panel import hiddify
|
9
9
|
from hiddifypanel.database import db
|
10
|
-
from hiddifypanel import hutils
|
10
|
+
from hiddifypanel import cache, hutils
|
11
11
|
|
12
12
|
to_gig_d = 1024**3
|
13
13
|
|
14
14
|
|
15
15
|
def update_local_usage():
|
16
|
-
|
17
|
-
|
16
|
+
lock_key = "lock-update-local-usage"
|
17
|
+
if not cache.redis_client.set(lock_key, "locked", nx=True, ex=600):
|
18
|
+
return {"msg": "last update task is not finished yet."}
|
19
|
+
try:
|
20
|
+
res = user_driver.get_users_usage(reset=True)
|
21
|
+
# cache.redis_client.delete(lock_key)
|
22
|
+
cache.redis_client.set(lock_key, "locked", nx=False, ex=60)
|
23
|
+
return _add_users_usage(res, child_id=0)
|
24
|
+
except Exception as e:
|
25
|
+
cache.redis_client.set(lock_key, "locked", nx=False, ex=60)
|
26
|
+
raise
|
27
|
+
return {"msg": f"Exception in update usage: {e}"}
|
18
28
|
|
19
29
|
# return {"status": 'success', "comments":res}
|
20
30
|
|
@@ -53,26 +63,30 @@ def _add_users_usage(users_usage_data: Dict[User, Dict], child_id, sync=False):
|
|
53
63
|
|
54
64
|
daily_usage = {}
|
55
65
|
today = datetime.date.today()
|
66
|
+
changes = False
|
56
67
|
for adm in AdminUser.query.all():
|
57
68
|
daily_usage[adm.id] = DailyUsage.query.filter(DailyUsage.date == today, DailyUsage.admin_id == adm.id, DailyUsage.child_id == child_id).first()
|
58
|
-
if
|
69
|
+
if daily_usage[adm.id] is None:
|
59
70
|
daily_usage[adm.id] = DailyUsage(admin_id=adm.id, child_id=child_id)
|
60
71
|
db.session.add(daily_usage[adm.id])
|
72
|
+
changes = True
|
61
73
|
daily_usage[adm.id].online = User.query.filter(User.added_by == adm.id).filter(func.DATE(User.last_online) == today).count()
|
62
|
-
|
74
|
+
# if changes:
|
75
|
+
# db.session.commit()
|
63
76
|
_reset_priodic_usage()
|
64
77
|
|
65
|
-
userDetails = {p.user_id: p for p in UserDetail.query.filter(UserDetail.child_id == child_id).all()}
|
78
|
+
# userDetails = {p.user_id: p for p in UserDetail.query.filter(UserDetail.child_id == child_id).all()}
|
66
79
|
for user, uinfo in users_usage_data.items():
|
67
80
|
usage_bytes = uinfo['usage']
|
68
81
|
|
69
82
|
# UserDetails things
|
70
|
-
detail =
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
83
|
+
# detail = UserDetail(user_id=user.id, child_id=child_id)
|
84
|
+
# detail = userDetails.get(user.id)
|
85
|
+
# if not detail:
|
86
|
+
# detail = UserDetail(user_id=user.id, child_id=child_id)
|
87
|
+
# db.session.add(detail)
|
88
|
+
# if uinfo['devices'] != detail.connected_devices:
|
89
|
+
# detail.connected_devices = uinfo['devices']
|
76
90
|
|
77
91
|
# Enable the user if isn't already
|
78
92
|
if not before_enabled_users[user.uuid] and user.is_active:
|
@@ -99,12 +113,12 @@ def _add_users_usage(users_usage_data: Dict[User, Dict], child_id, sync=False):
|
|
99
113
|
# detail.current_usage_GB = in_gig
|
100
114
|
else:
|
101
115
|
user.current_usage += in_bytes
|
102
|
-
detail.current_usage = detail.current_usage or 0
|
103
|
-
detail.current_usage += in_bytes
|
116
|
+
# detail.current_usage = detail.current_usage or 0
|
117
|
+
# detail.current_usage += in_bytes
|
104
118
|
|
105
119
|
# Change last online time of the user
|
106
120
|
user.last_online = datetime.datetime.now()
|
107
|
-
detail.last_online = datetime.datetime.now()
|
121
|
+
# detail.last_online = datetime.datetime.now()
|
108
122
|
|
109
123
|
# Set start date of user to the current datetime if it hasn't been set already
|
110
124
|
if user.start_date is None:
|
@@ -142,7 +156,7 @@ def _add_users_usage(users_usage_data: Dict[User, Dict], child_id, sync=False):
|
|
142
156
|
if not sync and hutils.node.is_child():
|
143
157
|
hutils.node.child.sync_users_usage_with_parent()
|
144
158
|
|
145
|
-
return {"status": 'success', "comments": res, "date": datetime.datetime.now()}
|
159
|
+
return {"status": 'success', "comments": res, "date": hutils.convert.time_to_json(datetime.datetime.now())}
|
146
160
|
|
147
161
|
|
148
162
|
def send_bot_message(user):
|
hiddifypanel/panel/user/user.py
CHANGED
@@ -73,6 +73,44 @@ class UserView(FlaskView):
|
|
73
73
|
'''Returns singbox client JSON config (ssh)'''
|
74
74
|
return self.singbox_ssh_imp()
|
75
75
|
|
76
|
+
@route("/wireguard/")
|
77
|
+
@route("/wireguard")
|
78
|
+
@login_required(roles={Role.user})
|
79
|
+
def wireguard(self):
|
80
|
+
'''Returns wireguard client config'''
|
81
|
+
c = get_common_data(g.account.uuid, 'new')
|
82
|
+
wireguards = []
|
83
|
+
servers = set()
|
84
|
+
for pinfo in hutils.proxy.get_valid_proxies(c['domains']):
|
85
|
+
if pinfo['proto'] != ProxyProto.wireguard:
|
86
|
+
continue
|
87
|
+
wireguards.append(pinfo)
|
88
|
+
|
89
|
+
servers.add(pinfo['server'])
|
90
|
+
|
91
|
+
if not len(wireguards):
|
92
|
+
abort(404)
|
93
|
+
wg = wireguards[0]
|
94
|
+
addrs = f"{wg['wg_ipv4']}/32"
|
95
|
+
if wg['wg_ipv6']:
|
96
|
+
addrs += f", {wg['wg_ipv6']}/128"
|
97
|
+
resp = f"""
|
98
|
+
[Interface]
|
99
|
+
PrivateKey = {wg['wg_pk']}
|
100
|
+
Address = {addrs}
|
101
|
+
DNS = 1.1.1.1
|
102
|
+
MTU = 1390
|
103
|
+
|
104
|
+
[Peer]
|
105
|
+
PublicKey = {wg['wg_pub']}
|
106
|
+
PresharedKey = {wg['wg_psk']}
|
107
|
+
AllowedIPs = 0.0.0.0/1, 128.0.0.0/1, ::/1, 8000::/1
|
108
|
+
Endpoint = {next(iter(servers))}:61339 #{servers}
|
109
|
+
"""
|
110
|
+
return add_headers(resp, c)
|
111
|
+
|
112
|
+
# return self.singbox_ssh_imp()
|
113
|
+
|
76
114
|
@route("/clash/")
|
77
115
|
@route("/clash")
|
78
116
|
@login_required(roles={Role.user})
|
hiddifypanel/templates/fake.html
CHANGED
@@ -212,6 +212,8 @@
|
|
212
212
|
{{_("config.grpc_enable.description")}}
|
213
213
|
{{_("config.httpupgrade_enable.label")}}
|
214
214
|
{{_("config.httpupgrade_enable.description")}}
|
215
|
+
{{_("config.splithttp_enable.label")}}
|
216
|
+
{{_("config.splithttp_enable.description")}}
|
215
217
|
{{_("config.vless_enable.label")}}
|
216
218
|
{{_("config.vless_enable.description")}}
|
217
219
|
{{_("config.trojan_enable.label")}}
|
@@ -248,6 +250,8 @@
|
|
248
250
|
{{_("config.path_v2ray.description")}}
|
249
251
|
{{_("config.path_ss.label")}}
|
250
252
|
{{_("config.path_ss.description")}}
|
253
|
+
{{_("config.path_splithttp.label")}}
|
254
|
+
{{_("config.path_splithttp.description")}}
|
251
255
|
{{_("config.path_httpupgrade.label")}}
|
252
256
|
{{_("config.path_httpupgrade.description")}}
|
253
257
|
{{_("config.path_ws.label")}}
|
Binary file
|
@@ -2,8 +2,12 @@
|
|
2
2
|
msgid ""
|
3
3
|
msgstr ""
|
4
4
|
|
5
|
-
msgid "
|
6
|
-
|
5
|
+
msgid ""
|
6
|
+
" Search\n"
|
7
|
+
" Settings"
|
8
|
+
msgstr ""
|
9
|
+
" Search\n"
|
10
|
+
" Settings"
|
7
11
|
|
8
12
|
msgid "%(count)s records were successfully disabled."
|
9
13
|
msgstr "%(count)s records were successfully disabled."
|
@@ -670,6 +674,9 @@ msgstr "Select this option to restore All Users"
|
|
670
674
|
msgid "Root"
|
671
675
|
msgstr "Root"
|
672
676
|
|
677
|
+
msgid "Russia"
|
678
|
+
msgstr "Russia"
|
679
|
+
|
673
680
|
msgid "Save"
|
674
681
|
msgstr "Save"
|
675
682
|
|
@@ -1638,6 +1645,12 @@ msgstr "should be random"
|
|
1638
1645
|
msgid "config.path_httpupgrade.label"
|
1639
1646
|
msgstr "ℹ️ HTTP Upgrade Path"
|
1640
1647
|
|
1648
|
+
msgid "config.path_splithttp.description"
|
1649
|
+
msgstr "config.path_splithttp.description"
|
1650
|
+
|
1651
|
+
msgid "config.path_splithttp.label"
|
1652
|
+
msgstr "config.path_splithttp.label"
|
1653
|
+
|
1641
1654
|
msgid "config.path_ss.description"
|
1642
1655
|
msgstr "Shadowsocks Path in the Links"
|
1643
1656
|
|
@@ -1858,6 +1871,12 @@ msgstr ""
|
|
1858
1871
|
msgid "config.speed_test.label"
|
1859
1872
|
msgstr "🚀 Speed Test"
|
1860
1873
|
|
1874
|
+
msgid "config.splithttp_enable.description"
|
1875
|
+
msgstr "config.splithttp_enable.description"
|
1876
|
+
|
1877
|
+
msgid "config.splithttp_enable.label"
|
1878
|
+
msgstr "config.splithttp_enable.label"
|
1879
|
+
|
1861
1880
|
msgid "config.ssfaketls.description"
|
1862
1881
|
msgstr ""
|
1863
1882
|
"Shadowsocks FakeTLS is a simple obfusacting tool that encapsulate the date "
|
Binary file
|
@@ -2,8 +2,10 @@
|
|
2
2
|
msgid ""
|
3
3
|
msgstr ""
|
4
4
|
|
5
|
-
msgid "
|
6
|
-
|
5
|
+
msgid ""
|
6
|
+
" Search\n"
|
7
|
+
" Settings"
|
8
|
+
msgstr ""
|
7
9
|
|
8
10
|
msgid "%(count)s records were successfully disabled."
|
9
11
|
msgstr "%(count)s رکورد با موفقیت غیرفعال شد."
|
@@ -654,6 +656,9 @@ msgstr "برای بازگرداندن کاربران از این گزینه اس
|
|
654
656
|
msgid "Root"
|
655
657
|
msgstr "ریشه"
|
656
658
|
|
659
|
+
msgid "Russia"
|
660
|
+
msgstr ""
|
661
|
+
|
657
662
|
msgid "Save"
|
658
663
|
msgstr "ذخیره"
|
659
664
|
|
@@ -1635,6 +1640,12 @@ msgstr "باید تصادفی باشد"
|
|
1635
1640
|
msgid "config.path_httpupgrade.label"
|
1636
1641
|
msgstr "ℹ️ مسیر ارتقاء HTTP"
|
1637
1642
|
|
1643
|
+
msgid "config.path_splithttp.description"
|
1644
|
+
msgstr ""
|
1645
|
+
|
1646
|
+
msgid "config.path_splithttp.label"
|
1647
|
+
msgstr ""
|
1648
|
+
|
1638
1649
|
msgid "config.path_ss.description"
|
1639
1650
|
msgstr "مسیر شدوساکس در لینکها"
|
1640
1651
|
|
@@ -1859,6 +1870,12 @@ msgstr ""
|
|
1859
1870
|
msgid "config.speed_test.label"
|
1860
1871
|
msgstr "🚀 تست سرعت"
|
1861
1872
|
|
1873
|
+
msgid "config.splithttp_enable.description"
|
1874
|
+
msgstr ""
|
1875
|
+
|
1876
|
+
msgid "config.splithttp_enable.label"
|
1877
|
+
msgstr ""
|
1878
|
+
|
1862
1879
|
msgid "config.ssfaketls.description"
|
1863
1880
|
msgstr ""
|
1864
1881
|
"شادوساکس FakeTLS یک روش مبهم سازی ساده هست که دیتا را در بسته TLS کپسوله "
|
Binary file
|
@@ -2,8 +2,10 @@
|
|
2
2
|
msgid ""
|
3
3
|
msgstr ""
|
4
4
|
|
5
|
-
msgid "
|
6
|
-
|
5
|
+
msgid ""
|
6
|
+
" Search\n"
|
7
|
+
" Settings"
|
8
|
+
msgstr ""
|
7
9
|
|
8
10
|
msgid "%(count)s records were successfully disabled."
|
9
11
|
msgstr "%(count)s registros foram desativados com sucesso."
|
@@ -609,6 +611,9 @@ msgstr "Selecione esta opção para restaurar todos os usuários"
|
|
609
611
|
msgid "Root"
|
610
612
|
msgstr "Raíz"
|
611
613
|
|
614
|
+
msgid "Russia"
|
615
|
+
msgstr ""
|
616
|
+
|
612
617
|
msgid "Save"
|
613
618
|
msgstr "Salvar"
|
614
619
|
|
@@ -1568,6 +1573,12 @@ msgstr ""
|
|
1568
1573
|
msgid "config.path_httpupgrade.label"
|
1569
1574
|
msgstr ""
|
1570
1575
|
|
1576
|
+
msgid "config.path_splithttp.description"
|
1577
|
+
msgstr ""
|
1578
|
+
|
1579
|
+
msgid "config.path_splithttp.label"
|
1580
|
+
msgstr ""
|
1581
|
+
|
1571
1582
|
msgid "config.path_ss.description"
|
1572
1583
|
msgstr "Caminho Shadowsocks nos Links"
|
1573
1584
|
|
@@ -1785,6 +1796,12 @@ msgstr ""
|
|
1785
1796
|
msgid "config.speed_test.label"
|
1786
1797
|
msgstr "🚀 Teste de velocidade"
|
1787
1798
|
|
1799
|
+
msgid "config.splithttp_enable.description"
|
1800
|
+
msgstr ""
|
1801
|
+
|
1802
|
+
msgid "config.splithttp_enable.label"
|
1803
|
+
msgstr ""
|
1804
|
+
|
1788
1805
|
msgid "config.ssfaketls.description"
|
1789
1806
|
msgstr ""
|
1790
1807
|
"Shadowsocks FakeTLS é uma ferramenta de ofuscação simples que encapsula a "
|
Binary file
|