hiddifypanel 10.50.3__py3-none-any.whl → 10.50.5.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.
Files changed (34) hide show
  1. hiddifypanel/VERSION +1 -1
  2. hiddifypanel/VERSION.py +2 -2
  3. hiddifypanel/drivers/user_driver.py +11 -7
  4. hiddifypanel/drivers/xray_api.py +45 -27
  5. hiddifypanel/hutils/proxy/shared.py +10 -3
  6. hiddifypanel/hutils/proxy/xray.py +1 -1
  7. hiddifypanel/hutils/proxy/xrayjson.py +11 -0
  8. hiddifypanel/models/config_enum.py +3 -0
  9. hiddifypanel/models/proxy.py +1 -0
  10. hiddifypanel/panel/admin/DomainAdmin.py +3 -2
  11. hiddifypanel/panel/init_db.py +54 -2
  12. hiddifypanel/panel/usage.py +31 -17
  13. hiddifypanel/templates/fake.html +4 -0
  14. hiddifypanel/translations/en/LC_MESSAGES/messages.mo +0 -0
  15. hiddifypanel/translations/en/LC_MESSAGES/messages.po +12 -0
  16. hiddifypanel/translations/fa/LC_MESSAGES/messages.mo +0 -0
  17. hiddifypanel/translations/fa/LC_MESSAGES/messages.po +12 -0
  18. hiddifypanel/translations/pt/LC_MESSAGES/messages.mo +0 -0
  19. hiddifypanel/translations/pt/LC_MESSAGES/messages.po +12 -0
  20. hiddifypanel/translations/ru/LC_MESSAGES/messages.mo +0 -0
  21. hiddifypanel/translations/ru/LC_MESSAGES/messages.po +12 -0
  22. hiddifypanel/translations/zh/LC_MESSAGES/messages.mo +0 -0
  23. hiddifypanel/translations/zh/LC_MESSAGES/messages.po +12 -0
  24. hiddifypanel/translations.i18n/en.json +8 -0
  25. hiddifypanel/translations.i18n/fa.json +8 -0
  26. hiddifypanel/translations.i18n/pt.json +8 -0
  27. hiddifypanel/translations.i18n/ru.json +8 -0
  28. hiddifypanel/translations.i18n/zh.json +8 -0
  29. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/METADATA +1 -1
  30. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/RECORD +34 -34
  31. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/WHEEL +1 -1
  32. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/LICENSE.md +0 -0
  33. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/entry_points.txt +0 -0
  34. {hiddifypanel-10.50.3.dist-info → hiddifypanel-10.50.5.dev0.dist-info}/top_level.txt +0 -0
hiddifypanel/VERSION CHANGED
@@ -1 +1 @@
1
- 10.50.3
1
+ 10.50.5.dev0
hiddifypanel/VERSION.py CHANGED
@@ -1,3 +1,3 @@
1
- __version__='10.50.3'
1
+ __version__='10.50.5.dev0'
2
2
  from datetime import datetime
3
- __release_date__= datetime.strptime('2024-07-14','%Y-%m-%d')
3
+ __release_date__= datetime.strptime('2024-07-19','%Y-%m-%d')
@@ -18,11 +18,15 @@ def get_users_usage(reset=True):
18
18
  users = list(User.query.all())
19
19
  res = defaultdict(lambda: {'usage': 0, 'devices': ''})
20
20
  for driver in enabled_drivers():
21
- all_usage = driver.get_all_usage(users)
22
- for user, usage in all_usage.items():
23
- if usage:
24
- res[user]['usage'] += usage
25
- # res[user]['devices'] +=usage
21
+ try:
22
+ all_usage = driver.get_all_usage(users)
23
+ for user, usage in all_usage.items():
24
+ if usage:
25
+ res[user]['usage'] += usage
26
+ # res[user]['devices'] +=usage
27
+ except Exception as e:
28
+ print(driver)
29
+ hiddify.error(f'ERROR! {driver.__class__.__name__} has error in update usage {e}')
26
30
  return res
27
31
 
28
32
 
@@ -40,7 +44,7 @@ def get_enabled_users():
40
44
  total += 1
41
45
  except Exception as e:
42
46
  print(driver)
43
- hiddify.error(f'ERROR! {driver.__class__.__name__} has error in get_enabled users')
47
+ hiddify.error(f'ERROR! {driver.__class__.__name__} has error in get_enabled users {e}')
44
48
  # print(d, total)
45
49
  res = defaultdict(bool)
46
50
  for u, v in d.items():
@@ -54,7 +58,7 @@ def add_client(user: User):
54
58
  try:
55
59
  driver.add_client(user)
56
60
  except Exception as e:
57
- hiddify.error(f'ERROR! {driver.__class__.__name__} has error {e} in add client for user={user.uuid}')
61
+ hiddify.error(f'ERROR! {driver.__class__.__name__} has error {e} in add client for user={user.uuid} {e}')
58
62
 
59
63
 
60
64
  def remove_client(user: User):
@@ -10,27 +10,35 @@ class XrayApi(DriverABS):
10
10
  return hconfig(ConfigEnum.core_type) == "xray"
11
11
 
12
12
  def get_xray_client(self):
13
- return xtlsapi.XrayClient('127.0.0.1', 10085)
13
+ if not hasattr(self, 'xray_client'):
14
+ self.xray_client = xtlsapi.XrayClient('127.0.0.1', 10085)
15
+ return self.xray_client
14
16
 
15
17
  def get_enabled_users(self):
16
18
  xray_client = self.get_xray_client()
17
19
  usages = xray_client.stats_query('user', reset=True)
18
20
  res = defaultdict(int)
21
+ tags = set(self.get_inbound_tags())
19
22
  for use in usages:
20
23
  if "user>>>" not in use.name:
21
24
  continue
22
25
  uuid = use.name.split(">>>")[1].split("@")[0]
23
- try:
24
- t = "xtls"
25
- protocol = "vless"
26
- xray_client.add_client(t, f'{uuid}', f'{uuid}@hiddify.com', protocol=protocol, flow='xtls-rprx-vision', alter_id=0, cipher='chacha20_poly1305')
27
- xray_client.remove_client(t, f'{uuid}@hiddify.com')
28
- res[uuid] = 0
29
- except xtlsapi.xtlsapi.exceptions.EmailAlreadyExists as e:
30
- res[uuid] = 1
31
- except Exception as e:
32
- print(f"error {e}")
33
- res[uuid] = 0
26
+
27
+ for t in tags.copy():
28
+ try:
29
+ self.__add_uuid_to_tag(uuid, t)
30
+ self._remove_client(uuid, [t], False)
31
+ # print(f"Success add {uuid} {t}")
32
+ res[uuid] = 0
33
+ except ValueError:
34
+ # tag invalid
35
+ tags.remove(t)
36
+ pass
37
+ except xtlsapi.xtlsapi.exceptions.EmailAlreadyExists as e:
38
+ res[uuid] = 1
39
+ except Exception as e:
40
+ print(f"error {e}")
41
+ res[uuid] = 0
34
42
 
35
43
  return res
36
44
 
@@ -63,10 +71,8 @@ class XrayApi(DriverABS):
63
71
  inbounds = {}
64
72
  return list(inbounds)
65
73
 
66
- def add_client(self, user):
67
- uuid = user.uuid
74
+ def __add_uuid_to_tag(self, uuid, t):
68
75
  xray_client = self.get_xray_client()
69
- tags = self.get_inbound_tags()
70
76
  proto_map = {
71
77
  'vless': 'vless',
72
78
  'realityin': 'vless',
@@ -88,17 +94,27 @@ class XrayApi(DriverABS):
88
94
  res = p, protocol
89
95
  break
90
96
  return res
97
+ p, protocol = proto(t)
98
+ if not p:
99
+ raise ValueError("incorrect tag")
100
+ if (protocol == "vless" and p != "xtls" and p != "realityin") or "realityingrpc" in t:
101
+ xray_client.add_client(t, f'{uuid}', f'{uuid}@hiddify.com', protocol=protocol, flow='\0',)
102
+ else:
103
+ xray_client.add_client(t, f'{uuid}', f'{uuid}@hiddify.com', protocol=protocol,
104
+ flow='xtls-rprx-vision', alter_id=0, cipher='chacha20_poly1305')
105
+
106
+ def add_client(self, user):
107
+ uuid = user.uuid
108
+ xray_client = self.get_xray_client()
109
+ tags = self.get_inbound_tags()
110
+
91
111
  for t in tags:
92
112
  try:
93
- p, protocol = proto(t)
94
- if not p:
95
- continue
96
- if (protocol == "vless" and p != "xtls" and p != "realityin") or "realityingrpc" in t:
97
- xray_client.add_client(t, f'{uuid}', f'{uuid}@hiddify.com', protocol=protocol, flow='\0',)
98
- else:
99
- xray_client.add_client(t, f'{uuid}', f'{uuid}@hiddify.com', protocol=protocol,
100
- flow='xtls-rprx-vision', alter_id=0, cipher='chacha20_poly1305')
113
+ self.__add_uuid_to_tag(uuid, t)
101
114
  # print(f"Success add {uuid} {t}")
115
+ except ValueError:
116
+ # tag invalid
117
+ pass
102
118
  except Exception as e:
103
119
  # print(f"error in add {uuid} {t} {e}")
104
120
  pass
@@ -106,16 +122,18 @@ class XrayApi(DriverABS):
106
122
  def remove_client(self, user):
107
123
  return self._remove_client(user.uuid)
108
124
 
109
- def _remove_client(self, uuid):
125
+ def _remove_client(self, uuid, tags=None, dolog=True):
110
126
  xray_client = self.get_xray_client()
111
- tags = self.get_inbound_tags()
127
+ tags = tags or self.get_inbound_tags()
112
128
 
113
129
  for t in tags:
114
130
  try:
115
131
  xray_client.remove_client(t, f'{uuid}@hiddify.com')
116
- print(f"Success remove {uuid} {t}")
132
+ if dolog:
133
+ print(f"Success remove {uuid} {t}")
117
134
  except Exception as e:
118
- print(f"error in remove {uuid} {t} {e}")
135
+ if dolog:
136
+ print(f"error in remove {uuid} {t} {e}")
119
137
  pass
120
138
 
121
139
  def get_all_usage(self, users):
@@ -137,10 +137,12 @@ def get_proxies(child_id: int = 0, only_enabled=False) -> list['Proxy']:
137
137
  proxies = [c for c in proxies if 'trojan' not in c.proto]
138
138
  if not hconfig(ConfigEnum.httpupgrade_enable, child_id):
139
139
  proxies = [c for c in proxies if ProxyTransport.httpupgrade not in c.transport]
140
+ if not hconfig(ConfigEnum.splithttp_enable, child_id):
141
+ proxies = [c for c in proxies if ProxyTransport.splithttp not in c.transport]
140
142
  if not hconfig(ConfigEnum.ws_enable, child_id):
141
143
  proxies = [c for c in proxies if ProxyTransport.WS not in c.transport]
142
- if not hconfig(ConfigEnum.xtls_enable, child_id):
143
- proxies = [c for c in proxies if ProxyTransport.XTLS not in c.transport]
144
+ # if not hconfig(ConfigEnum.xtls_enable, child_id):
145
+ # proxies = [c for c in proxies if ProxyTransport.XTLS not in c.transport]
144
146
  if not hconfig(ConfigEnum.grpc_enable, child_id):
145
147
  proxies = [c for c in proxies if ProxyTransport.grpc not in c.transport]
146
148
  if not hconfig(ConfigEnum.tcp_enable, child_id):
@@ -190,7 +192,7 @@ def get_valid_proxies(domains: list[Domain]) -> list[dict]:
190
192
  noDomainProxies = False
191
193
  if proxy.proto in [ProxyProto.ssh, ProxyProto.wireguard]:
192
194
  noDomainProxies = True
193
- if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade]:
195
+ if proxy.proto in [ProxyProto.ss] and proxy.transport not in [ProxyTransport.grpc, ProxyTransport.h2, ProxyTransport.WS, ProxyTransport.httpupgrade, ProxyTransport.splithttp]:
194
196
  noDomainProxies = True
195
197
  options = []
196
198
  key = f'{proxy.proto}{proxy.transport}{proxy.cdn}{proxy.l3}'
@@ -411,6 +413,11 @@ def make_proxy(hconfigs: dict, proxy: Proxy, domain_db: Domain, phttp=80, ptls=4
411
413
  base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_httpupgrade]}'
412
414
  base["host"] = domain
413
415
  return base
416
+ if proxy.transport in [ProxyTransport.splithttp]:
417
+ base['transport'] = 'splithttp'
418
+ base['path'] = f'/{path[base["proto"]]}{hconfigs[ConfigEnum.path_splithttp]}'
419
+ base["host"] = domain
420
+ return base
414
421
 
415
422
  if proxy.transport == "grpc":
416
423
  base['transport'] = 'grpc'
@@ -127,7 +127,7 @@ def to_link(proxy: dict) -> str | dict:
127
127
  if proxy.get('fingerprint', 'none') != 'none':
128
128
  baseurl += "&fp=" + proxy['fingerprint']
129
129
  if proxy['l3'] != 'quic':
130
- if proxy.get('l3') != ProxyL3.reality and (proxy.get('transport') == ProxyTransport.tcp or proxy.get('transport') == ProxyTransport.httpupgrade) and proxy['proto'] in [ProxyProto.vless, ProxyProto.trojan]:
130
+ if proxy.get('l3') != ProxyL3.reality and (proxy.get('transport') in {ProxyTransport.tcp, ProxyTransport.httpupgrade, ProxyTransport.splithttp}) and proxy['proto'] in [ProxyProto.vless, ProxyProto.trojan]:
131
131
  baseurl += '&headerType=http'
132
132
  else:
133
133
  baseurl += '&headerType=None'
@@ -261,6 +261,9 @@ def add_stream_settings(base: dict, proxy: dict):
261
261
  if proxy['transport'] == ProxyTransport.httpupgrade:
262
262
  ss['network'] = proxy['transport']
263
263
  add_httpupgrade_stream(ss, proxy)
264
+ if proxy['transport'] == ProxyTransport.splithttp:
265
+ ss['network'] = proxy['transport']
266
+ add_splithttp_stream(ss, proxy)
264
267
  if proxy['transport'] == 'ws':
265
268
  ss['network'] = proxy['transport']
266
269
  add_ws_stream(ss, proxy)
@@ -334,6 +337,14 @@ def add_httpupgrade_stream(ss: dict, proxy: dict):
334
337
  }
335
338
 
336
339
 
340
+ def add_splithttp_stream(ss: dict, proxy: dict):
341
+ ss['splithttpSettings'] = {
342
+ 'path': proxy['path'],
343
+ 'host': proxy['host'],
344
+ # 'acceptProxyProtocol': '', for inbounds only
345
+ }
346
+
347
+
337
348
  def add_kcp_stream(ss: dict, proxy: dict):
338
349
  # TODO: fix server side configs first
339
350
  ss['kcpSettings'] = {}
@@ -239,6 +239,8 @@ class ConfigEnum(metaclass=FastEnum):
239
239
  ws_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
240
240
  grpc_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
241
241
  httpupgrade_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
242
+ splithttp_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
243
+
242
244
  vless_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
243
245
  trojan_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
244
246
  reality_enable = _BoolConfigDscr(ConfigCategory.proxies, ApplyMode.apply)
@@ -260,6 +262,7 @@ class ConfigEnum(metaclass=FastEnum):
260
262
  path_v2ray = _StrConfigDscr(ConfigCategory.hidden, hide_in_virtual_child=True) # deprecated
261
263
  path_ss = _StrConfigDscr(ConfigCategory.hidden, hide_in_virtual_child=True)
262
264
 
265
+ path_splithttp = _StrConfigDscr(ConfigCategory.too_advanced, hide_in_virtual_child=True)
263
266
  path_httpupgrade = _StrConfigDscr(ConfigCategory.too_advanced, hide_in_virtual_child=True)
264
267
  path_ws = _StrConfigDscr(ConfigCategory.too_advanced, hide_in_virtual_child=True)
265
268
  path_tcp = _StrConfigDscr(ConfigCategory.too_advanced, hide_in_virtual_child=True)
@@ -20,6 +20,7 @@ class ProxyTransport(StrEnum):
20
20
  tcp = auto()
21
21
  ssh = auto()
22
22
  httpupgrade = auto()
23
+ splithttp = auto()
23
24
  custom = auto()
24
25
  shadowsocks = auto()
25
26
 
@@ -195,6 +195,7 @@ class DomainAdmin(AdminLTEModelView):
195
195
  # raise ValidationError(_("You have to add your cloudflare api key to use this feature: "))
196
196
 
197
197
  dips = hutils.network.get_domain_ips(model.domain)
198
+ server_ips = [*ipv4_list, *ipv6_list]
198
199
  if model.sub_link_only:
199
200
  if not dips:
200
201
  raise ValidationError(_("Domain can not be resolved! there is a problem in your domain")) # type: ignore
@@ -203,7 +204,7 @@ class DomainAdmin(AdminLTEModelView):
203
204
  raise ValidationError(_("Domain can not be resolved! there is a problem in your domain")) # type: ignore
204
205
 
205
206
  domain_ip_is_same_as_panel = False
206
- server_ips = [*ipv4_list, *ipv6_list]
207
+
207
208
  for mip in server_ips:
208
209
  domain_ip_is_same_as_panel |= mip in dips
209
210
  server_ips_str = ', '.join(list(map(str, server_ips)))
@@ -298,7 +299,7 @@ class DomainAdmin(AdminLTEModelView):
298
299
  def after_model_change(self, form, model, is_created):
299
300
  if hconfig(ConfigEnum.first_setup):
300
301
  set_hconfig(ConfigEnum.first_setup, False)
301
- if model.need_valid_ssl:
302
+ if model.need_valid_ssl and "*" not in model.domain:
302
303
  commander(Command.get_cert, domain=model.domain)
303
304
  if hutils.node.is_child():
304
305
  hutils.node.run_node_op_in_bg(hutils.node.child.sync_with_parent, *[hutils.node.child.SyncFields.domains])
@@ -12,12 +12,51 @@ 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 _v88(child_id):
20
+ def _v90(child_id):
21
+ result = (
22
+ db.session.query(
23
+ DailyUsage.child_id,
24
+ DailyUsage.admin_id,
25
+ DailyUsage.date,
26
+ func.max(DailyUsage.online).label('online'),
27
+ func.sum(DailyUsage.usage).label('usage'),
28
+ func.count(DailyUsage.usage).label('count'),
29
+ )
30
+ .group_by(DailyUsage.child_id, DailyUsage.admin_id, DailyUsage.date)
31
+ .all()
32
+ )
33
+
34
+ for r in result:
35
+ if r.count > 1:
36
+ # Delete existing records for this group
37
+ db.session.query(DailyUsage).filter(
38
+ DailyUsage.child_id == r.child_id,
39
+ DailyUsage.admin_id == r.admin_id,
40
+ DailyUsage.date == r.date
41
+ ).delete()
42
+
43
+ # Add the aggregated record
44
+ new_record = DailyUsage(
45
+ child_id=r.child_id,
46
+ admin_id=r.admin_id,
47
+ date=r.date,
48
+ online=r.online,
49
+ usage=r.usage
50
+ )
51
+ db.session.add(new_record)
52
+
53
+ # Commit the changes to the database
54
+ db.session.commit()
55
+
56
+
57
+ def _v89(child_id):
58
+ set_hconfig(ConfigEnum.path_splithttp, hutils.random.get_random_string(7, 15))
59
+ set_hconfig(ConfigEnum.splithttp_enable, False)
21
60
  pass
22
61
 
23
62
 
@@ -471,6 +510,9 @@ def get_proxy_rows_v1():
471
510
  "httpupgrade direct vless",
472
511
  # "httpupgrade direct trojan",
473
512
  "httpupgrade direct vmess",
513
+ "splithttp direct vless",
514
+ "splithttp direct trojan",
515
+ "splithttp direct vmess",
474
516
  "tcp direct vless",
475
517
  "tcp direct trojan",
476
518
  "tcp direct vmess",
@@ -487,6 +529,11 @@ def get_proxy_rows_v1():
487
529
  "httpupgrade relay vless",
488
530
  # "httpupgrade relay trojan",
489
531
  "httpupgrade relay vmess",
532
+
533
+ "splithttp relay vless",
534
+ "splithttp relay trojan",
535
+ "splithttp relay vmess",
536
+
490
537
  "tcp relay vless",
491
538
  "tcp relay trojan",
492
539
  "tcp relay vmess",
@@ -506,6 +553,11 @@ def get_proxy_rows_v1():
506
553
  "httpupgrade CDN vless",
507
554
  # "httpupgrade CDN trojan",
508
555
  "httpupgrade CDN vmess",
556
+
557
+ "splithttp CDN vless",
558
+ "splithttp CDN trojan",
559
+ "splithttp CDN vmess",
560
+
509
561
  "grpc CDN vless",
510
562
  "grpc CDN trojan",
511
563
  "grpc CDN vmess",
@@ -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
- res = user_driver.get_users_usage(reset=True)
17
- return _add_users_usage(res, child_id=0)
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 not daily_usage[adm.id]:
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 = userDetails.get(user.id)
71
- if not detail:
72
- detail = UserDetail(user_id=user.id, child_id=child_id)
73
- db.session.add(detail)
74
- if uinfo['devices'] != detail.connected_devices:
75
- detail.connected_devices = uinfo['devices']
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,11 +156,11 @@ 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}
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):
149
- if not (hconfig(ConfigEnum.telegram_bot_token) or not hutils.node.is_parent()):
163
+ if not (hconfig(ConfigEnum.telegram_bot_token) or hutils.node.is_child()):
150
164
  return
151
165
  if not user.telegram_id:
152
166
  return
@@ -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")}}
@@ -1638,6 +1638,12 @@ msgstr "should be random"
1638
1638
  msgid "config.path_httpupgrade.label"
1639
1639
  msgstr "ℹ️ HTTP Upgrade Path"
1640
1640
 
1641
+ msgid "config.path_splithttp.description"
1642
+ msgstr "config.path_splithttp.description"
1643
+
1644
+ msgid "config.path_splithttp.label"
1645
+ msgstr "config.path_splithttp.label"
1646
+
1641
1647
  msgid "config.path_ss.description"
1642
1648
  msgstr "Shadowsocks Path in the Links"
1643
1649
 
@@ -1858,6 +1864,12 @@ msgstr ""
1858
1864
  msgid "config.speed_test.label"
1859
1865
  msgstr "🚀 Speed Test"
1860
1866
 
1867
+ msgid "config.splithttp_enable.description"
1868
+ msgstr "config.splithttp_enable.description"
1869
+
1870
+ msgid "config.splithttp_enable.label"
1871
+ msgstr "config.splithttp_enable.label"
1872
+
1861
1873
  msgid "config.ssfaketls.description"
1862
1874
  msgstr ""
1863
1875
  "Shadowsocks FakeTLS is a simple obfusacting tool that encapsulate the date "
@@ -1635,6 +1635,12 @@ msgstr "باید تصادفی باشد"
1635
1635
  msgid "config.path_httpupgrade.label"
1636
1636
  msgstr "ℹ️ مسیر ارتقاء HTTP"
1637
1637
 
1638
+ msgid "config.path_splithttp.description"
1639
+ msgstr ""
1640
+
1641
+ msgid "config.path_splithttp.label"
1642
+ msgstr ""
1643
+
1638
1644
  msgid "config.path_ss.description"
1639
1645
  msgstr "مسیر شدوساکس در لینکها"
1640
1646
 
@@ -1859,6 +1865,12 @@ msgstr ""
1859
1865
  msgid "config.speed_test.label"
1860
1866
  msgstr "🚀 تست سرعت"
1861
1867
 
1868
+ msgid "config.splithttp_enable.description"
1869
+ msgstr ""
1870
+
1871
+ msgid "config.splithttp_enable.label"
1872
+ msgstr ""
1873
+
1862
1874
  msgid "config.ssfaketls.description"
1863
1875
  msgstr ""
1864
1876
  "شادوساکس FakeTLS یک روش مبهم سازی ساده هست که دیتا را در بسته TLS کپسوله "
@@ -1568,6 +1568,12 @@ msgstr ""
1568
1568
  msgid "config.path_httpupgrade.label"
1569
1569
  msgstr ""
1570
1570
 
1571
+ msgid "config.path_splithttp.description"
1572
+ msgstr ""
1573
+
1574
+ msgid "config.path_splithttp.label"
1575
+ msgstr ""
1576
+
1571
1577
  msgid "config.path_ss.description"
1572
1578
  msgstr "Caminho Shadowsocks nos Links"
1573
1579
 
@@ -1785,6 +1791,12 @@ msgstr ""
1785
1791
  msgid "config.speed_test.label"
1786
1792
  msgstr "🚀 Teste de velocidade"
1787
1793
 
1794
+ msgid "config.splithttp_enable.description"
1795
+ msgstr ""
1796
+
1797
+ msgid "config.splithttp_enable.label"
1798
+ msgstr ""
1799
+
1788
1800
  msgid "config.ssfaketls.description"
1789
1801
  msgstr ""
1790
1802
  "Shadowsocks FakeTLS é uma ferramenta de ofuscação simples que encapsula a "
@@ -1650,6 +1650,12 @@ msgstr "должен быть случайным"
1650
1650
  msgid "config.path_httpupgrade.label"
1651
1651
  msgstr ""
1652
1652
 
1653
+ msgid "config.path_splithttp.description"
1654
+ msgstr ""
1655
+
1656
+ msgid "config.path_splithttp.label"
1657
+ msgstr ""
1658
+
1653
1659
  msgid "config.path_ss.description"
1654
1660
  msgstr "Путь Shadowsocks в ссылках"
1655
1661
 
@@ -1871,6 +1877,12 @@ msgstr ""
1871
1877
  msgid "config.speed_test.label"
1872
1878
  msgstr "🚀 Тест скорости"
1873
1879
 
1880
+ msgid "config.splithttp_enable.description"
1881
+ msgstr ""
1882
+
1883
+ msgid "config.splithttp_enable.label"
1884
+ msgstr ""
1885
+
1874
1886
  msgid "config.ssfaketls.description"
1875
1887
  msgstr ""
1876
1888
  "Shadowsocks FakeTLS — это простой инструмент для запутывания, который "
@@ -1554,6 +1554,12 @@ msgstr ""
1554
1554
  msgid "config.path_httpupgrade.label"
1555
1555
  msgstr ""
1556
1556
 
1557
+ msgid "config.path_splithttp.description"
1558
+ msgstr ""
1559
+
1560
+ msgid "config.path_splithttp.label"
1561
+ msgstr ""
1562
+
1557
1563
  msgid "config.path_ss.description"
1558
1564
  msgstr "链接中的 Shadowsocks 路径"
1559
1565
 
@@ -1755,6 +1761,12 @@ msgstr "允许您的用户进行速度测试。它可以帮助他们识别链接
1755
1761
  msgid "config.speed_test.label"
1756
1762
  msgstr "🚀 速度测试"
1757
1763
 
1764
+ msgid "config.splithttp_enable.description"
1765
+ msgstr ""
1766
+
1767
+ msgid "config.splithttp_enable.label"
1768
+ msgstr ""
1769
+
1758
1770
  msgid "config.ssfaketls.description"
1759
1771
  msgstr "Shadowsocks FakeTLS 是一个简单的混淆工具,将日期封装在 tls 数据包中"
1760
1772
 
@@ -639,6 +639,10 @@
639
639
  "description": "should be random",
640
640
  "label": "ℹ️ HTTP Upgrade Path"
641
641
  },
642
+ "path_splithttp": {
643
+ "description": "config.path_splithttp.description",
644
+ "label": "config.path_splithttp.label"
645
+ },
642
646
  "path_ss": {
643
647
  "description": "Shadowsocks Path in the Links",
644
648
  "label": "Shadowsocks Path"
@@ -771,6 +775,10 @@
771
775
  "description": "Allow your users to do Speed Test. It helps them to identify the link quality",
772
776
  "label": "🚀 Speed Test"
773
777
  },
778
+ "splithttp_enable": {
779
+ "description": "config.splithttp_enable.description",
780
+ "label": "config.splithttp_enable.label"
781
+ },
774
782
  "ssfaketls": {
775
783
  "description": "Shadowsocks FakeTLS is a simple obfusacting tool that encapsulate the date In tls packet",
776
784
  "label": "Shadowsocks FakeTLS"
@@ -639,6 +639,10 @@
639
639
  "description": "باید تصادفی باشد",
640
640
  "label": "ℹ️ مسیر ارتقاء HTTP"
641
641
  },
642
+ "path_splithttp": {
643
+ "description": "",
644
+ "label": ""
645
+ },
642
646
  "path_ss": {
643
647
  "description": "مسیر شدوساکس در لینکها",
644
648
  "label": "مسیر شدوساکس"
@@ -771,6 +775,10 @@
771
775
  "description": "با فعالسازی این گزینه به کاربران اجازه تست سرعت می‌دهید. این کار به آن‌ها کمک می‌کند تا کیفیت سرور و کانفیگ‌ها را بسنجند",
772
776
  "label": "🚀 تست سرعت"
773
777
  },
778
+ "splithttp_enable": {
779
+ "description": "",
780
+ "label": ""
781
+ },
774
782
  "ssfaketls": {
775
783
  "description": "شادوساکس FakeTLS یک روش مبهم سازی ساده هست که دیتا را در بسته TLS کپسوله میکند تا فیلترچی فریب بخورد.",
776
784
  "label": "Shadowsocks FakeTLS"
@@ -639,6 +639,10 @@
639
639
  "description": "",
640
640
  "label": ""
641
641
  },
642
+ "path_splithttp": {
643
+ "description": "",
644
+ "label": ""
645
+ },
642
646
  "path_ss": {
643
647
  "description": "Caminho Shadowsocks nos Links",
644
648
  "label": "Caminho das Meias de Sombra"
@@ -771,6 +775,10 @@
771
775
  "description": "Permita que seus usuários façam o teste de velocidade. Isso os ajuda a identificar a qualidade do link",
772
776
  "label": "🚀 Teste de velocidade"
773
777
  },
778
+ "splithttp_enable": {
779
+ "description": "",
780
+ "label": ""
781
+ },
774
782
  "ssfaketls": {
775
783
  "description": "Shadowsocks FakeTLS é uma ferramenta de ofuscação simples que encapsula a data In tls package",
776
784
  "label": "Shadowsocks FakeTLS"
@@ -639,6 +639,10 @@
639
639
  "description": "должен быть случайным",
640
640
  "label": ""
641
641
  },
642
+ "path_splithttp": {
643
+ "description": "",
644
+ "label": ""
645
+ },
642
646
  "path_ss": {
643
647
  "description": "Путь Shadowsocks в ссылках",
644
648
  "label": "Путь для Shadowsocks"
@@ -771,6 +775,10 @@
771
775
  "description": "Разрешите вашим пользователям выполнять тест скорости. Это помогает им определить качество связи.",
772
776
  "label": "🚀 Тест скорости"
773
777
  },
778
+ "splithttp_enable": {
779
+ "description": "",
780
+ "label": ""
781
+ },
774
782
  "ssfaketls": {
775
783
  "description": "Shadowsocks FakeTLS — это простой инструмент для запутывания, который инкапсулирует данные в пакете tls.",
776
784
  "label": "Shadowsocks FakeTLS"
@@ -639,6 +639,10 @@
639
639
  "description": "",
640
640
  "label": ""
641
641
  },
642
+ "path_splithttp": {
643
+ "description": "",
644
+ "label": ""
645
+ },
642
646
  "path_ss": {
643
647
  "description": "链接中的 Shadowsocks 路径",
644
648
  "label": "Shadowsocks 路径"
@@ -771,6 +775,10 @@
771
775
  "description": "允许您的用户进行速度测试。它可以帮助他们识别链接质量",
772
776
  "label": "🚀 速度测试"
773
777
  },
778
+ "splithttp_enable": {
779
+ "description": "",
780
+ "label": ""
781
+ },
774
782
  "ssfaketls": {
775
783
  "description": "Shadowsocks FakeTLS 是一个简单的混淆工具,将日期封装在 tls 数据包中",
776
784
  "label": "Shadowsocks 假TLS"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hiddifypanel
3
- Version: 10.50.3
3
+ Version: 10.50.5.dev0
4
4
  Summary: hiddifypanel multi proxy panel
5
5
  Home-page: https://github.com/hiddify/hiddify-manager/
6
6
  Author: hiddify
@@ -1,6 +1,6 @@
1
1
  hiddifypanel/Events.py,sha256=AlnRdjVul0jP-NCT4-zoaQgowoOo-JhdQB4ytetAFKA,723
2
- hiddifypanel/VERSION,sha256=MBe1HGLa9eJeux-8Enscik477V1t2zUl7gTZoWgnEtE,8
3
- hiddifypanel/VERSION.py,sha256=Ro0PDgqUsuWXE4n3Fgh_-MBvqAJTbd7U83MsC2nKmow,113
2
+ hiddifypanel/VERSION,sha256=7SCZRWwM5oue4PhRudz-wpdsP00oz8VVCPET-VASK8E,13
3
+ hiddifypanel/VERSION.py,sha256=3XGSD1ce86npdXAikb8ccHYk258GkRQlZQMbZIWWpdo,118
4
4
  hiddifypanel/__init__.py,sha256=aLukp3ORszdcH4G9J-MlxhjHN6yFlOuOE6mm-L3aG_g,266
5
5
  hiddifypanel/__main__.py,sha256=IVchnXpK6bm8T3N--mN17HBQNLMeLAjyP7iwzULexB4,218
6
6
  hiddifypanel/auth.py,sha256=Xq0UwiFTRFmQpxnOehQGwPDlJqoelwGhPQbYZ0Xn5c0,7850
@@ -10,9 +10,9 @@ hiddifypanel/database.py,sha256=14sfbGEG-NCqkfUtyLvcO2JbkQ3-Fzs-MezPNkNbvgk,717
10
10
  hiddifypanel/drivers/abstract_driver.py,sha256=HpWkgbWVWF8n3WhDe0BlxsIF1WTWO57AQEAEb2ZVCPM,223
11
11
  hiddifypanel/drivers/singbox_api.py,sha256=gdP_RM8b7qvDpN9RzUyJJ9i_MtMOpATx0LVDLEmDMjs,2270
12
12
  hiddifypanel/drivers/ssh_liberty_bridge_api.py,sha256=m74JOYu7Pkt1bNvKlAAroea1QyxSfhf1bBMbtyf3VJA,2220
13
- hiddifypanel/drivers/user_driver.py,sha256=3xm5xGJXULo6Mb8KCMqUb4BxUTYSGCctn8k7gSbVM8w,2036
13
+ hiddifypanel/drivers/user_driver.py,sha256=58ZYX8FxmvWE8DLNMEFF8QWHdEct51lj80erW-wz2I8,2229
14
14
  hiddifypanel/drivers/wireguard_api.py,sha256=zBC7tlVRgQQC2BJzmwfFKIcNXcfBenpVgD5OGzh7AI4,3640
15
- hiddifypanel/drivers/xray_api.py,sha256=2Dd9UUi0y_dOiZ-8oQ_uHn-9Wk5H468er0i5TWBxDMU,5393
15
+ hiddifypanel/drivers/xray_api.py,sha256=b6f8q2oYZaWqsjaR7t_OAzE7gIjsSdpd4Z1a3i_0BcI,5869
16
16
  hiddifypanel/hutils/__init__.py,sha256=eHFBeXrTwiW3sb0ojTJNG_J26uiwyBoZ9O-W2lQKmeo,296
17
17
  hiddifypanel/hutils/auth.py,sha256=Ci3_lBfLXx1yi2M6HvYX3ceHYtOf-cfX092evcs8528,3030
18
18
  hiddifypanel/hutils/convert.py,sha256=mPEDzR64hKeQ4B_tZRk2Ci8-Ybod0bjX0BbxLHOmLZA,2075
@@ -37,19 +37,19 @@ hiddifypanel/hutils/node/parent.py,sha256=UbyfvfP4fTSn6HN9oZDjYsKYIejiqW6eApKIfP
37
37
  hiddifypanel/hutils/node/shared.py,sha256=FDSj3e-i3pb3mEv5vcUeX0Km1nxYg1CeAruIq7RwFmU,2540
38
38
  hiddifypanel/hutils/proxy/__init__.py,sha256=xXBa83kjYT_b-BNseEykfQYyJBQHTq1ZosfR8ZrQHkI,106
39
39
  hiddifypanel/hutils/proxy/clash.py,sha256=t57ywMo2TPpnAIuOn9v5gMD2os7zqS9b4NQtFX-Do5s,5813
40
- hiddifypanel/hutils/proxy/shared.py,sha256=3xyRNkwlUl91asHhCExcMNrjU5-qWvHI4dtji1exvSo,21766
40
+ hiddifypanel/hutils/proxy/shared.py,sha256=cQ49Vi23MKtvY9hpjb_1HTo2zc0C-TlSabY6uMfFPtc,22175
41
41
  hiddifypanel/hutils/proxy/singbox.py,sha256=WBSsGF7QeNvDPg0SbfWitV2_CP6UQ0gcV5-Gpy4AlkY,10786
42
- hiddifypanel/hutils/proxy/xray.py,sha256=LFHjgQhebN4Kw1XzMDRk7F_K-2DSL93wkad12XijzBA,10694
43
- hiddifypanel/hutils/proxy/xrayjson.py,sha256=Ph1m_ZKINZ57XyWcnhp5mjASWL4ahj8ObVu3Kd7O8ZI,14452
42
+ hiddifypanel/hutils/proxy/xray.py,sha256=TqGTU4JxBkqbhhx2r6dYp8GBrnkWGULO17Kd19ZCJDA,10694
43
+ hiddifypanel/hutils/proxy/xrayjson.py,sha256=TsnOHM5IUAn5AVEsboVVTLzDLS93EU67SqasHm1y6BA,14796
44
44
  hiddifypanel/models/__init__.py,sha256=PngFjQL9WvQP4EioNHRz1tTeyIgLoNvZ7WpmAhwKHnU,677
45
45
  hiddifypanel/models/admin.py,sha256=qZ-BRJ_Gn6hJNWz35SQQSds1CoeDslU9B0MDBRhjPSM,7596
46
46
  hiddifypanel/models/base_account.py,sha256=TUGDGHt3q3GWqWBdWwqaZl75KXTt7bw6pxnzOWAbkjI,3454
47
47
  hiddifypanel/models/child.py,sha256=ZFJaH-GWTKAGD0BGMH0iKEMipi37_cAk59OeJKt2IKA,3039
48
48
  hiddifypanel/models/config.py,sha256=-KKYqMkSEn2DabRxqBogSyA6xOU4ons6sa5CxxHAlAk,6373
49
- hiddifypanel/models/config_enum.py,sha256=KDDXdYfNKjY3SUvmmhAJqLQ5cshFAsQjtqgZ8jbrjo8,15364
49
+ hiddifypanel/models/config_enum.py,sha256=Xa73WjdNJViYwUE6zI4GKUeTF3Rb2M6I1e0kZHjGVa8,15538
50
50
  hiddifypanel/models/domain.py,sha256=0tAPHR6XukN35CoyOxR3zXDNjXR-w_Ezd89jxk2H-xc,8308
51
51
  hiddifypanel/models/parent_domain.py,sha256=bs5F1neOAQu9XHEk3QQTBM4p2iuebM4cnAQqwfNjCtg,2291
52
- hiddifypanel/models/proxy.py,sha256=9cm5Q0ZUEPeRDWdm1lQGom0SM_Q32NCDFTNFh36OzaQ,3304
52
+ hiddifypanel/models/proxy.py,sha256=czKeDz_MVUSHuX2Lf9H2Ys_kgkggtzEiUx3HZPjJCXQ,3327
53
53
  hiddifypanel/models/report.py,sha256=33h9k12SAEWkwZsc3-jUdIIpFL66cEOTHQqVXd07NWY,1001
54
54
  hiddifypanel/models/role.py,sha256=V93_AhOcgbIiAaRYUaNIWKsKZ704ANl0hq-uAJFQCUo,269
55
55
  hiddifypanel/models/usage.py,sha256=BCZtYhmgru-bF8O2dGwJgcN7qtZ29a3arQEK9EVPdtE,4362
@@ -63,15 +63,15 @@ hiddifypanel/panel/cli.py,sha256=GNK-lqoedepG6hfpLHTPLxBaMsdjbQHZAw-qKjdRxnQ,859
63
63
  hiddifypanel/panel/common.py,sha256=3jMmdoMk-qvdT8mSmIXEBh9y54P81EsWUKmGeK9qQKg,7593
64
64
  hiddifypanel/panel/custom_widgets.py,sha256=9qI_fNX8NKqB1r8ljgcaisGZaDM89_PM_rOBZbGaTYs,2506
65
65
  hiddifypanel/panel/hiddify.py,sha256=Tj2WSjNrlRJ3yahFINCTQSn36ygBgFB3SQRr9MegLuE,15572
66
- hiddifypanel/panel/init_db.py,sha256=wewSjqu9LwvD9UiTtrAe4Y6BVl6EjzxwZ7ONUxwaWes,33397
66
+ hiddifypanel/panel/init_db.py,sha256=eBuJoSMJo-7ETbawDugzWcTrTdGaEqXTLjlzOo45vhM,34952
67
67
  hiddifypanel/panel/run_commander.py,sha256=D9y-My0xSe2adHWXKV5UPYGl-9WwKURzniq55MRu6tE,3259
68
- hiddifypanel/panel/usage.py,sha256=LBmM5pKPbCxBxFozPjrXIypNVMlBn4ZyO46t5VBCNKg,6137
68
+ hiddifypanel/panel/usage.py,sha256=EYnfu0puVXX_sRaJ9ujVHfIBM5qy6h_kbH0U6hFONWo,6856
69
69
  hiddifypanel/panel/admin/Actions.py,sha256=yRMKuCZ7J8F8KLlIfFUTYhdL19zVC_tujzZUWmTmCOA,8573
70
70
  hiddifypanel/panel/admin/AdminstratorAdmin.py,sha256=eUUe5b8bGPj2nZstKkwK3lhqBhMixyAbzEMvZAp0I2k,10231
71
71
  hiddifypanel/panel/admin/Backup.py,sha256=BKSoAZgw1j16P1Jh9vMqGj7ZfB2m-WafDK0C5vil5FY,3634
72
72
  hiddifypanel/panel/admin/ConfigAdmin.py,sha256=0hnLY-8BxrpVnrAcQaedWjHnRUq1X_Styi_ZCZ2ivds,2876
73
73
  hiddifypanel/panel/admin/Dashboard.py,sha256=JOqZLHxPOYKQYQVJ7AtHAkilH-anJZQyK1rQrgCJUeA,3798
74
- hiddifypanel/panel/admin/DomainAdmin.py,sha256=hORvsng-7m-r4bPS866g1AxI2eU1lmisrK5QD2p5py0,15790
74
+ hiddifypanel/panel/admin/DomainAdmin.py,sha256=PnvKa_uY5dEb2soa3Mhj_cqs9UjkBDywySpT1N-Pk9M,15815
75
75
  hiddifypanel/panel/admin/NodeAdmin.py,sha256=QAHQjF7e7F4KqsWNWpMt7SoLANlFEborVtWQV9OXJ2E,3102
76
76
  hiddifypanel/panel/admin/ProxyAdmin.py,sha256=jiay6e9Eyi_-VgWORBLgCAyzxLRYCAyJnlG7DtFaQIc,5243
77
77
  hiddifypanel/panel/admin/QuickSetup.py,sha256=EDa_ombxF3vWDsj7JEmDnw8Kf0bKwdXU-IdISDi2hj0,11448
@@ -812,7 +812,7 @@ hiddifypanel/templates/admin-layout.html,sha256=OzEUQ4gxx_pdF2-dPbm-pincmakcEGfi
812
812
  hiddifypanel/templates/admin.ht.old,sha256=e9FBo9YPi7zFVidg8jS6JhOOsYdBbNPxfpTWG1dbIeg,8384
813
813
  hiddifypanel/templates/donation.html,sha256=Oft3WENpSnwpbDgMw3MnhQIlQhuN_TDKm54qd4_FwIk,741
814
814
  hiddifypanel/templates/error.html,sha256=Tnu3mMZ6zvFcATU6_OY1stljVPd9Djnxm3LV7Zx4zck,476
815
- hiddifypanel/templates/fake.html,sha256=Eg8_9LqIPA4-HGHBjji2kT8emaBOD2VWsYfHqcE0WyQ,12943
815
+ hiddifypanel/templates/fake.html,sha256=XdGFRlRuCxeHuKY791eYUGeeASvArpzfB8uExr4dCUA,13107
816
816
  hiddifypanel/templates/flaskadmin-layout.html,sha256=PkF74ld3HZ-j5_nVzVxmispnmmo3ni4WII7OXnN9VOs,7612
817
817
  hiddifypanel/templates/github_issue_body.j2,sha256=6Z4QF-cOAaUxDtRQXT8H4O9SrZ3TGoxgpjnfIpGbsxo,474
818
818
  hiddifypanel/templates/lte-master.html,sha256=jYhcNj8SuMOPT35OEG4e1sLWm03Vq53n4ynf3SdOWj4,1585
@@ -822,24 +822,24 @@ hiddifypanel/templates/redirect.html,sha256=K9x_O4P96vEkqBhOXIhoGrWw1KIqd2bL0BjI
822
822
  hiddifypanel/templates/static.html,sha256=jp6q4wtx-k2A_cjqJoNiMS7Ee30arE45qI3ev4d5ky4,165
823
823
  hiddifypanel/templates/hiddify-flask-admin/actions.html,sha256=2NeITe2e-lPKCk_o511tCIqVtrPu8LYHE1wTCtrFUrI,1331
824
824
  hiddifypanel/templates/hiddify-flask-admin/list.html,sha256=MBGrTqZpzNLe4sZy0RozvXNr8seFUQc2C6v88BJtNWc,11095
825
- hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=SzKllkuY7YnrdQdiAT8Ap_7tDxpFbORmU-13Oer7h24,75756
826
- hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=96O8XWX3UEb8OCw0WL9cGTOkzyU51UupXSKt4dBMs14,78920
827
- hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=hEaGAfhNqehZVV7_NrSvRpW7Etiz38EALwnD-mL8Gu8,96092
828
- hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=JdZQhrLwzFDngs0Wu3qDJaCxSoh7UJn09zwPTMKupyg,101469
829
- hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=vKGf2PjCuTpRZRWpKE6gr_pq1YNzdoArjfvzzGGMxT4,58649
830
- hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=tEWo_g0gJAm1wlmRWfV7rKjt1w87GglPwv504K7hPyI,69401
831
- hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=Qrn8yMYLG7E9BgC4CyzdyL3w0Z-tjNgerYGeiIH3328,97620
832
- hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=7gdyumMtKwmL2KtbdE6aVSZ31N5VM51GuyHhS__41ds,104624
833
- hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=Fwakm_RUEp-khHn9XiJbp1n2rNd1GgktnooKS3MQGJ0,58966
834
- hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=8aP7TqaDZjDEHwiL0t8_eu5yP5PH8OrgouOND9ExH88,68629
835
- hiddifypanel/translations.i18n/en.json,sha256=IukyU5kkY_FRkFx_xT1APP7A5PASazjFOzMzDg5aZy0,68563
836
- hiddifypanel/translations.i18n/fa.json,sha256=ebTs9S5L4F_rFYfQxuJ8pMr6fz2PG8i8fkl4Soyxhzc,91103
837
- hiddifypanel/translations.i18n/pt.json,sha256=YQseQvgHDlCy3HHVJo-yAvepMl_y-zCU0qPLARybDmA,59407
838
- hiddifypanel/translations.i18n/ru.json,sha256=dCp5BI_15WoiMpV2u9_6M6feS_yL_lf22gXeyMqJDB4,94231
839
- hiddifypanel/translations.i18n/zh.json,sha256=8iFoOhmXeoPJHWop7Fa8FMs1Ix-5jvn09gq8N9w1iUs,58875
840
- hiddifypanel-10.50.3.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
841
- hiddifypanel-10.50.3.dist-info/METADATA,sha256=5bikPXsZ6c5iZVaWmr9tMy8sNhn05TRMLmuwpYPHxuc,4039
842
- hiddifypanel-10.50.3.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
843
- hiddifypanel-10.50.3.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
844
- hiddifypanel-10.50.3.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
845
- hiddifypanel-10.50.3.dist-info/RECORD,,
825
+ hiddifypanel/translations/en/LC_MESSAGES/messages.mo,sha256=cE-aZq-3Tmwtf-RZRt5VPUsDP2IHf14UBh5nsF1TzBs,76076
826
+ hiddifypanel/translations/en/LC_MESSAGES/messages.po,sha256=U5c4GAyPUnplApOyVvHCFwyb_lPpxnESZkhFvp7KW3s,79248
827
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.mo,sha256=X5aoRWAPEUQc_9q5BodSpkDiHOhDuVJ0hiN6cwx71Us,96092
828
+ hiddifypanel/translations/fa/LC_MESSAGES/messages.po,sha256=Zbc4Rppblv9vSUuV-AWs1h7t6Qfq6N7rcvcOJBTdwL0,101673
829
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.mo,sha256=uYwghL1lFFCnHPZntnptl9wSEF8Z_UYBwCnOb-tG10Q,58649
830
+ hiddifypanel/translations/pt/LC_MESSAGES/messages.po,sha256=jnfGYa4KbVT9y5IyB05f9a3dvrTjbH6ehoawJwNcOvM,69605
831
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.mo,sha256=HFvWfQSNXgj260qdgVNicxiqm0VNnx2MNOd4W1SgJ_I,97620
832
+ hiddifypanel/translations/ru/LC_MESSAGES/messages.po,sha256=XQ3TJehiI3aI-KMQ9acFYNfy4DonM-pvCMuNWIgJ4Os,104828
833
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.mo,sha256=nwzCTZc-fb8k6Q73h61Ra6pNErHQ4sBEMlwcSrvAyr4,58966
834
+ hiddifypanel/translations/zh/LC_MESSAGES/messages.po,sha256=Eh-RM2eTKAg3PYGjXkKn1jmlSej2QOkyXgP_LX4K87I,68833
835
+ hiddifypanel/translations.i18n/en.json,sha256=Z1unSSA_-pIx9mBLYiQcu9-PJBs9zgtSew582LXftRM,68837
836
+ hiddifypanel/translations.i18n/fa.json,sha256=pZore_pWQQllwWcrZGJeVaRT8BGgCLLWTYvNGo3Lops,91253
837
+ hiddifypanel/translations.i18n/pt.json,sha256=ZLqj-VYvQCg0U_A97UHBzE5S8XsUeZkbELcFp4ehGqQ,59557
838
+ hiddifypanel/translations.i18n/ru.json,sha256=lZFcY6IoxKfJnP0bzfJJl4KPmxXQhCPgprRgoqPmZDE,94381
839
+ hiddifypanel/translations.i18n/zh.json,sha256=SHI1S40XAv8bpHpWTOujgD8_ZYF4dnKy26VypS6uFtk,59025
840
+ hiddifypanel-10.50.5.dev0.dist-info/LICENSE.md,sha256=oDrt-cUsyiDGnRPjEJh-3dH2ddAuK_bIVBD8ntkOtZw,19807
841
+ hiddifypanel-10.50.5.dev0.dist-info/METADATA,sha256=vur3gkJOqe-QY5bAE_ua032TCRVz6w6zsy1OecRZgrk,4044
842
+ hiddifypanel-10.50.5.dev0.dist-info/WHEEL,sha256=-oYQCr74JF3a37z2nRlQays_SX2MqOANoqVjBBAP2yE,91
843
+ hiddifypanel-10.50.5.dev0.dist-info/entry_points.txt,sha256=Xzpqlh3nwBtZhoV9AANJykano056VJvYzaujxPztJaM,60
844
+ hiddifypanel-10.50.5.dev0.dist-info/top_level.txt,sha256=rv-b3qFWUZQTBy0kyBfsr7L6tPpeO7AaQlLHXn-HI5M,13
845
+ hiddifypanel-10.50.5.dev0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.3.0)
2
+ Generator: setuptools (71.0.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5