hiddifypanel 3.0.0.dev63__cp310-cp310-manylinux2014_x86_64.whl → 3.0.0.dev65__cp310-cp310-manylinux2014_x86_64.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/Events.py +27 -4
- hiddifypanel/VERSION +1 -1
- hiddifypanel/VERSION.py +1 -3
- hiddifypanel/__init__.py +7 -3
- hiddifypanel/__main__.py +13 -3
- hiddifypanel/base.py +88 -3
- hiddifypanel/base2.py +40 -3
- hiddifypanel/models/__init__.py +10 -3
- hiddifypanel/models/child.py +26 -4
- hiddifypanel/models/config.py +105 -4
- hiddifypanel/models/config_enum.py +207 -4
- hiddifypanel/models/domain.py +106 -4
- hiddifypanel/models/proxy.py +55 -3
- hiddifypanel/models/usage.py +58 -3
- hiddifypanel/models/user.py +171 -3
- hiddifypanel/panel/__init__.py +7 -4
- hiddifypanel/panel/admin/Actions.py +170 -3
- hiddifypanel/panel/admin/Backup.py +80 -4
- hiddifypanel/panel/admin/ChildAdmin.py +122 -3
- hiddifypanel/panel/admin/ConfigAdmin.py +54 -4
- hiddifypanel/panel/admin/Dashboard.py +70 -4
- hiddifypanel/panel/admin/DomainAdmin.py +195 -4
- hiddifypanel/panel/admin/ProxyAdmin.py +128 -3
- hiddifypanel/panel/admin/QuickSetup.py +127 -4
- hiddifypanel/panel/admin/SettingAdmin.py +224 -3
- hiddifypanel/panel/admin/Terminal.py +51 -4
- hiddifypanel/panel/admin/UserAdmin.py +277 -4
- hiddifypanel/panel/admin/__init__.py +82 -4
- hiddifypanel/panel/admin/adminlte.py +13 -4
- hiddifypanel/panel/admin/commercial_info.py +23 -3
- hiddifypanel/panel/admin/templates/config.html +1 -1
- hiddifypanel/panel/admin/templates/proxy.html +2 -2
- hiddifypanel/panel/admin/websocket.py +9 -3
- hiddifypanel/panel/admin_2.py +33 -3
- hiddifypanel/panel/asset.py +17 -3
- hiddifypanel/panel/cf_api.py +35 -4
- hiddifypanel/panel/clean_ip.py +125 -3
- hiddifypanel/panel/cli.py +172 -3
- hiddifypanel/panel/commercial/CommercialDashboard.py +59 -4
- hiddifypanel/panel/commercial/CommercialSettings.py +224 -3
- hiddifypanel/panel/commercial/ProxyDetailsAdmin.py +38 -4
- hiddifypanel/panel/commercial/__init__.py +50 -4
- hiddifypanel/panel/commercial/restapi/__init__.py +14 -3
- hiddifypanel/panel/commercial/restapi/tgbot.py +57 -3
- hiddifypanel/panel/commercial/telegrambot/DefaultResponse.py +11 -3
- hiddifypanel/panel/commercial/telegrambot/Usage.py +71 -3
- hiddifypanel/panel/commercial/telegrambot/__init__.py +6 -4
- hiddifypanel/panel/commercial/telegrambot/admin.py +120 -3
- hiddifypanel/panel/commercial/telegrambot/information.py +123 -3
- hiddifypanel/panel/common.py +98 -3
- hiddifypanel/panel/custom_widgets.py +71 -4
- hiddifypanel/panel/database.py +18 -3
- hiddifypanel/panel/hiddify.py +655 -4
- hiddifypanel/panel/hiddify_api.py +70 -3
- hiddifypanel/panel/init_db.py +393 -3
- hiddifypanel/panel/usage.py +85 -3
- hiddifypanel/panel/user/__init__.py +25 -4
- hiddifypanel/panel/user/link_maker.py +416 -3
- hiddifypanel/panel/user/templates/home/multi.html +1 -1
- hiddifypanel/panel/user/user.py +233 -3
- hiddifypanel/static/css/custom.css +11 -0
- hiddifypanel/templates/500.html +1 -1
- hiddifypanel/xray_api.py +109 -3
- {hiddifypanel-3.0.0.dev63.dist-info → hiddifypanel-3.0.0.dev65.dist-info}/METADATA +1 -1
- {hiddifypanel-3.0.0.dev63.dist-info → hiddifypanel-3.0.0.dev65.dist-info}/RECORD +69 -71
- hiddifypanel-3.0.0.dev65.dist-info/top_level.txt +1 -0
- hiddifypanel-3.0.0.dev63.dist-info/top_level.txt +0 -2
- pyarmor_runtime_000000/__init__.py +0 -4
- pyarmor_runtime_000000/pyarmor_runtime.so +0 -0
- {hiddifypanel-3.0.0.dev63.dist-info → hiddifypanel-3.0.0.dev65.dist-info}/LICENSE +0 -0
- {hiddifypanel-3.0.0.dev63.dist-info → hiddifypanel-3.0.0.dev65.dist-info}/WHEEL +0 -0
- {hiddifypanel-3.0.0.dev63.dist-info → hiddifypanel-3.0.0.dev65.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,124 @@
|
|
1
|
-
|
2
|
-
from
|
3
|
-
__pyarmor__(__name__, __file__, b'PY000000\x00\x03\n\x00o\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xf4\x16\x00\x00\x12\t\x04\x00\xc7l%}\xea\xfa\x8d\xa3;\x02^m\xb4\tU\xe4\x00\x00\x00\x00\x00\x00\x00\x00\xd2\xabw\x91\x05\xa3\xcdEA)o\xaaC\xa9\x8a\xcf\x1b\x81\x99\x12\xe0k\x98&\x83\x1a\r\x9d\x979\xd4\xf0\xa2;i\x8d\x9fP\xee);\x97\x9c\xb9H\xb9\xfd\xec\x85\xc7\xf3\xd3\x8b\x1c\x0f\xde\xb2\xc1\xddB\x1eq\xc6\x98.\xe6\xa1!\x1d\xd2d~\x9cV\xe3\xdfL\x9d\xb5cD\x19\x14\x91G\x93\x9f\x9f\xa1\xd92\xc1\x8e\x1e\xb2\r(N\x10YJN\x12j\xe5N\x00\x9dJ}\xb4q,\xd1\xea!\xe4\xfc\xcc\x86\xd1\xe6U&\xd5\xe1\xb4p\x81n\x91;:\x9f\xb8Xh\xb0\x97\xfe\xb9\x14\xb9\xd2n\xa1|\xa8:-\xba\xee\xf4\xa3\xecv\xf4\xc9W\xf6\x11K\xba\xf4@\xd7v\x1c\xc6\x80\x1b\xc6\xc0V\xf6\xf5\x1bw9\xad\xe8\x8f\xd8\t\x07v\xd4\xef\xc8\n\xb4\xe8\x00M\xadM\x85v\xc1h\xea_S\x8c\xdc\xb7\xef\x1d\x98\xa7\xd6;t\xe3i\x1a\x02u\xa6\x9e\xa7\x0b\xcc\xfc\xa7\xf3\x16\xa4K\x19\xa6\xd4:q0\xa3\x00\x88qTY\x119\xa5\x80X\xf2\xdd:1P"t5$C~\\\x06\xd5_\xc1\x0f\n\x1eZE\xb8H\xb5\x91\xaf\x13\xb2sj\xba\xd2\xda\x1e\x97vd2ry\xed\x89\x98*N\x0e\tN\xf9\xab\xf3\x7f\x87}y\x99\x8f&\x99\xb2\x05\xb6\xcb\xb4E0\xe3\xc2\xc2\x02\xcdb\x1f&\n\xeb/|aH\xcb_K\x1aM\x1a\x91\xd1e\xab\x7f\x81\xef\x9c\x7f\x8d\x8b\x05\xe3\x9b/\xf5\xc2\x97hZ\xf2\xde\x1e\xe6i\xbb\x83\x02\x03\x11\xfe\x1b\xd3G\xb0"P\x97\xd1\xc4\xa0\xad\x90BU\xd1\xe6>\xa8\xab\xc2\xdc\x13G\xc3`v\xbe\xbd\x0e?j\ty=+\xd4F\xd1HVv*_Q\x94\xcd\xb5\xfb\r\x1a\x85\xd40P\xe0\xad\xd0Q\xe0|\x0c\xe7+\x8b\xd9\xf2sz0\r&\xdfC\xd2\xac[\xc7\xe1X\\n\x0c\x06\x9bB\x07\xeaO\xa6\xbcN\xc6\xb2\xcd[\xd2T\x15\xf9\x05\n?\x8b\xab\xbbT\x90\x0c\xac7U\xac\x95@4\xfb\xa9G\xb5\xe3\xc9\xe5N"*\xdb5\xeb\x7f7\xf2\x8f\xa9K\xa0\xbe\x08TI\x92\x13\x11.\xe6W\xda7y\\:\x9es6Q\x85\xcc\xd1\x17\xbe\xfc\x02\xf4N\x00\xc5#Ag\xe3\xca\x0bb\xad4\x85\xcf\xc9\xed\xdf\xfdV\xc2\xebk\xaa\x85\xc0\x80q\xd3\x8f\xfc\xce\x8f\x1dO\x05q\xab>#0.\x8f\x06B\xe1\n\x83E\x97D\xe7\xdc\xa8\x97&\xaf\xff\x14H^\x18\x84\xb7\x95q\xd63p\xa2;\xaf3\xeb<\xea\xace\xf6^\xb6/\x85y"F\t,W\x8d%"\x94\r\x17[\xdf\x1e\xc3\x98\xadJ\xe6QX\xed>Rk\xda2XK\x99)u<\nS\x06\xb8Y\xace\xf6\xe9\xd1\xfc\x89\xbf-\xcf&w~4d\x96\x9a\x19h\xe3\xee\xbf`w\r\xbd\xc1\xd0\x1b\xbb\xf7 9M\xf0\xd6t8\xd0\x16\x9bXW\x7f\xe5\xacv\xda\x8e<?\x0b!\xe91\x99\x1bW\x91\xab\xb1k\xe2\xdcz\xbd\x16|\t{\n@\xe43/~;\xdc\xa1z\x9b\x01\xb0\x1e\xa9\xf2\xfcL\xb3\x88\xaa\xcf\xa6\xa9\xadz\x9d\x07\xd8z\x1a\xc5\xeb\xbd\x88aU\x13\xa0\x90\xdc\x96\x11\xf93\xb1\x13H\x9a\xf3N\xce\x94\xa9\x0f\xc9a|0\xa8~\x91\xe3\xe9\x99\x82cH\xd0\xc8\x8d\x06\x93\xbdZ\xb1\xf7x\x88\x9b(\x03+\x01\x0b\xe8\x1dz\xe3\x17\x11\x81\x9f\xe6\x82?\xbf9\n.\x07\xba\xad\xe8;z\x9aPb\xec}G\xa3p\x19\xf9\x0c\x1aZs6\x87\xed\xcf\xf5M\xf2\x14kg!w\xeb\xdbZ\x81\x8b\xb6\xb2\x9c\xe0i\x0czy\xf8h\xe7\t\xb1}\xd1\xbcrm<\xe7r\xe4\x9a)@\xd0\xe8\x98\x86\x18O).\x96BH\xa2\xb12A\xbeh!\x00\xfbD\x19\x95\x86\x7f\x86:L;\xdf\xd3\x0bj\n\xc3\x0b\x93\x02q\xd4\xdd6X\x14FX\xa0\xad\x9d%\xc8v/\t+\xd0tK[qp%vU\xd8\x1a\xa0\t\x0bW\xfe\x1c\x13\xe91N\xc3\x8b\x80\x93?\xb6\xa28T\x96\xa5\x0c\x9cU\xf7\xb2\xe0\xe1\xc6\xbe\x89\xed/Z|\x04\xb1\xae+\x93\x95\xad\xedk\xff\x16\xf2\xd5a>s\xa6\xa3\x1e\xec\x06\xd3\x10\x82\xe0p\xc8\xda\xa8\xe9\x11\xceY\xee0\'\x8f\x9a\xa2kt\xbbA\xb3\xc8,\x89\xbf\x1esH\xb9\xb4K\xa4OT\x1d\x03\xb4\xefM\xff\xbe\x02\xf0p\xfb\x9eE\xc6\xad>\x998\xf8\x06\xff@\xec\x1b\xe5\xb3\x0e\xdba\xb7\x12LX\xec\xb90\x8f_\x9a\x88\x1cI\xccw\x12\xe2\xa4E\x14<.\xed!\xb2\xec>6\xb8\xd3b\xbd\x08\xea\x95\xe3\xdd\xc8\x81W\xd4\xf2\x86\xfa\xdeC\'v\x05<@\x14\xa1\x0b\xc3\x13(\x1c\x0e\xda4rV7?\xb6g?2\x9fC\x90\x12\x80\x9b\xe4\xba7\xfa\x08\x82\x9e\x84\x1a\x12;\xb6o"\x1e\xb3/\x9a\x89\xcfj\xbb\xcatX?\xf9\x1e\\Eb\x80\x16\xa5\x92\xd1\x95i\x08\x89\xa9\xc4\xda\xc9d\x84\x13\xb8\xdd\xb1cy\xd9\xc8b\xd0\xf1Z\xcc\x85/\xa0\x1b\x91\x96|7\x8d\xc3\x12\x062R=\xb34\x97^\x1b\xea}i\xa8\xb6\x81\x87~V\xec\x1c$\xd6\t5#\xbe\xa2\xaa2\x9dvP]\r\x9c\xd5\x8b\x96\x13\x00)\xe8\xa9vN\xf5\xc0\xd7\x97\xa3\x8e\xefkjS*\'\xfc\xa8\xe9^\\\xf1Y\nV\xe6=\x16&\x97-Z\x8a\x91\xfe\xf5jR\x98e\x7f\xe7\xf7\xbb\x06!Q\x03\xc9\xe6\x083[\x0c\x02\xb7\xd0c-\r\x12\xd6}\'\xed\xc1n.\xe1G\xaf\x07V\xd5\xa2\xdee\x07O5\xea{\xa2P\xbf\x18/\xa7\x13-O\x0f\x91\xcc\xa1T"\x0c\x7fw\x1b\t.0\x9e\xbe\x15t\x90\x88ul\xb2\xf8+\xdd\x9a\x9dg\x1d\x07\xb0*\x8d\x0e\x17\xf7\xb2p\x04i\t\xf2\x8c"T$\x9e\xbaW\x14\x03\x03N2\x00/\x80/\x95\xdaL\xde\xc4\xa4\xc3\xce\xd7c\x8d\x9b\x18#d\xa9\xb3\xfe\xf3\x9d\x88?\xcd\x01s\x10~j\x8ea\x80\x1cl~P\xa1\x92\xf6\x92\xb4\x0es/@x\x9e\x12\xf5\x87/\x87\xd9$\x10\xd9\x9f\x1ee+\xd3\xdcyK\x1e\xf6\t\x99\x03E\xf4\x18>\xa7\xae>\xdd\xbbg\x9f%\xe0\xa4y@\x19O\xabd\x93\xb57v)h\xc3\x9c\xb1\xbc\x08\x94\xad\xaa\x9b\x19\x87Ht$\x03\x9e\xa5XK\x08\xb2<r\xb5a\x07\xc5\x81\xfb{:\xda\xf5n\xc1\xf1\x82<]W\xe2..\xeaR\xa4Z\xe9\xdf\xcdw\xa63m\xf4\x8cQF\xee\x05\x98Yz\x8b|\xdc\xaf^\xfc$H;j?\x87\xe3\x84\xe0BG\x91\xcb2\x12\xaa\x89\xf9B\xfeM\xc2\xeb\xd3v\xa9Z\x00\xdav\x1bM\xe0\x9a\xaf\x8ba\x8b\xedj `,\x9f\xf4\x8b\xd7B\xc5aB\x92\x87\xc7\xb6\xba\xe3\xaf\x97\x96\xf0\xff\xc2r\x9d\x08\xe2H|Bv:a\xbb\xd9".\xfc\xd0\x04\x17A}\xb4H\x10\xd8\x16\x87\t\x9dU\x11\x9d\'"v\x8fR\xe3\xb72\x16\xe8;X7\xa0\xea\xaa\xe9I_\t:\x8cS\xec\xce\xef%\x89\xe1\x8e\x03\x8e\xeai\x9c\xa9%\xa1\xa4B\xcch\xcda\x0c\xe8\xbcH\xda\xbcmY\xe5\'i\xfd\xca\xc1\x8a`\xf0\xc7\x91\xbe\xfao\x9c\x89i\xd8\x15rr\xd1%>;\xc1\xf4$\x1b\xa6LhNb\xdf3\r\xa6^\x93-H:\x89O\xc5\x16T\x01y\x9b\xa9\xaa\xd9\x94(\x8d\x8d\xd7\x16b@\xfc\t.a\x85\x020\xf8Ks\x96\xe7\'\xc5Z\xa4\xa3\xc3\x0f\xb7*\x95{\xec\xcbX;\xc9\xfd\xb4m\t,\x82iW6g\xbe\x90\xbc\x1b\xf6\x07\r\xeb\xa4H\xb3\xe0Y\x99j&\x82~\xb8\xeb\x82-\x80(\x19L\xbexT\x13\xebz\xe9Aii\xa9\xf7\xc4\x01\xd2e\x82\xf7\xb5\xdc\x87\xcc\xa8}\xe6\x9bf\xa8;U\x88\r\x86\n\x8d\xac`F\xac\xad\xcfY\x1b*\xd5\x02\xc9z\xe4bU,H\xebR\xff\x91\nV\xab\x83\xd4\x9e\xcb\xa6\xf6_\x96J"\xa1\xa99d \xd3\x01\xfcq\x1bL\xafx\xe3|\xe1\xb8\x95 G\xda\xfa\xb9\x98\xae\nV\x08\xa2\xe0v\xeb\x00\x04)\'\xa3\x15\xd5g\x8erz\x11nu\xe1\x9a\xceP\x05\xea>j\xf2m\xfa\xeb\xd3\xc9vPb-+*[p\xa6\xe4\xb3!\x83\xe9\xd2\xeb\xbdl\x91\xfe\xa0qk\xe1\x8b\x0eA\xd0\x02\xd9SI\x96i\\\xc8\xbb\x99O\xff\r\xabu\x16\xeaS\r\x08,\xaa\xa3\x9f*\x1a\x8fS\x0e[}\x83\x82\xb7\xd68\x95\x8aE\x9b!R\n\xba\x01[\xccdT\x9c\xa1+%o\x97\x87Dn\xe6}6\xe5\x1cB\x9ab\xcc\xe1^\xd5\x90\xa6\x94,x7h\x04|\x83z\x93\xf99y\xdaC=\x15A\xa6\x0c\xb6\t\xd7\xe5\xbcLap\xd6cE\x808\x9e\xc34\xa0>"\x84H\x892\xc7\xb1\xda9\xe8\xb7tG\xddD\x83\x13\xa0\xb6\x82\xf2\rR\xbf\x16\xf6\xd2\xda\xdb\x84\x90\xf7\x1bZ\x88\xeeD\xf6>\xa20\xc6\x95\xf124\xe0\\\xcb\x1d\xa9#h\xaf\xd6\xa2!\xffP#\x17\x95(\x1b\xb4\x7f?$\x8b\x14\xadA\x12\xb9\xef\x11(\x83\xb7\xd6\xe7\x8e\xf1I\x0e\x80\xb5\x94\x96\xa4\xbd\\\xfa\xab\x0b\xb9\x80\xacX@\xa6\x1d\\\xff\xd4;\'\xdeQr\xf60\x11\xdb\xe9\xa5\x10x\x1a3*|\xd7\xa4\x00\x80\t\x12\x1d\xa5\xf4] \xa6\xf489\xca\xc6\xdbW\x9a-0\xed\xe8\xd2\x07\xc6\xe1\xe2\xd8\xc0\xfc\x07\x13\xcd\xfc:5j\x8c\x14.\xb4l9\x0f.\xe5\xeb\t>\x97\xf1\x01u\xed\x0b[7\x1b\x02F\xa4\xfeP/#\xeb\xfd\xda\xa4\x00x\xedi\x93\xea\xf8\xd6\xd9c\xfa\xc2\xaf\xa1\xa1\xc3\x8bE\xf3\'\xe9\x0e\xf3b\x01\xac*\t[p\xdf\x9e\x849\xe5?\x8e1\xe63\xe3\x0e\'\x19\x85J\x18\xa8\rV\xc9\xbe\x96\xa2\x17\x90\x84\xa8\xa0\xd7z\xae\xd5\x98\xea\x14\xfa\xa9\x9c \xa1\xe3\x81x\xeeD\x8a|\x85\xd6g6\x06\xca\'Bc\x00\xe6v\x84\x07Q\x1a\xaaFn\x9d\xf6\x1eq!\x91\xd9\xf7\xd0\xb8w\xf5\xef\xfc\xb4^\x923\xc5\x9a\x82\xed\xbe\xa2c\xfe\xcfV\x8c\xa7\x94\xc2\xb7\xd5\x19\xfe\xe0u\x8e_\x19\xd2\xbeMW\xd8L\x93\x0e\xe0C\xe5j\x06\xd7\xf6Q\xa0Q\xd2)\xb1}\xf4<\x90\x15\x9c\xb8\xba\x1a9\xe6\xd3\xeen\x14k\xbbAH\xfd\xa3\x8b\x9b\xd4\xff\n\xe8\xb4\xc5\xdewr\xa6\xbdG"\xa2F\x9d2\x11\xca\xd8j\xd3\xbd\x01\xc3\xde\xe7\x9d\xb8\xca\x8c\xc3|\xbb\xd4\x8a\x1e\xb3 \x87=\xc7\x8e\xb5\xbb6\xe2\xea\xda\xe6\xbb\x8fy\x99\x8b\xf1\xc9\xff\xa0#N)\xebqrD\r\t\xd4\x8cD\xdf#\xb5\xc9\xb5e\xee@r\xc2 jx\xa0\x80\x1b\x01^Q5%\xe2\xb4\xcf\xd0J\x07w\xb2\x8b5TEa >\xcbz\xc5\xdc\xa6\xcb\xed\x92\xd3\x16\x802\xecC%\xef\x03\xa5\x95\xd6J\xf6\n9^vE\xcd\xede\xfa\x8b\x9e?M\xed\x93\xfca\xac\xfc=m\xa6\x04\x0co\xf2*\xe5z\x01\xacvLW\xcb2\xe7/G\x94\x91W\x96\x0e\xfeBEKF\xc6\xc1^\x12\xb7g\x84\x9d\xed\xee\xc2V\xaf\xfb\x11\xda\x1a"\xde\x80\xa5\x18\x14\xd7$\x02\x1e\xca\xad\xf1\x13io\xdf\x8aM9N%\x04I\x8ec~\x1c\xad\xe3~Y\x87X\xc6N\xa6z\x13\xbdw\xbc\x98\xe0 +D\xf5\x14\x93\xe1f\xd5jS\xe1K\x87\xdew\xc6\xf3\x83*\x9c\xb5\x1ag\x0e=B\x01\x8b\xb9_\xa3\x17\xd0\xe1\x88\x03J\xcf9f\xdfV6N\x18\xd3\xc1a\x17h\xd8D\x1e\xdff\x95x\xdd\xe9\x87\xa1\xaa\x01^\xe0}Q\xf8C\xf8\x85\xd7$\x0b\x01i\xb9M\xefL\xba\xb0l\xb2\x92\xf9\x81\xb6\x9b\xf1\xf1\x8cVx92\x92\xaer\xb6\xe4\xbc\xd1\x15\x10E\x8a@\xc79\xbb\xab\xd2\xbbG\xb9Qc\xb9s\x03\xf3\xc8\xa0\xde\xd3\xe8\x9d\x8e\xd4\xb7\xbc\'\xdd\xf9V\xa3]\x0fa(/(\\\xee\xfbe%\xae\xfe_7\n\xda^\xd8\xa3\x8e\xebDHS\x81]8\x04U\xda\xae$\n\xe8\x9as\x94\xa9\xd0\x97\x93\xc5\xb9o\x01\xc2R\xc6S\xa2\x1b\x94h\x83\xda\x0e\xf5\x02\xd0k\x8f~\x7f\x1b\xb6r\x8f\xbce-~\xa1\x82\xff\xf5\xa7*3\xb3`\xbc\x859\x1d$$\xd5\xfa\x10\xc4\x87,\x03#\xde\n\x94g\xe5\x90\x90l\x8c\xc1[\'3\x94\x92)B\xb6e\x98W_\xf7\x8b\xd4\x94\x1a\xa7\xb9\x14\x9ez\xc9q\x9e`\xf4\xd8\xed\x8f\x18B\xfe\xf0\x0fg!\x8d&\xaf\xfblx\x15\xd6K\x9d"\x05\x93\x17m\xe7\xd0T\x95\x96H\x90\xc6NCo\xfd\xde(\x8e1\xb5\x1aif\x96\x08\xdf\xd7\xab\xf3\x06i\xcf\x0f)\xfd\xbe\xf4\xc0/u\xf5\xc6\x1b\xfdL\x98\x8e\xeb\xd9\x08*\xd6t\xad\xd2\xc0n^I\xb9\x95*L\xe7\xf6o\xc0d>l\x08\x82)\xff\xdb\xa3\x97\x8e\xa3W\xe7\xbfS:\xf4\xef"\x9b\xbd\x11\xa9\xe0\xb6\x96\xb13\xd3p,\x8c\x87\x7f.U\x8a\xaf\xb4z\xcew\xb8f\xb4a\xceq\xcc\xa3?I\x8a7\xfd\xbe\x02\xcb\xe3\xf4\x83]\x00\x81\x93\x9e<\xfb\xa9\xb7>\t\xe4\xca\xca\xc4[zo\x96\x96\x97\x86\xc7\xb5\x1f;\xe6s\xab\x94\xaeL\x0b\xac\x9f\x8e\x18?\x0e\x90\xc3S\xb0\xa3\xadVr-\x950\xe2\xac\x9f#U\x7f\xe9\xc4\xd4\x7f\xed~\x14\xde\xd2l\xaa\xbb\x9a\xa4\xb8^\x88z\xf7N\x97\x92\xb8\xcac\r\xb1\xe4\x92\xaf\x95\x17\xb3B\xbe\x95\xf3\xcdp\x8f\xcb\xa8\xb2\x04\xfaU\xb5/\xb2\x15\xf21\xc0,\xad\x00\x81\xf5\xb1\x85\x08\x9b\x9d^\x88\t\xa5\xa4C\x85\xf3\x1f\xb0\xb7$\x7fX\xeb:\x9aJ-\n\x11\x03N5\x92\x19ikk\xf6\xcc\x80\xdb\xff\x15\x93\xc9\x16\x0f\xd3W8\xc7(\xa5\x9a\x8b\xbb\x91\xfa\xc7\xde\xec\x9fSs\x93ZZ/Q(\xba\xa0\xcd\xc3\x15\xf9\x92\xfd\xca\x17\x8b\x95\xb0\x98\xd1\xbd\x7f-:\xf9@\x8b\xefVh\xdd\x00\x90\x15\x80\x85T\r\x14\xad\x93\x04Wds\xb8\r\xa6N2J\xf1]\xe7(\xaeb\x17s_\xaa\xf5\x1d\xa9\xd3;\x17u\xbb\x94\xd8\xad\x94\x91{\xb7\xb7\xf8\xc4\x9d\x0b\xbf\xd0\xf4p\x81\x82}\xf3\xdb\x85X\xce(f\x8e\xb3I\x80B\xdc\xf1\x8f\xb5\xd1\xc1\x86;\x96\xe9\xcaiL\x81:\xf5\x8ao\x18=\x05K\x9c\xa7\xee.\x9c0\xa4Y\xb9,G\x16\'\x1a\x9d\xfe?\xb1\xb8\x1b\x04\xe8\x84\x16\x15\xf6\r\x0e\xdd\x8f\xf3\\<\x9c\xc0\x06m\xe60:H\x86\xe0$+^\x07HP\xc1\xc8\xd7<\x16l\t\x9aU&\x8dGU|x\xc7\x9b\xb2\xf82u\x92N\'\xedn\x13\x14(\xa9d\xb2\x15ny\x901c\x8c\xaak\x85\xc5\x176B\xef?u\'\xfd\xfd\x06\xf8AqE\xbc\xdd\xf3\x9ea\xca\x9b\xd9Ptw~\x04\x80\xac>\xc5P0\xaa6\xd0d\x89\x92\xe4x\x0eC\xb3B\x81\x9fcT\xbc\r\x08\x1d/\xe5\xbcg;\xc1\xbb\xc0p2\x10|\x01\xbchD%\xd6\t\xb3\xe0\xc4\xd5\x8cG\x82\x97Zx\x1dV\x85p\x15\x00\xfa\x9eF\x99\xbe\xa1$\xb0\xd2\xdbw\xb8\x08F;O$\x85M\xd9\xa5L\xdc\xc0m\x13\xf6\x0cg\x11\xf8\x99\xa1\x0e\x85\x86\xfd\x8d-s\xdf\x95\x12\xca\xfe\x16\xab\x14\xff\xee\x0f\xb5V\x1b4\xd2\xa1\xcdq\xa6\xce90\x9bG\xca\x91k\x81\x15\xb4\xf5\x82\xbd\x03\xd8\xa1\xdf\x177\xdb-BC5QD\x0cLZ\xa3\x04`I\xf1\x04n\xf9\xb0N\x06\x19o\xa48\x8e\x9e\x19\xcdHI\x17\x18\xae\x02\\\xfcgM\xf8;\xa1\xb4)2|\x88qw\xd7Y\xfb\xc9\x19\xa1\x86y[l\x8b\x16\x87:\x0f\xac\x11\xb4\xe2\x06)\xb5\xdf\xaaX:\x10\xb1\xe8`\n\x03\x8ae\t\xa5m&(\xd5b\x93\xd6{d\x11N\xd8\x06?\xba#\xe4\x11\xb0+#\x91n\xffZ\n\xbc\xf9t;8\x9fLv\xd9\xe9T\x9e\xbb\xdf\xbd\xab\x8b\xe0H\x9bDe\x01\x12\xbd\xc6\x1d\xa2\x82qCTb\xea\xd6nh\xebjP\x9f\x12v\x92#\xd3\x08\xb3\xa5\xe7\xe7^1\x16\x9c\x05\x8fq\xcc*7\xcf\x0c\x8cc\x80\x9e\x141+\xdd.M\xfcXOl\xffx\xcdk\xc8\x01<\xde4\xc2\x12}5l5y\xb6\xf5\xdby_\xaf\xae:\x14\xecuN\x1f8s\x93)\xdd\xc2&T\xf0c\xbd\x80\xac\x8b\x08\x8a \'Jo\x9f[9\x98\xf2K0l\x8bj\xb2y\x86Em1\x07m\xe8\xfb|\xf9\x87\xcar\xa3qf5\xcd\x86h"(\x94j\xa8>7*\xc1\xb0\x1b\x1f\xc0O[\xe6\x04\xfb\xce\x8e&\xbb$Cv\xec\xdb\xfc\x80\x99\xde\xbey\x8aD\xac\x89&\xfc$E?\x19\xbc\xd2\x18\x8e\xe1\x89\xc4\xd5N\xf7\x16\xa6\xfe\\:y\xe0%.Z\x18\xa2\xed\x0c)$\x85\x88]\x98\r\xf7l\xcb\x84w\x88\x0f-\x8bRKX\x08\xa7\xde\xeak\t\x11^\xaa\'X\x06Bx\xa0\x03\xd4C\xfd\xf0"\xfa\xd8L)\xfd\xf7\xd2\xf4\xad\x1b\x1dE\xa0A\xda$\xd7\x81\x0f\xe0\xf3Y_\xd8\xe9\xb9\x0b\xd0\xf2\xa8g\xe4\xab2\xe0\x8d5:\xd2&\x05/+\xa9\xa5\x01\xb1a\x02\x87\xeeN\xca\x0b\x8e\xf1\x8f\xe6\x15\xe7v\x87|\x93u\xd2\x94i\xa3\x87\xb7\xe7t\xa4Gd3\x000G6\xd2Y\xa0C\x86]\xae8x\x0c\x15\x9e5\x0b\xad\x16\xb5u\xa9\xb4\xc0q\xd7\x1f>\xab\xa5\x89K\x8fC4\xcf\xa1\x8d|\x0fR\xbc\xd6b\x0b\xe2\xcf\x05\xb5Q\\\xc5\x87sM\x82\xba\xc9\xe0\x8b\xc0\xbe(@Ki\xaf\xc3/\xcc\x91\xc8\x81}\xa6\xd7\x0b\x88m\xe5>\xdfy\xe4\x12\x03\xcfV_\x1ag\x1e\xa8\xd6\xde\r\\?u\xbf{\xa7\xe8\x90\xb1\xa2+l|]\xc98\x07S6\xd6e\xf5\x12@\x1a\xc4\xe5\xad\xdc\xf2\xb26\x1bV\x9dCi\x1b\xd3a>\xb1\xe7\x11r:\xc9\xc5z\xb7\xac\xfezf+\xce\\\xdd4Wm\xbd\x03!\n\xf7w\xd4\xdeh|\x9a\x16\xcf\xceb\xf30~@\xb3\x0f\x86\x95\x0e\x03\x1b\x9e\xf2t\x98\xda\xbc1N\x83\xe1\xde\xeb(\x10\xb8\xd7\xe9\xfd\x81\'\xb0\x02\xd8\xb3\xcd&V\x8a\xf9\x8d\x98C\xd7\x85\x8f\x0c]|\x12\xf4qc0\xd1c\xc8kj\x88\xe8\xb2\xea\xd5\x10M\x00\x1f\xb6\xb5\x02\n:\xe03c\xef\xd9\x1f\xfa65o\x02\xa8\x18Xl\xeat\x9e\xf3/\x97\xef\x81~\x0f6\x1d\xf4@\x06\t\xd2\xde\x01\xcb\xf7\xeb\xa6\x81\xc8Qv\xa4\xd3.\xbcT\xb4q\xaf\x8a\xfd\xe6\xb3h9TY\x9c\x99\xad\x1c\xc3I\xf0\xbb;\x8b\x81\x9d\x889\xb0\x19\x00,\x9c\n7%&\x96\xfa\xc67\xa9\xe6\xa4Ar(\xc4\x103\x92/e\xd5\xe82t\xa3\x9fh\x08\x87\xec\xc3k\xc3,\xb0;B8tX!\xe2\xe6\xf6\x1c\xa1\xca\xe7\xe1\x1b\x8b\x80\xde\\\x83\x00\x0c4\xd9\x97\x90\xc9mb\x1c\xe8\xb3iy\x85ED+\x12\x8d\xbe\xbb\xee\xc6\x1aI\xfb\xe5\njE5\x99\xd3fXI\xbd\xc9\xfd\xf7h\x03\xa8\xf4\xba\xbd7\'\xfc\xf08\xb8en0\xaci3\xf1\x1f}\xc4\xeem\xfd\x97PJ\xdf\xe2\xb1D\xcf\x01%\xb0\x1a\xcb|n3\xe9L\xdf\xef[\xa0\'^\x8f\xb3\x86\xee\xf1o%<g|A\xe5\xc9\xb7_*\x0bc\xfe\xef\xe2\xfe"\xc8\roX\xe1zC\n\xb4`\x13\x18\x1d\x01\x19\xe9\xb4\x7f\\\xfb\x1d\xdb\xc6 \t2\x17o\x01f\x0e\xa8"\xad\xcb\xb3k\xd0\xe0Q\xa5A\x9d\x87\x96\xdbUX\x80\xacu>*\xaeU\x03\x9e\xd8{V\xe1\xd8j\x05\xf2a\xd5\xc3\x0f\xfdp4\x80mH\xae\xac@\x17I\x0c#\xac\x84\xdd5\xf3\x0f \xb7\xce\xbap\xa9\x9ay\x8e\x81\xea_\x1bA\x9be/\xa1C8\xd4\xd4\xadnp~E\xa32\x9f\xaa\xc43\xcf\x08\xac\x05\x82\x9e\x87v\xee\x86_f\xd0\x0f\xf55\xd4\xafn\xacu\xe3\x8b\xc8\xb0e\x19F\xbeD"\'rf\x9e.\xde\xb7\xa7\xfb\xabA\xab\x01\xef\x98\x91\x95\xbd\xf7\xe9\xd1\xfb\xb5\xa8o\xaa\xbd\xa1\xe8\xb6\x14l\x84\xd2\xfb:\x0e\x06_H\x97\xf5\x83\x03\x9b\xc7f1\xea\xd0\x1f\xa1\x82n\x8d\x05\x15\xdbT\xa5\x80\xd7x\xa3N"[\xbd<Z\x8f\x10O\\\xc7\x08\x1d\xf8X$\xea\xe6\xce\xf4\xa9MzQ\x16\xba<v\xde\xbc\x9b\xb6\xf7\x10\x81\x89\xb4\x8e\xc4\x1a\xd1\xc0\xda\x0e~cLA1\xe1c\xfa\x7f\xea\xdck\xf9\n\t$\x15P\xad\xa3i {\x1c2Hm\x03\x01k _\xcc3\x89\xa6n\xc3\xa1\x8b\xb5\xf0IG\x89 \xabZ\xf1\x073\x0b\x1d\x02\xfb\xb4\xf0\xe6\x95\xe7\x1f\xd3t\r\x99Ke_\x01c\x82\x8a\x1a\xe8\x11\xa8\xbf\x89:\x98@n|w\xc2%\x18\xd9\xfd\x89,\xf4\xdc\x01s=;\xe4\xb3\xb5\xea\x12\x05\xb4\x00\xac\xd4\xf9\xe5\x94\xad\xaf\xc1\xede\x9c\xe2\xe7\x07\xc2\x8a\xb9\x15%a\xe2\x9f\x9aL\x13\xb7\xb9\xbe\xda7[\x15\x88\xb4\xc9"Kb\xde\x17\xed\x0c\xafZ\x0f\xd1r\xdf\xe9\xf3s\xed\xca\xf9\x1b\xb3\nN\xd8\x95\x87K\x19\xc8_\x8a\xa7\x8d\xac\xf0\x81\xf7<\xf6\x00\xf3\xff\x96\xb4\xd3\xac\xae>]-\x9b\x8d\xecJ$\r\xf3\xa9\xc3\xc7\xcf\xa09\xf8\x02\xa2t\x83\x8a\xd4n^5\x04/\x04]\x19\xaey\xf3\x7f\x03\x88{\x91\x9ejD\xe0\xc7\x8fP\x95\x9b\xf8\x91t\x9b\n\ni\xa5\xb6\x02\xaf\xe8\xfd\xc3\x94?j\xdc\xc0-\xe4\xdc\xed<8M\xcb\xaa\xba\x8e\xeb\x0b\xa2 \xb4\xff\x14\x7f\xa3N\xe8]\x9f\x04\x8b\xc7\xa2\xe9\x15\xd2<\x12$E\x82hXg\x9b\x04\x11N\x91\xf0\x8e(\xe6\xd1\xe3\xb7c[\xc4\x81\t\xe9\xf3z.\xde\xcb\x96\xac+\xe4\x7f2\xfb*\xac0\xa9\x82\xbd\xfc.\xdc%\x9bn\xf6\xb5\xae.\x98\xae\x15\xb7\xa0Z\xe5$\x07\x02\xaed\xd3\t\tp\xfe\x06\xd6\xa2\xd5\x85\x19A:\x18\\\x15\xef\xcbU\xbb-\xc9D\x89c\x9fU\xbe\x8d\xb1\x85\xafG\x9fgy\xba\x8a\xc3\xc9A\x08i\x94\xf2[\xf4\x00\xae\x97VK\xd9\xb6\x03=\xbdp\x10\rY\x92X\x18\xb3|\n\xdddi\x1b\\\xa9\xec\x10Nx^\x06p\x04O\x15\xe6\xa3\xd7D.\xb3\xa8\xfb \x14\xc8o\x15\xccD\xf6\xd4\xf94|+0\x9c\xf7EP\xf6\xa3m>\xdb\xd2\xd1}\x90\xd5&E`D\xcf(\xaf\\\x916@\xa8$\x90\x95\xc1\x19\x0c!\xe4:\x85\tz\x00\xde\x01S|,h4u\x87G\xf0|\x18\x8f\x9b{P\xcc@\xbd>\xb3QGn\xc9d8\xedq\x0e\xd5\xb7\xd4\x8a~<\xbd\xe3K\x877\xa2C-UK=\x1d\x81\x9c~\xa6b,\xb1\xbeV\x84\x07\x82\xe7\x8b\xeb\x08\x19k\x833E\xcf\x1b\x14\x8c 3)\xbfx\xfd\x08!\n\xc0g\xe0P\xael4W\xdbqt\xc5\xe4\xa8\x1efN\x0b8\x13`\x0bqj(\xcbr1b\x91\xfa\x04\x8a\xbcnqY\xdfq\xad|\xb0rP\xf0*\xc9j\x91v\xf2\x148\x03\x1bkU\xe5\x90\x85\xf1\x8b\xd3\xc3,\xc5;I\xd1\x92\xa4=\xdfSc~+J\x17H\x81fV\xf4\xa2_x\xfc\x08\xb7\xd4n\xb4\xadz\x91\x96El\xaa\x8f\xb2`\x8a\x01\xdb\x01PF\xc48\xeb\x8e\xce\xb1\xeb\xb6\xdd,\xf4<\xd3f\xc0H\xec\x8b<:m\xff\xa4\x1b\xa5Y$\xc8UP~\x82\xc6\x06\xff\xfc\xf5n\xa3A\xb3\x8b\xcbU<\xb3\xb6\xd5V^[FtUe\x13x\xb2\xad\x13\x9d\xaa\x16\x96\xa5b\xb9["3\x03`4\x18\xc3WQVe\xcc\xd5\xd9\x04\xea\xe9u\xcd\xdf\xb1\x1f\xa1d\xb0\x92\xae\xb3\x11\xcfZGg\xe9]\xeeQ7\x13\xa4v\x9f\xcf\xa9\xbd\x0f?\xf1\xe0c9C`\x08\x8d\xc0B/\x9fP)\xe7%\xf5\xd2LW\xb9#\xc3%\xbcb\n\xb7#\x00\x8cm#)\xd1\x0b\xb0\'\x15\x18S\xc6\x07Dj\xc2\x82\xa4$\x80\xfc\xcb\xed\n\xa7Dw\x08\xd3!\x86\x06L\x0b\x18\x9c5\xcb0\xbc\xf9_\xf0\xf8h\xf6$\xef\xc3\xf5)\xad\xb2\xd9\xecXx\x86S\xa1\xc0C\x96-\x93S\x0e\xca\xf3e\xeb\xb4_\xae\xa5\x9e\x86\x8c\xbf\xc6\xae\x91\xb1\xd9\xe7\x05>\xaciN\xa0R\x14\x0eQ\x196G\x90\x1e/\\c75\xe1\xd5\x1f\xd9\xd5\xa2k\x8cRG\x1a\xa2\x19\x19\xd4\xad<\xa9J\x0f69l\xab\xd0\xe6\xdf\x046 \xd0\x01\xb0A\x03\x00\xc2\x8a\x0e')
|
1
|
+
from flask_admin.contrib import sqla
|
2
|
+
from hiddifypanel.panel.database import db
|
3
|
+
from wtforms.validators import Regexp
|
4
|
+
from hiddifypanel.models import *
|
5
|
+
from wtforms.validators import Regexp, ValidationError
|
6
|
+
from .adminlte import AdminLTEModelView
|
7
|
+
from flask_babelex import gettext as __
|
8
|
+
from flask_babelex import lazy_gettext as _
|
9
|
+
from hiddifypanel.panel import hiddify
|
10
|
+
from flask import Markup
|
11
|
+
from flask import Flask
|
12
|
+
from flask_sqlalchemy import SQLAlchemy
|
13
|
+
from flask_admin import Admin
|
14
|
+
from flask_admin.contrib.sqla import ModelView
|
15
|
+
from wtforms import SelectMultipleField
|
16
|
+
|
17
|
+
|
18
|
+
from wtforms.widgets import ListWidget, CheckboxInput
|
19
|
+
from sqlalchemy.orm import backref
|
20
|
+
# Define a custom field type for the related domains
|
21
|
+
from flask_admin.form.fields import Select2TagsField,Select2Field
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
class ChildAdmin(AdminLTEModelView):
|
26
|
+
column_hide_backrefs = False
|
27
|
+
|
28
|
+
list_template = 'model/domain_list.html'
|
29
|
+
# edit_modal = True
|
30
|
+
# form_overrides = {'work_with': Select2Field}
|
31
|
+
|
32
|
+
column_descriptions = dict(
|
33
|
+
domain=_("domain.description"),
|
34
|
+
show_domains=_('You can select the configs with which domains show be shown in the user area. If you select all, automatically, all the new domains will be added for each users.')
|
35
|
+
# current_usage_GB="in GB"
|
36
|
+
)
|
37
|
+
|
38
|
+
# create_modal = True
|
39
|
+
can_export = False
|
40
|
+
form_widget_args={'show_domains':{'class':'form-control ltr'}}
|
41
|
+
form_args = {
|
42
|
+
|
43
|
+
'domain': {
|
44
|
+
'validators': [Regexp(r'^([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})$', message=__("Should be a valid domain"))]
|
45
|
+
},
|
46
|
+
|
47
|
+
}
|
48
|
+
column_list = ["domain","show_domains_list"]
|
49
|
+
# column_editable_list=["domain"]
|
50
|
+
# column_filters=["domain","mode"]
|
51
|
+
# form_excluded_columns=['work_with']
|
52
|
+
column_searchable_list = ["domain"]
|
53
|
+
column_labels = {
|
54
|
+
"domain": _("domain.domain"),
|
55
|
+
# "mode": _("domain.mode"),
|
56
|
+
|
57
|
+
'show_domains':_('Show Domains'),
|
58
|
+
'show_domains_list':_('Show Domains')
|
59
|
+
}
|
60
|
+
|
61
|
+
form_columns=['domain','show_domains']
|
62
|
+
|
63
|
+
def _domain_admin_link(view, context, model, name):
|
64
|
+
admin_link = f'https://{model.domain}{hiddify.get_admin_path()}'
|
65
|
+
return Markup(f'<div class="btn-group"><a href="{admin_link}" class="btn btn-xs btn-secondary">'+_("admin link")+f'</a><a href="{admin_link}" class="btn btn-xs btn-info ltr" target="_blank">{model.domain}</a></div>')
|
66
|
+
|
67
|
+
def _domain_ip(view, context, model, name):
|
68
|
+
dip = hiddify.get_domain_ip(model.domain)
|
69
|
+
myip = hiddify.get_ip(4)
|
70
|
+
if myip == dip and model.mode == DomainType.direct:
|
71
|
+
badge_type = ''
|
72
|
+
elif dip and model.mode != DomainType.direct and myip != dip:
|
73
|
+
badge_type = 'warning'
|
74
|
+
else:
|
75
|
+
badge_type = 'danger'
|
76
|
+
return Markup(f'<span class="badge badge-{badge_type}">{dip}</span>')
|
77
|
+
def _show_domains(view, context, model, name):
|
78
|
+
# return Markup(f'<span class="badge badge-{badge_type}">{dip}</span>')
|
79
|
+
res=""
|
80
|
+
for d in model.show_domains:
|
81
|
+
res+=f'<span class="badge">{d.domain}</span>'
|
82
|
+
return Markup(res)
|
83
|
+
|
84
|
+
column_formatters = {
|
85
|
+
# 'domain_ip': _domain_ip,
|
86
|
+
'domain': _domain_admin_link,
|
87
|
+
'show_domains_list': _show_domains
|
88
|
+
}
|
89
|
+
|
90
|
+
def search_placeholder(self):
|
91
|
+
return f"{_('search')} {_('domain.domain')}"
|
92
|
+
|
93
|
+
# def on_form_prefill(self, form, id):
|
94
|
+
# Get the Domain object being edited
|
95
|
+
# domain = self.session.query(Domain).get(id)
|
96
|
+
|
97
|
+
# Pre-select the related domains in the checkbox list
|
98
|
+
# form.show_domains = [d.id for d in Domain.query.all()]
|
99
|
+
|
100
|
+
|
101
|
+
def on_model_change(self, form, model, is_created):
|
102
|
+
model.domain = model.domain.lower()
|
103
|
+
|
104
|
+
|
105
|
+
dip = hiddify.get_domain_ip(model.domain)
|
106
|
+
if dip == None:
|
107
|
+
raise ValidationError(
|
108
|
+
_("Domain can not be resolved! there is a problem in your domain"))
|
109
|
+
if not hiddify.check_connection_for_domain(model.domain):
|
110
|
+
raise ValidationError(
|
111
|
+
_("Domain is not correctly mapped to this server!"))
|
112
|
+
print(model.show_domains)
|
113
|
+
if len(model.show_domains)==Domain.query.count():
|
114
|
+
model.show_domains=[]
|
115
|
+
|
116
|
+
hiddify.flash_config_success(restart_mode='apply', domain_changed=True)
|
117
|
+
|
118
|
+
|
119
|
+
def on_model_delete(self, model):
|
120
|
+
if len(ParentDomain.query.all()) <= 1:
|
121
|
+
raise ValidationError(f"at least one domain should exist")
|
122
|
+
hiddify.flash_config_success(restart_mode='apply', domain_changed=True)
|
4
123
|
#واقعا برای 5 دلار میخوای کرک میکنی؟ حاجی ارزش وقت خودت بیشتره
|
5
124
|
#Email hiddify@gmail.com for free permium version. Do not crack this cheap product
|
@@ -1,5 +1,55 @@
|
|
1
|
-
|
2
|
-
from
|
3
|
-
|
4
|
-
|
1
|
+
from flask_admin.contrib import sqla
|
2
|
+
from hiddifypanel.panel.database import db
|
3
|
+
from hiddifypanel.models import ConfigEnum
|
4
|
+
from wtforms.validators import Regexp,ValidationError
|
5
|
+
import re
|
6
|
+
import uuid
|
7
|
+
from .adminlte import AdminLTEModelView
|
8
|
+
class ConfigAdmin(AdminLTEModelView):
|
9
|
+
can_export = True
|
10
|
+
column_default_sort=('category',False)
|
11
|
+
column_display_pk = True
|
12
|
+
can_delete = False
|
13
|
+
can_create = False
|
14
|
+
column_editable_list=["value"]
|
15
|
+
column_searchable_list=["key","value"]
|
16
|
+
form_widget_args = {
|
17
|
+
'description': {
|
18
|
+
'readonly': True
|
19
|
+
},
|
20
|
+
}
|
21
|
+
def on_model_change(self, form, model, is_created):
|
22
|
+
if model.key==ConfigEnum.db_version:
|
23
|
+
raise ValidationError('DB version can not be changed')
|
24
|
+
# if model.key==ConfigEnum.decoy_domain:
|
25
|
+
# if not re.match("http(s|)://([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})/?", model.value):
|
26
|
+
# raise ValidationError('Invalid address: e.g., https://www.wikipedia.org/')
|
27
|
+
if model.key in [ConfigEnum.admin_secret,ConfigEnum.ssfaketls_secret]:
|
28
|
+
if not re.match("^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$", model.value):
|
29
|
+
raise ValidationError('Invalid UUID e.g.,'+ str(uuid.uuid4()))
|
30
|
+
|
31
|
+
if model.key in [ConfigEnum.telegram_secret]:
|
32
|
+
if not re.match("^[0-9a-fA-F]{32}$", model.value):
|
33
|
+
raise ValidationError('Invalid UUID e.g.,'+ uuid.uuid4().hex)
|
34
|
+
|
35
|
+
if model.key==ConfigEnum.proxy_path:
|
36
|
+
if not re.match("^[a-zA-Z0-9]*$", model.value):
|
37
|
+
raise ValidationError('Invalid path. should be asci string')
|
38
|
+
|
39
|
+
if model.key in [ConfigEnum.tls_ports,ConfigEnum.kcp_ports,ConfigEnum.http_ports]:
|
40
|
+
if not re.match("^(\d,?)*$", model.value):
|
41
|
+
raise ValidationError('Invalid path. should be comma seperated integer e.g., 80,81')
|
42
|
+
|
43
|
+
if model.key==ConfigEnum.http_ports:
|
44
|
+
if "80" not in model.value.split(","):
|
45
|
+
raise ValidationError('Port 80 should always be presented')
|
46
|
+
if model.key==ConfigEnum.tls_ports:
|
47
|
+
if "443" not in model.value.split(","):
|
48
|
+
raise ValidationError('Port 443 should always be presented')
|
49
|
+
|
50
|
+
if "domain" in model.key:
|
51
|
+
if not re.match("^([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})$", model.value):
|
52
|
+
raise ValidationError('Invalid domain: e.g., www.google.com')
|
53
|
+
if len(Domain.query.filter(Domain.domain==model.value).all())>0:
|
54
|
+
raise ValidationError(f"Domain model.value is exist in domains section. Use a fake domain")#واقعا برای 5 دلار میخوای کرک میکنی؟ حاجی ارزش وقت خودت بیشتره
|
5
55
|
#Email hiddify@gmail.com for free permium version. Do not crack this cheap product
|
@@ -1,5 +1,71 @@
|
|
1
|
-
|
2
|
-
from
|
3
|
-
__pyarmor__(__name__, __file__, b'PY000000\x00\x03\n\x00o\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xb6\x11\x00\x00\x12\t\x04\x00mK\xd3p\x12\xbd\xf1\x89\x17\xcb\xea\xc4\xcc\x9a\x82f\x00\x00\x00\x00\x00\x00\x00\x00\xbd\x90\xa2\xe1\xad\x08\x9f/\xaf\x9bQ|A\x07\xf1P\xebH\x9b\xadg^\xf2P\xcc4\x99;E\xa1\x9e\x082\x7f\xb8\xe6\x0cj1\xe2\xcfM\x08\xc8\t\xe9&\x86}\x03\x19-\xfc\xcfBg8\x95N\x1b\x00O\xb1\xa7k\xe8\xfb\xa4>\x804\x03mY\xdc\xb8%\x8d\x04a}*(7\xad*\xaa\xad\xb7\xbe\x07|\xbc\xf8F\xe5N@c4\xbf\x029_$\xa4\xdd\xd7\xd6\x86\x91\xf3\x0fl[h\x17F\xf6\xa1RAo\x87#$\xaf\xad#K\xfc\xad\x8e\xd5\xc6\x02\x16]\x06\xb6Z\x00\x88\xfa\xee\xf2`d\xce$\x89=\xbeV\x9eb.\xccZ\xc8\xe9m\xb9\t>\xf9\xb6\x84C\n<\\\x9d\xa0\'\xf6\x1a\xc5\xa6\xf8\x84\xda\xf7\x0e\xc0\xb5\x15\xe0\x89\xd3+;\xf2\xf0T\x9e7gEk\x1d\xa9,\x82\xcdV\x8a\x1e\x12\xab\xce\xa0\xdc\xacFVa\xc7a\xc1\x19I\xac\x07\xf7\x0c\xe5z\x90\x0b.\x9e\x90\xc8\x19V\xb0\xd2d\x1a^\xf7h\xb9\xfa\x14\xbc\x8b\xec\xc9\x7f\xab j\xa5Cm\x89\x90J\x11w\x80v\x81\xaa\xd6\x1f\xf0!9a$\xa7\xc0\x8a\xbb\xed\xb9\xf7\x9e,P1\xd9\xd3E8\xef\x8a+0\xca\xc5\x86*gC\x87?@\x96\x96-\x9e\xe94\xc5\x10\xce[\xa1\xe3\x8fl\xfc\xf9;\xff\x81\xa4\xa2&@\x89\x97+V\xe6"\x8e~E\xd3\x8cx\xb6\xc3\x1e\xa0\xd1\x02P\xf0}g\xbfs\xcf$\xe1;\xdcpR\x1d\xea\x0e\xe1~\xdbK\x88{\xd9Eyx\xa1-\xe0\x96khuw\xebRf\xf3\x01\x97\x91\x1e\xcb\xfd*\xd3\x8c\xc5-uM\xd6\xbeY\xb7\x97\xfe\x1b\xd9\xee\xc1\xe8\xe0\xa9\x1bl`\x9cZ\xb3\xbe\x814\x90\xe7\x04\xb1\xe4l\xe3*\xaa\x9a\x10\xce\x99<\x01\xbbsz\xf1+\x90\xcd\xc3z\xa0v\xd9u\x8f\xb80\xea}\x07\x93\xcc\xc7\x97%h\xb7QD%\x1cc- 3\xf7w\x98d\xc9\x9bw&\x1b\xe1\n^\x81\x12\x8dfrlc\xae\xaa:\xce\x03\x8a\xc3\xf2\xf5\x12\x06g\x86\xba\x97\xdcg\xea\xdbn:\x19[8{\x1e)7\xacs\x12\x0b\x8e\xb6cX d\x02\x98&\x168\xa1{\x93\x1d\xbf.\xa8\x9e*,V \x1b\x00\x85\xb9\x1b\xe6\xee\x87O\x99e%\x18\x88\x87\'\xdfG0\x93\x9e\x91!\x92\xe1|\xd6A\xed\xcds\x0ei\xee.%\xb4\xd0\xfey\xfbYJ\x84)\x15\xc7&\xd3\xe3\xa0\xde\xc4\xe8B\xc8\x8ac\x17W\x92~t\x9b\xa6\xe6\xd8\x14\x14\xba\xceY>w\xae\xd9\xe9\xaa\x9d\x83gv \x1a\xdb\x19\xc9V\x97X\xa8\xf3\xa1\xdd\xafX\xca\'\xcce\xa6\x80 \xf5\x86\xf09\xd2[;S\xed\xc3\xdb\xf7\x17oj\xfe\xca%\xafK\xb3x\x1aG\xd3=\xea\xd5{\xb9l\xc6\xfe;\x1e\xf9P\x02\xd0C\xf2\x06c\xf4\x1a\x99Y\x85\xa4V\n\na\xbd\xa83\xe6\x7f\x85\xa4r\x12\xaa(\x94\x9eVMP\x19\x85\xa8\xa9I o@\xb1\x1f2\xe0\xb4q$up\xb4Bd-\xe0j-hU\xabE\x95~\xc27\xd1\xb760\x9f\xe2\xcf\x0b\xb1\xac\x8fgv*u\x8b\x94\x0f\x84\xa1\xdaZ\x9e\x8fy\x96iH\x1b\x04\xb8\xa0\xe96\x0f$\xd38B\xc7\x98\x06\x8f\xa3$W(\x02\xd5J\xb4D\x0c6\xd9\xd9D\xcf\xf3\xd7*\x07Y\xc4\xcf\x06\xb9\x1f_M\xec\xa2Vx\xf7z<\xd4sx\xb1\x9c~\x96\xe1\xf60\xe2\xd7\xce\xc9\xd0\xa1\x9dW\xa3f8Z\xc0rGRi\xe1\xff\x14\xe9\x98\x9c\x8b\xe9\xb8,${\xd6\xa1\'\x94\x1ei\x97\xfe\xffC>\x08\x92\xd7\x92%\xe8\x03E\xeb~>$\xddG}\x03\xfd\x88\xef\x0bQ\xa5\x1bl\xa4\x05(C\xb5F!az\x1e;$;\xa2\xbfpp\xb0\xab\xf4\xd8\xbd\x8a\'\xe9lO\xc3g%.2\xafH\xf6\xcd\xc5TT\xd3\xabf\xe8~\xf0\x0b9\x04S>\xb3_U\xf6\xb3\x927I\xa1D\x01\x02\x06+@\xa7M;\xe5u\xdb/\xc4\xdf=u=\x0f1\x7f\xdda\'\x13m(\xcb\xd0\x99\x11\x055\xc1E+~|\xaa\x99RG\xd6WLCY^\xb1L|\xfex\xe9\x91\xe3\x8e\x9bY>\xd3\xe0t\xc8\xfeU\xa0\xc2\x97\x82&+\xd7`\xfe\xef \xe7\xc8K\xe3\xc5\xe2!W`\xa3[\xa9\xe1\xc3~\x08S_\xc1sS\xe5\xb7\x85\xb0\xb9*0\x8a\xa2\xc2\xd2\xfc\xf0\xe1\x94\xdf\xa5\x13k\x88\xec\x1a\x85\xf6#Z3\x8c[\x82\x8b\xb2A\xf6\\\xc3\xdf:\xe3\xf4<\xabI\xdd\xe8\xb2P\x0b$\xf2\x1e\x16Q\x88\xe5D\x93\x9eX}\x1f\x02\xd8Z\xc1\xc7.\x10\x0f\xbe\n\xa4\xcc\xc9\x04\x95B\xe4\x9b&\xc88\x11\x0c,\x87SJ6\xb3N\xf9\x1fd\xbfm\xf6\x00\xb4\x15\x0f?\xbb\xed\xf2\xaa_\x9a\xc5\xe5\xb5\x1fv\xd9S3\xa78\x8ec\x81\xa9|e\x0c\x86\xbbZ\xae\xba\x0e\xe1~\xd35\xa7\xd6W>\xde\x99\xd6\x95h\x0b7P\xf8\x9c\xbeo\x152Z\x90W\xba.E\xf0\xc8\xf1\xaa\x84\x06`,\x83\xe6\xdf\x17\xe6\xc8f!\xf5~\xe0\xb2\xab\xab[~#y\x00\xedg\xde\xd8\xa2\xd0\xe9\xbay\xc1\x94\x16go\x84p\xd5Kn\x13\xaf\x15\xfe\x9c\x85\xa6\x066T\xe9\'\x8f\xd1e\x7f\n\xf7j\x0e\x84\r\x0f^g\x86q\xa0\xc4\x0bK\xf7g\xf1\x01\xc5<\x89=\xae\xf4\x97\xcc\xe7\x02\x848\x99\xd7\x18\x06\x98\x1bW\x18y\xfe-\x89\xc8\xdaI\xbd\x1a\xea\xce\x03\xed\xa9$B\xdab\x14Q\x94x{\xd0\x98\xa63n:\xab\xd7\x9b\x96x#\x81\x10\xc3\x82\xfd\x9d6\xbe\x8c\xe4\xe9\r\xde\x82\x92\xbb\xc7}\xd7\x06\xfb\x0e\xbe\x8b\xb7\xc49\x97xw U\xda\x84\x93\xcf\t\x00\xf0|\xa1y}\xba\x1e\xa8\x1eD\xb9\xbb\xff(M\xaa\x90\x1bv\x89\x14\xd9\tM\xa3\xc4b\xe2\x18D\xa7\xbf\xcf\x81cQ\r\xa4\x8b\x85\xc2T+~\xaf\x1e\xb7\x1e\xf0\x0e\x9e\x1c\x9a\xea2H\xe5\xd6c\xb4x\xac\xe3\xee\xa2\xc3V\xa1?\x8b\xe5\x87\x9eQ\xefY\r\xa00\x8di\x13\xdf\xb4.\x0c]\xfe\xc5x\xec\xd4\xc1\xa9\x00}\xac\xf1\xeb!6\xf4\r\xa9$\xedx\xb7?\xb8\x80\xa6qC"\xca\xbdE\xd0\xe0\xff\xca\x9b\xb5v\xcb\x99\xe4sh\x82\xdfk\xed\x10xU!\xe9}\xa6c\xd8\xf9\xc7z\xa0\xfd\xc8i\xfdgZ\xb9Q\x96\x98\x18\x18fz\x8f^\x19qC\'\x99\xe58\x07D\x7f\x10\x8b\xc5@\xc9\x17A\xf9}P\xda\xdd\x19\xa8%gP\xc3gK;\x10\xb2\x99\xda\xc2\xc8\xe6\xcd\xb6\x9f\xf3v_\x0e\x0b\xf6K\xb5\xebG\xc7x\'\xd7\xb6.r\xcf\xc5.}Z\xa0\xbb\xcf\x1bW\xfdy\xbaV\xb1\x80\xf3,\x89;j\xa0}<3\x05\x0b\x1e\xbd\x06\xaf\xe7\x99\xc0\xe8~\xa3\xe2\xdb\xe0W\\g\xb4\x0cP\xa3\x82\xab\x1b\xbc\x06I4\x1b\xd8\xa2=\xa3\x8d\x01T\xdf\x02F\x19\x96\x1bW\xe4\x8d\x14\xaa\x1c\xb9ds\x9eSys\x94\x80\xf8}\xa1_[\x88&l\xbd\x8eB\\~\x98e\xc8jH\xa7\x16h\xcbP\xd7|\xa1\xd1\xb3\xb3\x0f\x16\xea\x94)\xbb\x1f\xe32.<K4\xb7q/\x94\xdexI}w\x17\xea\xe8\xcf\x1e\xc5t\xe7\xf7\xc9\x1d\xaa\xb2\xd4\x86\x12:\x00\x03q\x97H\x9f\x9c\xc3\xb8\xd4q\xeb\x89\xf5\x1f\xdc\xaa\xd4Mt4\x84\xc3#/\x1d\xc3\xf1\x9e\x14St\r\x93\x07G\x00[g\xee\x86\x97=\xad$q\x1dS=\xde=\xa10\x8cm\xee\xc5%\x03\x8db\xc1\xcc\xcb\x14\x9bY6i\xef\xa9\xb5\xacM\xa1\x1a\xd3\xc5\xa3\x8a&\x7f\x90\x81iL\xcb\xde\xa8\xab\xe8\x92,\x03\xaf\x02$\xf9\x9a\xa2(!\xdf\xeb>\x7fn\xd1\xf3\x94\x85\xc8\xc9o>\xfb\x1fV\x07\x90Y\xf4\xf6\xf6\x81\xed\xf2\xfa\x88\xaeCc\xdb\xa6L\xd1\xadp\xe4}W\x12#3\xe8\xb4\x8f:\x92H\xf5f\x17\x9f\'\xfb\xc8\x0c\xa3\xb9\x8dI$(\x1b\xe6\xa5z\x81\xbf\x12\x16\xe72y!\xd2I4rlR\xcakeOb\xd4\xc2\xaf\xfaE;\xc0\x9b\xe2_\xa4\xfca\xf9\xc5\x81e+\xda\xac\x8a<\x9a\xa5\xce\x85\x15n\xf6\xdd\x06\x85\x01\x8e\xc5\xd4\xa48\xfdz\x17\xee]\x82\x90\x8a\xa7\x98(\xcb$\x07\xa6\x11]\xd1\xbb\xd0~\xa5h\x84\x17&*\x8a\x86*\x88\xe8\x14\x01\xe9\x83\x9b\xa3\xa4-\xd1\x7f\xb7,\xa3\x84\x92?\x8f\xa90cH\xc5\xb0?j\xfe\x88x\x1f5\xa8\xe7\xa1j\xb8^\xf0e:\xba\'v5\x10\xbb\xc0\xe6\x17t\xe68\xf4\x96o\x84\xf5\\>\xe2\x8dS\xe4&o\xe6F$\xd4\xb9\xe9\x86km\x81\xcf\xb9\xf0m~t"\xac\x02\xfc\xe2\xaa\xe7\x92~\xe9>6\x91\x1b\xa8\xdfID\r\xc6V\xc2\xedg?`\xf8\x85$$\x14|\xe1x:x\x94w\x8d\xa7\xb6|\x05\xac\xf1\xed\xef\xe1\x81s\xe8\x1c\x01\xb5\x86u\xf2bt\xc8\x86\\\xe3?\xd4vru4\x13w\x81\xac\x93.\x0b0\xfby\xf9[\x84\xc5!\xd4\x86\xc4\xba\xdf^P!H[\xe6\xd4N:ce\x0fY\xc2\xef\xc6\xba\x9bJ\xa9\x17h{\xc97?\xea\x9c">\x10\x85,\xdbh\xf8S\xff\xc4\xe1\xddz\x8e6wI\x01?\xbb\xba\x85|\x02\xb6\x8d\x13\xd1\xc0\xbeU\x8e\x95\x95\xfe\xad\x15\x96\xaf\x05,5[!\x9f\xb0x\x0e\xb6=W\xee\x05}\xe7\x86[\rt\xe5xs\x8cG\xd0\xf2\xef\xa6{\x8a\xe1?.\x98\xae\xb9\x97\x9dT\n\xae\xb5\xd7\xbcJ\x8d;v\xa1[\x00\xe5=\xe1\x1f\xa6\xc7\xff\xd7\xb7\xea\x0e\xfd6\xc7B\x96\x0f\xedQw:~NI\xde\xd8[\x86R\xec\x8d\x1e\xbaK\xa9\x0c\xaa\xe3\x16\xa2\xe7\x9c\xc5\x0f\xde\xea\x13%\xe1l\xa1\x01\x16\xe4<\x11\x11\xd5\xfe\xc2p\xc6b76\xb2\xca\x17+\xf6\xc6\xd7\x8f\xa24_0\xca\x17\x11\xe2\xf8\xc5\x05\x08\xca\xb0e\xc6]\xe1\x89%\x1cw (\x1d\x980{!bJm\x8dd\xf1\xb6\xba\xf4\x0f\xe2\xecF\xbb\xfb\xaf\xa2\x83\x11#v\xe5\xd6\xc6Q\x0e\xdd~\x1bA\xf42{Q\xb3\xa7[w\x8a"]\xfew4\xad\xe2s\xb9\xeb\x9b)\xc5oP"rCN@\x0c\x9e\xfb\x81a\ruw\xe0\x03\x06\x8e\x8b\x83\xe3\xa4\xbf\'i\'\x95\xd1\xc2\xbcZ}\xd1\x96J/#w\x1awqv\xc0\xfe]\x08\x9c\xc4\x1aT\xd5\xcc\xa4\x8a\xdf\x1f6\x9bZ\xf6z\xbf\xe2&\x92\xb5\xf0\x00\xb6\x9a\xc9P\xc2\'\x86\x92\xc3-\xfc\xff\x88\x91\xd4v=U\xfe\xd0\x03B\xae\xe97c\x85\x19\x12Q\xc3\xef\xb6\x03\xf18R\xa8\x1dG=\xc7G:\x0c\x88\xce$\xdd\x1bv\xb6Z\xaf\xc3\x94\xc4}#\xa7\x03\xa3x\t\x18\xe2\x9f\xbav\x05\xc7-\x08%\xbf\x0c6\xbdS\xfcp@"\xe0T\x1e\n e\xb1\xb6\x9e\xa7E\x82\xd0\x92\xd6m\xd9\xe7M\x0e\xf8\xff"\x01\xdc\xff\xa7K\xa5@\x9c\xf5Q\xc9\xce\xba\xad\x8b\xcf\xe1\xcfsx\xf51\xd6\xdd\x1d\x87~\'\xb1Ra)\xdb\xfb\xc4\x01\xef\x9c\xbeT^\xabr\xfc\xd2G\x8da8\x88@\xbc\xd7/\x05\x1b\x08\x9a\x04S\'\x9d\xe9)\xe0<Ew\x83x5P\x15\x16\xd6\xe3z\x8cuf\x9c\xf7\xa2$\xc9\xcdx\xd4\x9c\xed!\xfc\'\x9b\xb5\x15I6K\xee\x9a\x8b72\xf2\xbc\x95m*\x7f\x15\xe0\xaa\xb2S\xcf\xc7\xad\xc5n\xd9\xcb\xc1\xdeD\xdd\x06Z\xee\xa9\xcd\x8c\xb9\x10\x96*Sw\x93b\xbe\r\xa2R\x1dW\xb3q\x9e\xf6\xf4\xf0\xb0\xfa\x9d\x80+\xb30\x03\xa6\xae\xa9*h\x92K.\x16]\x85\xc4\'\x80\xa4/\xce\xa3\xfa\xacL\xd2\xc2A:\xc4\xf0\xea\x9c\xe5\xb8]\xc9\xf3\xe9\xe2[\x05J\xee\xb7\xa2\xae\x9c\xd8\xe4\xd2s?>\x84+\xab\x84B\xb68F\x8fM\xff\xfem\xb3:j8\xec$\xd1/\xacI\x10\xde\xca\x93\x93y\x1f\xe2\x1d\xb4GG0_\x17\xbf\x1d\xc6y\xb7\\\xcb\xfa\x02\xb7\xe9\xa7\x9a\xf8\xf3\x87$l\x98\xf7"y\r:+\xda\x8f\xd5\xdb\x1e\xe7\xca\x19\x1cL\x00\x9a\xb0\x87nq\xd5\xed\xcc33\x00\xb8\xa7o\xa3\xcd\x1b\xf1\xdc\x10\x97\x9c\x12\xbbpl\x13\xcc#\xa8\x806\x80n\xe2\xe5\xe4\x81\xaa\x8b=y\x8cAgh\x80\x8e\x807l\x87o.\xfe6\xcc\xb9\x9c|\x000\xd8\x82\xeajw<\xf5\x15\xf7\x7fi<\x1bA(|\xe9\xe7a\x10Wr\xe0<\xf6\xc7> \xa5U\xc4w\x12\xa8/\x85\xbenPE\n\x81!\x93\xaa\xac\x04@S\x9a\xa9W\xbe\x1b\x88/m\x8b\x7f\'YO\x8a\xe5\xbb\x1c%\x10 A\xc4\xcd\x94?\x8c\xfc"\x8foe\xc1\x01\xa3\x94\xb1\xa3;]\xae\x06\xf7\xab\x91\xdcJ\xbd\x0f \xd6b#9\xd3\x9e\xd9;\x96\x1b\x112u\xd4\xb7A\xf5\xb6\x97\xdb\xe1\x069i\x96B:\xb2\xde\x02t>0\xd7\xd5\xf8K?\xac\xeaZ\xf3\x15\x98\x1d\xb8N\x9bBaH[5\x05\x9bl\xb5\xd7\xfa\x87=tZx\xc8\xf5\xea\xaa6\xdbY\x19\xf0\x0b\xaeD\xf3<\x00\'$y\xd6;\xc6\x93\xc3?\xc0\xcc+\xbd%\x1d\x06\xf4\xb6\xcf2[\xf0m\xfeo\x03\xee\xd6\x89Y\xd5\x13\xfb\x1c\x8c\x0bb7\x8ckm\xc3\xfa\x91\x99\xd4\x02\xf2\x9dB4ji\x89\xdf\x0b\xed\xcd\xdcj[\x85hZ}\x16\x14FlZ\xcf\x1d\xcd>\xd4\xab\xc3\x8f\xb5\xa62x|a\xaa\xc5\xe4M\x8e-\xe4p:C(\xaf\xd8G\x14\xa4\xaaq\xd8\x9d\x9e\xa3\xe1\xa1\xe7-[\x1d\xd7]\xc5\x95\xb3\x8c\x12"\x8e\xdf3[\x1dY\x98Jq\xf2-\x86>^v\xe0\xc5\\\xba\x00\xe34\xe0\xa8\xc3\x9f\x0c;\x1f\xb8>\xb7K#Z\xef\xc0!\x01j\x19\xee\x1dL\x8f\xaa\xb1\x1c\xb2\xf1\xf1O3\xda\x11\xd3\xbd\x1e\xf3\xedPg\x02\x0c\xe0=\xef\x96\x05@\xc5K\xda\xcaW\xdd\xa6\xbd\x98\xc3\x9dP\xc7N%|2\x08\xb6T(5\x15\xb2\xb4\xdf.\xa15\xb5`\xbd\'`\xc3\x8c\xff\'\x94\xa8\xce\xa4F?F_\xd1z(\xa3r\xe8\xa7\xa5\x95&\xe1\xcc\xe9\xd6.\x1eO\x9c\xf3}\xbd\x86\xc7\xaf\xd8\x890\x13\x15\xf1v\xa8\xe7\xfc\xad-\xc0.\x0e^y\x0b\xac\xd1\x1a\xd0\x8eW\x03\xe1{\xedf\xf1\xe6\xe8:\x12LT\xedz\xc7L{\xf9\xff\xb9\xd8h\xba\t\xaf\xc3H\xee\x11\xeb\x8fP\xac|\x95\xcd\x18g_\r\x0c\xd7\x1ca\xc4\xba\xee\x1a?\x93W=Y\xbc\x81\x941\xdb\x7f\xc6X:j\xae\xed\xdb\xa7\xdc{\xa9\rN\\\xed4\xdd\x1b\xc1TF\x03;\x96{u\x9f\xcf\x92\x03\xe3\r\x03C\xfd\x95}\xa8f\xdc\x11\xb5\x02\xffVXy\xb6^n]06R\xcc8\xf1\xa2\x14C3\x96\xc6d\xe7~d\x97\x925\xf2\xf47\x9f>0L\xafK\xfe%u\x80\xe96\xe0\xd6\xdfCmfo\xfb\x9f\x86\xabC\xfd\xe7\x86\xdc5\x83L\x83\xb30\xf4\\A\xe4PT\x12\x16z\x18\xb6E\xffG\x1d\xc9\x15+\x82\xa3\xfd\x01a\xbc\xd5\xd3\xc8IX>q\xe1>\'Jn\xce\xca\x83p}9\xce\xe3\x9fi\xde\xfa\x9a\xf4\x9a\x88u\x9c\xff\xa1\xda9_\xff\xfd\x8e\xf6\x12\x1aX\xc5\x00`q\xe4>\xce\xc9\xb8\x86\x1ee\xbb\xbfG\xca\xdbq\xc4\x95\xa5\xcf\x85\xe6\xc0?\xa7U\xd6Y\xaac\xb0\xc9\xfd\xdc\x89\x91\x8a\xf1G\x0c\xd7\x05^\x10\xe2z\x0f\xfe\xeaVK\xdb\xa2"7T\xc8\xb1\xa6,S\xcaM\x06Z\xc4b~0\x7f?g\xcc\xd5\x97\xe5U\x10=\x1f\xb6HB\x0e\x90\xabBV\x16\xf5\xf49\x80\x04\x1c\xd3\xc6s\xaaj\x8a\x14)^\x94\x1b\xab\xea\xae\xd0r\x0f\xfd\xbb\x03\x15\xffD\xc6\x17\xfar\x1e9\xe4h>|,\xf6\xc3\x9e\x1f\x01\x0bt\xbd\xc2[\t\xac\xdd\x19H]\xbf\xad.\x0ex4\xaf\xc4@\xe1\x07?\xf1\x98\x99\x8c\xfc\x99\x88<\xee\xac\xd1\xb8\xea\xc8Qv+`\xb1J\xc6\xf3\xac\x07\x90~\xc7MG\x81\xe2K\x8cR-\xab\x06\xf4:f\x06\\.\xda1E\x83\x1b\x9b<#\\F3\xf5Rp\x8e\xe0\x05S\x89\xd5\xbf\x04\xb4\xdf\xd2\xca\xfa\xf3pOS\xaa7A\x88\xaaG!#\xe5\xd2\x1a\xd1\xb0\xd2C\x0e\x10\x17\x89\xc0oC\xe3T\x94\x99\xd8\xc3\xa1H\xb6\x16\x7fg)\\w\xe5<\n\x8bn\x97\x91\x19\xc0\xb1L\xf5\xba\xc2\xf6\xd64H\xf5xC\x084!I\xbe\xe6\xa5`M\x1c\xdc\xe4~\xd2\x8a\xf4\xc4\x07U\x8f\x90\x7f\x0c\x9d\xe2\xff\x8eGKe\xcbl\xbd\x8d\xbe\x12#n\x1d\xd4DG\x03\xa6\xf6L\x86\xa6"\x83\xbf\xc67\x1a\xd4\xef*[y\xb4R\x14B\xada\xf7Qj\\,a\xa7\xeb\x1aw\x7f\xb3\x06\xaai4(+\xa0\x91I\xe7\x19H\xa2\xca^f\x13X\x08\xe1\xf5\xcb{\xa1/\xf4PMw\xdd\xd5\x90\x18A\r\xc6\x9d\x9dDWV\xa5\x8bM[\x89^\x0eCva\xd9\x14y\n\xb9\x12\xdfM\x9d_h31\xfb00P\x84(\xd6E\xce\x9bfk\x9a\x08$R\xc2\x0b\x9b\xb0\x1e\x9a\xe3\xc5i\x8e<?\xdc\xe6}\xaf\xb4\xf2Z\xf2\xc38\xa1T\xfd\xeam\t;\xc4u?\x10L5f\x02f@yz\x96\xbd%x|\xb4L~6FHE4U\xce\xe9#|\xa2\x18\xa9\xbc\xcb\x1d\x9e\xfdL\r\x93\x0b<\xe2\x1b\x05a\x81l[\xfa\xb4\x89\xaa\'\x91\x1b\x1f\xe1Iu\xfc\x8e\x00\xa1\x82sP\xbc4\xac\xba\xe0(\xa7\x18\x1apY4\xaf\xb8S&d\xe5\x1d\x10\xd8K\xfb\xbd\x96\xf1JG\xc5\x81\xebu\xed\xf4\xa8~\x98R\xfa\x93\xecB\x7f\x07 \x86r\xb1a\xa6\xca_iZ\x0b\x87\xa6\x8c\\VT\xfc\xbb\x86\x88q\x9d1}\xa7\xd1\xd7\x0e\x82\xd5:\xbc\xe1\xb0\x89w\xe8k\xaaM6)\xb7\n\xe6\x8f\xb8\xd4.\xd1#\x08\x02\x8a\x05\x85o6\x08:WAc7\xfe\xa6\xeb\xe3\xffq\x8d\x0b\xa0{\x07@9\xed\xf5-\xc1\xd2R\xec\x12,\xaf\xd6\xf4\xf5\x9f\xfd\xd7\xa8HmrJ\xe5\xac\xa1\xcc\x96\x15_pSf\x93\x94~Z\xd3\x9e\xc2\x9a-q\xc4\xdd\xe2J\xaa9{A\xfbM\xe6\x9a\xbb\x89\xcd\xb5\xd2\x00\x0ex\x95UG\x8d]B\xd0{F\x92\x1b9\xf7\x8c\t\xe2G\x88\xe0\x07\x03\x04\xe7\xdc\xb3\xf1\xd6\xe53\x97g\xdb\x80 \x0e\x19D}\xd1\xcf\x86\x8f\xb8nW\x81p\xc9\x18z(\xf8\xeb}\xde\xaa\x90\x1c\xd5\xc6\x95\xd2\xada)\n\xb90<\x03y\xcb\x12\xcf\xf9b\xb9\xed\xe97\xe9\xad\xbc7\x07Q_\x8d\x9a\x1d\xe8\x85\x1a\r\xeb\xe1\xb1#\x9c)\xe0}4\xcc\xe1jW\xc3\xaa\x87(!\xc2@\x92NK\xd4eH\xbf7T\x06\xf2N\x1a\xe8@J\xe9\xbd\xc1\xb5\x9d\xff\xbb')
|
4
|
-
|
1
|
+
from flask_admin.base import AdminIndexView,expose
|
2
|
+
from hiddifypanel.panel.hiddify import admin
|
3
|
+
from flask import render_template,url_for,Markup,request,jsonify
|
4
|
+
from flask_babelex import lazy_gettext as _
|
5
|
+
from hiddifypanel.panel import hiddify
|
6
|
+
import datetime
|
7
|
+
from flask_classful import FlaskView,route
|
8
|
+
from hiddifypanel.models import *
|
9
|
+
from hiddifypanel.panel.database import db
|
10
|
+
from hiddifypanel.panel.hiddify import flash
|
11
|
+
class Dashboard(FlaskView):
|
12
|
+
def get_data(self):
|
13
|
+
h24=datetime.datetime.now()-datetime.timedelta(days=1)
|
14
|
+
return jsonify(dict(
|
15
|
+
onlines=User.query.filter(User.last_online>h24).count(),
|
16
|
+
total_users=User.query.count(),
|
17
|
+
stats={'system':hiddify.system_stats(), 'top5':hiddify.top_processes()},
|
18
|
+
usage_history=get_daily_usage_stats()
|
19
|
+
))
|
20
|
+
|
21
|
+
def index(self):
|
22
|
+
|
23
|
+
bot=None
|
24
|
+
# if hconfig(ConfigEnum.license):
|
25
|
+
from hiddifypanel.panel.commercial.telegrambot import bot
|
26
|
+
|
27
|
+
if hconfig(ConfigEnum.is_parent):
|
28
|
+
childs=Child.query.filter(Child.id!=0).all()
|
29
|
+
for c in childs:
|
30
|
+
c.is_active=False
|
31
|
+
for d in c.domains:
|
32
|
+
if d.mode==DomainType.fake:continue
|
33
|
+
remote=f"https://{d.domain}/{hconfig(ConfigEnum.proxy_path,c.id)}/{hconfig(ConfigEnum.admin_secret,c.id)}"
|
34
|
+
d.is_active= hiddify.check_connection_to_remote(remote)
|
35
|
+
if d.is_active:
|
36
|
+
c.is_active=True
|
37
|
+
|
38
|
+
return render_template('parent_dash.html',childs=childs,bot=bot)
|
39
|
+
# try:
|
40
|
+
def_user=None if len(User.query.all())>1 else User.query.filter(User.name=='default').first()
|
41
|
+
domains=get_panel_domains()
|
42
|
+
sslip_domains=[d.domain for d in domains if "sslip.io" in d.domain]
|
43
|
+
|
44
|
+
if def_user and sslip_domains:
|
45
|
+
quick_setup=url_for("admin.QuickSetup:index")
|
46
|
+
flash((_('It seems that you have not setup the system completely. <a class="btn btn-success" href="%(quick_setup)s">Click here</a> to complete setup.',quick_setup=quick_setup)),'warning')
|
47
|
+
elif len(sslip_domains):
|
48
|
+
flash((_('It seems that you are using default domain (%(domain)s) which is not recommended.',domain=sslip_domains[0])),'warning')
|
49
|
+
elif def_user:
|
50
|
+
d=domains[0]
|
51
|
+
u=def_user.uuid
|
52
|
+
flash((_('It seems that you have not created any users yet. Default user link: %(default_link)s',default_link=hiddify.get_user_link(u,d))),'secondary')
|
53
|
+
|
54
|
+
# except:
|
55
|
+
# flash((_('Error!!!')),'info')
|
56
|
+
h24=datetime.datetime.now()-datetime.timedelta(days=1)
|
57
|
+
onlines=User.query.filter(User.last_online>h24).count()
|
58
|
+
total=User.query.count()
|
59
|
+
|
60
|
+
stats={'system':hiddify.system_stats(), 'top5':hiddify.top_processes()}
|
61
|
+
return render_template('index.html',onlines=onlines,total_users=total,bot=bot,stats=stats,usage_history=get_daily_usage_stats())
|
62
|
+
|
63
|
+
@route('remove_child', methods=['POST'])
|
64
|
+
def remove_child(self):
|
65
|
+
child_id=request.form['child_id']
|
66
|
+
child=Child.query.filter(Child.id==child_id).first()
|
67
|
+
db.session.delete(child)
|
68
|
+
db.session.commit()
|
69
|
+
flash(_("child has been removed!"), "success")
|
70
|
+
return self.index()#واقعا برای 5 دلار میخوای کرک میکنی؟ حاجی ارزش وقت خودت بیشتره
|
5
71
|
#Email hiddify@gmail.com for free permium version. Do not crack this cheap product
|
@@ -1,5 +1,196 @@
|
|
1
|
-
|
2
|
-
from
|
3
|
-
__pyarmor__(__name__, __file__, b'PY000000\x00\x03\n\x00o\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xe3\x1f\x00\x00\x12\t\x04\x00L\xf2\x9f\xf9\xe8&\x8b}MR\xc1lc\x04\x92u\x00\x00\x00\x00\x00\x00\x00\x00\xd1n\xf2\x88\x05\xd9\xed\r\xdbn\xb3#\x02\x89\r\xf9\t,\x07\x1c\xb0\x89\xf9M\xb7P;Q\xa5\x1e\x82\'\x8a.\xf3\xd0\x86t\xacsfF\xed#\xf7~K\xf0/\xcc\xa0\xb1\xafT\xbb\x10\x12\xa0\x98\x177\x8e\x9d2\x7f\xc2\xd4tYH\xad\x16wj#\xbe\x8c!@\x9d\xd4\xb4\xc5G\xc9\x95\r}\x96\xc3\xae\xad\x93v0\xd2\xf8\x82{\x93S\xd7\x94K\xfa\xf5m=\xab~\xf4:\t3\x9b\xf2\x17\x1b5\xcb\x86\x96\'`\x84\x8a\xb9\xcb\x9b%\x86r\xb4~C\xd3U5o4\'nm,\xde\xd3\xeb\xe5`\xc1\xe3k\xb4r\xb9t\x161\x87h\x90^XK\xe6;\xe4\xd6;\xd3\x9f\xb1\x98t"\xbd\xf9\xa1e\xd9n\xf6\x0bBf\x14L\x96\xc8\xb7\x05\xdf\xceO?\xf5\x91\x1d"\x10\xe1{\xf1\xb9W\xae/\xf1L\xff\x7f\xe7:y\xef\xca\x86\x19\x10\x032\xa2F\xe2\x9e\xdf\x99\x88\x18xMD\xc2\xdeb\xbb\xa3\x8b\xb7\xf0\xff\x04\x19<\xfeQ\xaf\x97] m\xd5\x85\xb5f\xb9:,l\xbd\x91\x10\x1b\x921D\xcb\xe7\x0b\xe6\xc2J\x0ey\x16a\xaa\xb7\x93B\xe0?\x9f0:!{\xde%\x9e\xa0/\xed)&\xb2\x10ZO\x05\xf6\xd2\ns\x9c_m\x13]h:Kg\xbc\xe6[f/W\xba"\xbc\xb2~m\xf2e\xfe\x02Q&9z\x1fH\xa2\x97\xfa\xa0\x16\xe1%\xef\x08\xe3\x1d\xd9\x96\xdb\xecC\xb1L4\x078C\x14\n\x83\xbe\x17\xc616\xdd\xc7\x81\x1d\x03E\xb8\xcfM\x10\x1f\xcd\xbc \xdb\xe7\xbf/\xc5\x80+3\x7fe\xb3\xd5<\x137\x88\x16Hg\xbe\xf3\x83\xb6zX\xeb\xbcMWE\xc2\xeeiOO\xa8\xee\xe1\x10\xf3\xcc\x95d:U\xed\x89\xd3e\xd2w\xb4M"\x8c\x8c\'\xefl\xebw\x07~_\xe8\x14\xf5RI\x1a\x8b\x88\xfed\xf3\x1b\xcd\xed\xd7}\nqWk-\xec}\xfa\x073\xb4\xd6O\xc6LB\x06\xbb5,!B\x8c\xdfi\xcb\xd4v\xd9\xee>\x17Ix\x9f\xd75\xfa\x8f\xdd\x9e6\xa8\xc6+&\x85\xf3ox\x1d\x1bT\x9e\x8c\x98\x8d\x06\xf3\xfa\xd3\\\xbc\xfe+\x1a\xc3\x85`\x94Ae\xb6\x03\xf5\xc0e\xd6=\xff\xffC\xd7!h\xa4\x82Y\xd1\x8aP\xe9hx\t\x8d%\xc7\x14\xd1,d\xd0\xe5\xd1v\xab>w\xa2(\x97p<\x12\xb66\xfb\x1d\x10o\x80a\xce!\xbd.,\xbah%~\x17K$\xfb\x93\x05zbO\x166\xe1\xad\x96,Ipt\xa2B=qU\xaa\xc8\xde\xa9\x9a\xdb\x19\xcc{\xab\xb0\x97\xad\x1fzKeG\xda\\6D%#\x1e\t@\xff\x83w\x7f\x12\x99\xdb\xf6hC\xe5H\xea\xe1^e\xeae\x11\x19\xfb\xd7\xd0\xbd\xe2\xc5\xe8\x1aV9.`DgL\x15\xda2q\xc3\xd6V\xb8\x8e\xcbn8Z\x84&\x90tj\x88\xbe\xdaF\xa3\x91\x05\x81\x1a\x8cl6\x82\xc7\x06[9\x9c\x93,\xc2\x97Z\xf9l6\x88\xdf\xb6P\xce\x16\xb1\x1b\xaa[\x8eX\xfb\xb4\x9aM\x9f\x92\xab\x80t\x99\xdfV]G*\xbf\xadDE?mo\xd4\xbce\xcc\xd5vT\xf2\xd9bYb|g\xff\xc8/k&\xe5as%\xfe\x89\xc9du\'&EI\xa4\xe0\xe2\xce\xba\x04"\xc0y\x9f\xd3:%\xf5\xfc\x19\xe2\xac\x87wl\xe7G\x1eE\x94>\xcb\t\xce\x8b$\xf7\xd1\xf6\xfb<\xe6\x05@\xbdQ \xae\xc19\x9c|\x9d\x8b\xa8#\xb6\xbe\x99>\x18u\xb54p\xcf\xd2"\xb8\x7f\xea\xb6nR\xfdJzl\x02Vx-\xed\xb4\xa1\xc6\x9a\xf3\xd8_\x1b^\x8c\xd3\x1d1\'\x918\x96\xcb\xd6\xb6\x18w\x9deZ\xd3\xe2O\xb7\xf1\x8f\xa5| W\x98No\x1bU\xdf,\xe2\xcan\xb3\xe5T\xba\x9e4k\xf3jRs\x91DPb\x1c\x01\x16\xa8\n\x86\xde\x86\xddGN\nj\xc1Y`\x11\xe0\x08\x99\xc40\xbd\t\xa7]\x1b\x02K]%3\x89\xfe\xce\x00\x82GH\x89\x1eV-\xe0c\x84`\xfb8\xd3w\\\xc20\x1cfp\xd7\x83A\xee_\xb9\xac\xa2<\xbb\xe9\x94\xdbl`el{\x85\xeb \x07lUu0\x1a`?e\x0e\x83\x15\xea\xc7\xe7\xa1U}\xd3\xbf\xd0\x83\xec\x03\xaahCk\x02_W(E\x01\xbc\x02\xa2\xca\xec(\x82K\xeeZ\x7f\x8b\x8f\x17\xe7\x8fO\xe9=@\xd3\xebJ"\xec\xe1P\xda\xf4\xa6\xa9y\xd3-\xbd:\x98V#\x89\xc6\xb4\x9d\xf2Ea7)T\xac\x99:\xc6\r\xdaJ(:\xc1\x11\x07\x07r\x95\x0eN\xfce\x0b\x93C\xda\x12\xea$\x10X5\xe9\xecW;\x01\x9a\x11\xa7\x11L\x029D\xa6\xba\x08~\xdf\x0b\xeco\x08\xf1\xb3C\xdaB*\n\x8d\xc4\x05\xce\xa8\xead\xeb\x89\xf9\xfc_\xf5\n\xab\x8b\xf8\x0f\x1b\xeaN\xbd\xd7\x84w;\xd6\x1d\x16\xdd\x1d\x1d\xb4 \n\x94.\x80O\xd5p\xa0c\xc5_\x0f\xd46\xab`7\xe8\xff\x14A\xfa\x0f!\x94HR\x0e\xcc\x01\x01\x12\x95n\x8c\xc5\rX\x10\xc9yI\xbew\x89\xea\x1e:\xfa\xbc\x1e\x9aO\xa1\xe9\x00\xe4\x88\x87V\xb0G~d\xd2A\xbaGD\xf3\x13\xca\xd5\xb2Y\x81`\xbc\x0b\x01O-XE\xf9B\xb3\xfc)\xde\xcd\x11=\x05;\xcf\x95\x86&a\xa2\xa9Z#\x00\x13\x96\x9a\x93D\xcc\x18\x9d;\xde\x15\xd3JT_n\xfe\xc2H\xaeU\x10\xfc\xfcTu\xe4\xe6\x0e\xd4\xc0#\xbb?\xd3\xb9\x81\xfa\xdf\xa0\x8d*\x0fQ\x9a\xf7r\xcc\x9f\x8e\xd0\x9cyL\xf4\xaeA\xde\xdfH\xe6z\x8a\xf0\xa3\xc6\x08\xa4\x87LT8\x84rY\x84\x8f\xd2\xb2\x0f\xado\xdb\x1e]\xa2\x8e\x1c\x90]\xaaOv\x8f\x9b\xd6\xdc\xa3`\xa9\x19\xdbpe\xcc\x16&\x98]\xe2,\x07q\xf0\x00\x96lSh\x86\x84\xc2E\x19\xc4z\xceE\xc9\xf9o\xfb\x8aG\xe8[\x85\xdf.4\x89P\xe0\xb7+!\x1b\xa9\xce\xf4\x866\xde\xfd\xc0vn\x0c\xce\xf4\x11>\xdb]\x05$>DR\xb0\xa7n0\xf8\xa1\xda\x02\xf1=\xb0V\xbdDh\x95(w\xeb}\xd5=\xd9\x9f?\xb8U\xceB\xbc\xde\xf5P\xcc\xb1\x90\x85\x95\x17YBxn\x9f\xd5\xfc\xa9k@\x9b\xae\xbcE\x8e\xa8VUQ\xf0~\xbeq6&\xb8+\x93\xce\xe0e\x08ZW\x8b\x17V6\xc4K\xb1\x0c\x1d\x8bS\x0f\xb1\xedM<\xb3\x87\xc7\xdb\x1eH\xb2\x9c^\x8b\x969\xe5\xb8\x02j\x99h\x1b\xbfh4\xd9\x89R\xda\xeay\xa5<\xa3n\xa8ZR\xaa\x11\x1f\xa2q-v\x9b\x9b`\x18\\\x19H\xf8\x1c\xf8\xa8\x13\xe6\x08\\Jle\x0c\x82YD\xcc%"\xd7\xa5\x9e\xb3\xd9)&^\xcd\x81\r\x19\xc9y~\xff\xf9cH>\xe1\x13,d\x8dM\xd6\xa7\xe3\xb9\x7f\x84\x14M\xa9\x97N\xb9\\T\xeb\xf4\xefS\x00q\xce\xd9\xe3\xc1t|z\xd8Ltc\x14\x00v\xb4C\xefdJ:k\xb3.\xb3\x04&\xcc\x85\xfa\xf8\t|v\xb5~r?\x13\x1a\xb0\xcc\x13-\x93\x83\x99\xef\x88x\xa3\x17|\xc9q\xf7\xe7{\xfa\xdc@\x9f$r\xb2\x88:\x99\xb3\xc0\x18)\xde\xdc\xc0\t\xa4\x06\xe9&\x0f]M\x019\x93n\xba\xe6\xab\xb9\x04\x9f\xfaN\xc6\xc7\xf2.\xb8\xe0\x89k\x00\xad\x96\x95\r(,\xf0\xfd\xebZ\xcdF\x881\xba\xe9\xf2*ft\x12\xd8\x1b\x99W\x1f]#\xa76C\x067\xba\xa9\x8b\xf5}\xc4\xdc@>\xd3\xb7\xc5K\x08\xb4\xb2\xdc=\xb5\x96n\xcb\xc8i\xa2\x10\x8e\x83\xe1x\x0e\xa1X~\xfd\xbbnH\xbc\x92.\x1eG\x9d_\x1e\x0el\xbc\xfcr+e\xad\xbb\xf8`\xf6)\xdf\x92~\xa5v`\x0c\xad\xf3m\x98\x04(a\xa2}\xb6O\xdf\'\xfa\xe0\xea\x85!T\x15\xf9\xc7\xd5FQ\xf2\xeaAx\xd6\xdc\xe8\xe7\xc3\xacu&\xae\xf6\xb5\xe6\xab#\xdb\xc0\xc4\x08\x19g\x91\xe2\xd6Bts\x10\xef\x9bg;\xb7\xc2\xf6E\xb3\x13\xfd\xad\xbfZ\xdc\x89r\xbe.5\n\xc3\x01\xf8WX\r\xa52\xa7P\x17\x13M\xd2\x99L\x8d\xb0\xfdS>\x9c~\xa645\x84\xdf\xc1/\xaf\xb6ZHh\xcb\xf5o8\x82\x17\x1c\x80\xc4\xff\x95$>\x8b\xf5\xfbZ\xcc*\xab\xf7\x1c\x99^\xaa\xccSEj\xef\x9c\x0c\x043hW\xe0L\xee\xcea\xf5I\x97\xb7Rj\xeb\xfb\xfd\xbav\x80\xd6\xb0mT\xd9\xd9\x11\xe9(\xcb\x98!\x1e]\x914G\x07\xfa\xcahf\x17g\xff\x1d\xcah\x1d\xf25\xbc\xb5#J\xb7UE\x12c\x11]E\x05 \x19\xc5{z\xd2n\x19\xadX\xe8\x8c9\xc46R\x88c\x88\r@\x0c\x96q\xcf\x05)X\xea\xce\x90\xc6{\x01\x7f\xc6\x92\xa8\x10F|\xfb\xd8\xfc\xffBc\x90\'\xf1\xf1\x13\x1a\x8e?\xc3vO\xdeG57[\xb1\x14\xbe\x99(\x1e%\xca(\'\xbe#<\xac\x8c\xbe\xd2u\xc4\xa9\x07\xa9\xf6\xa5W\x1c9\xc2q\xb3\xd6\xe8\xc0\xc0\xf42oXx\xcd\xe3\xea75\xfah]Sb\xee\xb4\xd5\x8fk\x17\xba\x8a\x96\x8d\xe0\x86\xdc\x8a\xec\x08\xf7,\xbbOS@7ue\xac\xbc\x9f\xf62\xe5\x9b\x00L\xc2u\x90\x8dK\x03%\xf7T\xa5F\x86\xf3\x9a\xf4\xe2\xc5\x87V\xc4\xb9\x03c\x9f!#\r}\xd66-\xc4\xab&\xa6\xda\x19{g\x0fE\x0eS]4A\xfam(\xd0\x8a\xd5\x11\x9c\xf0\x88\xabWU\x11\\\x89\x93)Z\x100=\xb2\x92[\xef\xad\x8d\xa8\xfa\x06)\x92\xed\x0e\xc4\x82\xe1\x8cK\xa2\x1e\xa7\xe3a\xa9|\x17QT8\xd6OEf\x86\xcdT}\xdb\xa2M1\xbf\x9e\xc0\xfe\xfa=\x87gx\'\xa0\xfe\xaess\x83~7m$\x88ta\xe6M[\x8a\x1b\xf9\x88\x97\x85\xc7\xee~\xf7\x84\x8f\xa3\x11L\xde>7\xf9\xf9FD+#:\xa4\x10\xc3o\xd7\x90\xb2V\xeb=\xbb\x8f\x91\xd2\xad@\x1a\x84\xf0\x95\xb9\xd6\xcd\xce\xe2\xfb~\x80r\xccO\xfa%v_\xf4\xe4\n\xd7\x93\xb0\xd5qo\xf49\xce3\xca\x86\xc8\xe1\xbb\xdd\xf2t\xfdt\x99 \x87=f\x12(\xed\x87\x19\xff\xc4\x88X_\xd4U8 \xbb\xf0(\x1cJa\\\x87^\xf8\x80p\'R\x98?I\xa3q\xbb\xb9\x17\x03*\xf2\xd1\x88\x88X\x825\xeft\x94\xbf\xa1f\xfd\xd7\xd7\x97\xc2\xf6\xe4\xdf\xbc\x92l\xfd\xc6\xc5k\xd9|y\xa9\xa9"\n\xdd\xbd\x85\xa6\x90\x1ae\x18r\xfa2\xdbw\xf3i`\xee\xa2\xc6\x03\xd7J\x07\x01`s\x1a\x81\x89\x99\x1c&k\x9e-\x88\x1c\xd0\xbf\xae\xfa\xe37\xbb\xd5\x89y\x08\xeb\x05\xcb\xafxw\xd6\x84`j\xe9\xdd9#\x07\xfb\xe0\xb5^\xaa_\x8d(V\x847tdE\x16\x11Z\x0f\x82h\xa4\xf1[Kj\xbc|\xa4R\xee\xb6\x8c4$\x04)\xe8\xb9|\x8d<\xa3 \xe5g?\x9f\xa1\xb2\xf2\x7f\xact\xeb\x0e\xf5\xd7i\x07\xf5^\xc3\x00m\x98\x88\xdb\xc1\xce\x8c\xed\xdd\\cq\xb1\xfa\x1e\xbe\xa9x\xcc\x1cqX\xfc\x02\xff\xb5(\xbdJ\xcdg{\xbd2w\xff\x87\xc1x\xba\x06\xd8\xb4x\x1d\xd3\x95\x945,\xef.d\xf3[\xbc\xeb\x0b8Q\x7f\xaf\xfd+\x1c\x18\x8a\x93"\xc8\xb1\xc6\xb6T\xf3\xe0\xe3\xb5^\x9bp%\xd2\xac\xa2\xf2\x94\x03\t\xb70\xe4\xaegL\xc1If\x96\x08V\xa8\xaf\x01\x9c\x16\xeb=Z\xb0\x80h\x80\xa8T\xc5A\xe8K\xa1K\x11g\xcf\xcd\x8c\xfc\xf8\x8c\x83\xb7OG\xb85\xf2\xeb\x97Z\x82\xf7\xba\x1dCy\xb13\xf3\x911Z\xdd\n\xda\xb6\xcf\xf3\x08\x08e\xd8<\xf6Z\xb1\xb2"]\xc1]?\xacu\xde\x13}k\x1f\xd9\n*\'W\xaa\xc9R)x\x89S\x81\xee\xe4\x00W\x01\x8e\x9b(\x00\xde\xe9y\xa6\xed\xb0\xbc\xb7\x19Z\xd1\x87\xf7|\xb7C\x99\t\xf5B_AS\x16\x89\xc2\xc4OC\x05<\x84\x0b\n\x9a\xd6\x9e5\x00C\xbb!8\xc9\x1a\xad\x94@\x0c\xb7\x19\xbd\x0c\x1c<\xd7\xed{!\xfa\xdeu,\xbc\x18\x8c <y\xa8g\xc3N\x9b\xde{[\xd1#\xfb\x133\xad\xf2\xf2\xd0\xd6\xb4G\xa5\x8d\r\x7f\x9eL\xc1\xc9z\xab3i\x0c~sa\xb7\x9d\xf9\x07\x00>\x02w\xd0\xb3;g?\x8b\x93Y\xab\xc3\xe6G\x9b\xfb\'a\x85$\xe6\x81\x88\xd4\x10\xd5s?\xfd\xcd;\xb1JR\xd2\xcbj\xd4\x19\\\x80\xe2\xcd\xc06\x1ff\xa9\x98\xc1\xc8\x97}Z\xfb\xd9\xf7#\xd7\x8e*(\x9aEh]r\xc7a?\xc7\xf1}\xd2\xaaF\xbf\xf4J\x00\xce=q,\x90x\xebO\xf6\xdd\x0e\xa6\t\x1b\x94\x10\xe9\xdb\xfde\x1fi]\n\x9e\x96G\xb9omC\x81YZ@\xf11\xa1n\x08\xe00:\xcd\nb\xd2\xd8\x16e\xa4\x17\x81\r\xd6f\xd9\x01s\x82Q\xcb|\x94\xcb8^\x14\xfb\t[=\x97\xa1w\x01\xbf\x0e\\\x90`\xa0{#Y\xf2\xe3D\x14\x0fKR\x03\xdd\xa1\xcb[\xb7m$ "\xadTI\xd6\x83\x9ex\xc1b\xea\xe6\x8f\xdb\xa1\xe5|\x07\xb5\x90\x9fv\xfe\xb3Uz\xc8\x8a\x05\x7f\x96\xba?JK\x13\xec\xfex\xf4k\xbf#\xf8\xcc\x03\x8f\x98%:\xfc\x1a\xec\x1d\x1b\xd6Y=\xa9\xe95\x14\xd7\x9e@\xb8\xb9\xd2Po5\x91\xb8z\x06t\x9e*\xa9i\x8e|\x7f;\xa6\xf2~\xf6\xc4\x8b#\x0e\x08\xed\x9a\x89\xfa\xa3\xb56\x0eY\xfa#e5[r]\x95\x95\xab\x0b\xf3s%\xf5\xa5\x8f\xd3]:d2qX\xa3\xd04\x14\xddk\xad\xf7\xdd.D\x86\xf6\xde\xe5,\xa04\xf3\xd2\x8a\x97\x81\xf5\x90-\x9aU\x97i\xf1\x8cC\xd7\xc0\xe2\xf1\xad+\x93;Pa\xb3m{\xad\xc9L\x82v\xc6u\x86\x91\x84\xfd\xdcT\xcc\x96vl\xa7\xd7\xfd\x82\xcb\xc9\x05dR\x80\x91\xf6\xde\xc14"\x86\xdbZIS\xdf\xef\x89\x03$#\x9d\xf3od\x02\xc3)\xd8\x93\xa0\xf2\xc5\xbf5\x90\xb7.#k\xe5\xf9\xa0\xce\xc6\x0b\xbf\x04\xf7\x04\xed*\xf3\x99\xec\xaa\xdb\x8a\x0f\xe76\x9e\xb2\x1b?w\xea>\xe0\xdb\x0e\xd9\xdf\xdc\xae2\xf7\xdbQ\xe9\t\x14\xcd\xe5\xa4x\xae\x9a"\xfa\x00\x83\xe8\xbd1\xd8\x00g!\x93\x895\x91f\xbd\xd2\x1aYE\xfe`\xeb`\xb7\xc9H\xe6\xa3\xca\x1d\x1ed\xe5\x14\x04VK\x06\xff\r\xe59Bc\xbcL\xf9Y5\xf4\x14\x1b\xe9\xa2M7?\x8ahD\xc7T\xf8&\x9a\xdb1\xaaB\xbez\xd1\x83ki,\xbe\xcd&U.\x9c\xa2\xb1\xd5\x1ek\xb4\xe4\xb3\x84X\xee\xc1z\xa2Q\xdc\x84\xa9D-\xdf\x0c`\xe7\x02\x89\xc2Z\x1f\x85\x1e0\xef\n\xb7\x8e\xd2\xae\x05]\xd0\x0fq\xd3\xbf\xb5J\xbb\xb8S\xda\xeeq\xf8\xca\x17\xfd\xd8\xa0\x9a\x12\xeci\xa7\x1a\x88\xd5\x98H\xc0\x1f\x02*\xa2T\x9dq\xdb\xb1o=\x92\xfa\xf6\x0c-\xba\x13|0tS\xa7\x07\xc8\xc8\xe2_k\xc2\xee\x94\xc1D\x84G4\x1d\x95"b\xdfRf\x0c$\xf8A\x16q\x84\xf6UA\xcf\xbb\xc6\x85\x06\x17\xd7\xa4:\x16\x111\xc7.%MES\xf6]^\x14D|5\x12\xc2\x82\x9a\xe6 \xe5\x1d\xc5\xc2\x9b\xc1\x05\x07\xb2/\x07\x9a\xc5\xbd\x8d\xee\xd3\x8eH\x9fW\xdd\xbfG\xd2.\xf8\xda/\xac\xfc\x9f8\xd85\x9c\xb3\xe3\x01\xfbn\x10W\x91\x90\xfeH\x98\xdf\xb6\x8a*U\xfb=\x8bi\xc0\xde\xa6q-\xf6\xf2K\xd1\x01\x0c\x88\x0b\xae\xc1\xa8\x13\xc3i\x9d[\xf1\xef~\xb4\x85\x89nt\xd3g\xda\xd7\xd2\xb0\x04q\x89\xbb\xd8\x99\x96A%\x1f\x85s\xe4\xbe\xb4\xba\xb0\xd7\xfdj\x8e\x86\x96\xa1\xc6\xf2/h\x97|\xe9Cktw,TanHU\x0b0%\x81- \xa0\xcb\xfa\xc1\xf3\xaf\x1c\x95\x97=\xd9\xe5\xe5n\x9f//LO\x90Z\xda\xf0\xa0\x07\x16=\x8f\tp\xc1`\xf8A2\xe0v\xa3l\xfb\x8e\xf7\xc7\xd9l\x8d\xee\xfd\xf6\x11L;C\x93r3;\xc2\x9d\xf6\xc3b\x081\xae\\\xe2\xdcc\xf8\xd5\xa0\x8d\x98\xf0\xbd+\x06\xd9\x1f\xedz@T\x8c\xdb\xc9\xd1\xd9\xc2-\n\x1aS\xad\xb9]s)\x94\x1b\xb9\x17j\xaeO\xa5Ij\xfa\x1e86\x1d\x9a\x13\x99\xa5]\x92\xfb\x98g.R4P\xa1\xf84\xe3\xd8QExsM\xb5C\xf3\x01\xa5\x95\xf1\x7f/6\x07%\n\xb5\xcc\xf8#\xb4\x87\xd5\x89\x00Q\xf4\xc7qw\x94\xf9XR\xdf\xe5SK\x1a\xf6\x1f|\xa1U\x17\x07R\x88F\x04^\xb1\xfa\x80\x87\x1b\x08+\xe5\'x\x87_\xf4T:\x87\xa3\xa7\x0c\x8f\x9dY\xb6\x81\x1e\xd9\xff\x18i\xab\xef\x12\xed\xc4!\xf5\x1c\x17\xac\x9c\xb6\xdb\x15k\xf9\x11\x10\xdaD\x87\x98\x1c\r:\x93l`\x80\x8d\n\xc4\xcd\xf1\xbc\xc1L\x94{\x0f\xf8m\'o\xdb\x04\x01\x04\x94ZN\xb3\x17\x8a\xd9\xd4\xc6Ya\x1c\xe2*\xdd@\x98\xd8\xd9G\xebQ9\x99+\xbd\xd9\x9a^Z)\xa6\xc1\xa1I0\x15\x15\x86"\xb6\x9f$f4\x89\'\xc1f\xea\xde\'\xf9\xae\x95\xd3\xdbGA\x0f\xb6\xa8a)n3/34\xcb\xd0"C\x9f7r.\xea(\xef\xeb\xa7/U\x11M+\xd5\x93\x1f\xa1p/K\xe5\xf8\x9f\x845\x85\xbdS \xde!\x8c?\xdc\x9aY\xf1MO\xda\xb0\xacg\x1cbe7M\xae\xecr\xd2*|\x0cV\xf4S%\x1ci\x99\xcf\x13\xdb\xe9\x7fU\x8cA\r\x91!m\x0b\x96\x1aK+\x14u\xda\xba\x12_\xa9\xf5\xf9\x1e\xfc*\x86i3\xc0\x80W\xdd-\x15X\xcbk{\xf0 \xd3\r\x1dg\xfbs\x93\x85\xb8<h\x8eR\x1d\\?m\x16\x04\xe9\xeaN\x9ch\x984\xa9\xa0g\xd5\xa0R$\x9e@\xd1Tc\xfc\xf5\x18\xdcg\x07k\xbf\xb3\x8aN\xdf\x96\x9f\xb5\xe1\xd7\xb0\xcf\xc7bqz\x07\xac\xd8%w\xe3\xfc%\xbd\x0c\x9a\xda\x19\xd2I7\r\xf3\x82vu\xc9\x9a2?\x84J\x89\x0f\xee\x00\x95\xfd\xd2\xd2\xe2V\xa8z\x04h@\xa2\xae\xd9[\x82\xbdh`_\xed\x03|\x96\xd6\x14B1\x9bR>\xcc\xd2^\x8b\xc4~\x00\xebs\x8a\x0c\r<\x8c\x90\x94\x13\x1aw\xebY\xd6al\x16\xe5\xff<\x82~\xc6\x10M\xddk6\x05\xa5\xdfA\xf9\xa2\xfe;\x9b\xe5\xdd\xd0\x07\xe6\xd7\xd2\xc1zjy\xd1\x97\xb7\x93p\xf84\xa1\xa01\xac\xb35\x9a\x84\xd3\nB\xbb\x0e\x83y\xdfI\xd7\xd4\x18\x04Y\xad\'P\xff\x12$9q\x85\x7fgo\xfd{\xa3\x04[\xec\x1b\xe4P\xc9/fP\x11i\xf8>\xd3\x0eq\xd3\xd9\xb08mW\xecx\xe6K\xd1;\x9e\xcf\'k\xc7$\xfc\xb7%&3\xff\xd1\x9c\xb8\xa6u\xd3\xe1B*zZ:QOD\xc6\xa5vqm~\x80\x00\xb5\xcdQ\xeb\xe2\x8b\x0eW\xa8[a\xac\x95HVEO\xb4\xda:\x94D%B0\x03v\xe0g\t\x08\xfa\xda\xbdz\xb2\xc7\xf9\xe3\xe4\xf8\xb07\x0e\x81\x9f\x05\xba\xfc\x83#K\x19M\x14\xf0(9\xcb\xe6|\x88U\x99SJA?\xf2`\x01r\x8e@\x9b\xd3\x0c\xcc\xd1\x98\xb0\xc9\t1\x18\x92\xe74\x89\xcfXZ\xb6\xbd\xe6\xd1\x17\x1b\x89\x0c6\xf7NW\xcd\xc0f\x87cux}\xe5\x9d\xe4\xa4i\xff\xb7\x83B\xc9z\x84\xc5\xc2\xc2\xe8\x8a\x9a\x15\x90u\xa7AGM\x83\x95\x80\xa6\xfadlz\xfe7GJp\xc9\xd7[\x90\xd4M_\xb6v\x9d\xd3\xfb&\xdcd\x90M{\xed\xfd@\x8d\x1b\xdd\xa7\xa0\xc6MPa\xa9\xb1#lp\xaeLQ}\xb7tl(\x86\x102\xd5h\t(\xd3\xf9??\x9a\x81\xfc\xc6h\xb1n\xf9K\x9a\x8fb\x04\xff\x07\xb7\x13TT^\xbb\xbc\xe6W\xe2\x0f\x06Q\xda\xee\x82\xc3\xc4]^\x14%\xd9&#\x9eah\x85\xc3\xb94\xeb\x03\x18\x82@\r\x9c#\xcd\xa74\x0c$\x06\xd2\xbd\x9dVX\xdb\xaf\x1c#\xed\x8b$\x1e\xff\x8e\xdd\xaa\x93Y\x0f\xd55Iw\xba\x93\xdb%\xe8\xfdkU\xc8Y\x15Vf\xbc\xd7\x17C\x07\x92\xab\x1b\xb5\xcf\xa9a\x7f\xb6Z\x90\xb4\x13\xa5u\x17\xb1I\xec\xe5F\xe0\xe7d\xd8>`\xf3\x15\xfa0P\xd4\r\x13\xb1X\xfa\x0b\xfa\x97J\xac\x9d5\x89t\xc1\xdc\x06R\xef\xe4\x11\xa64\x9c\xa1\x1d\xd4\x16\xed\xcd4\x96\x9c\xdc\xd1\x9f\x1fqV\x0fndC\xe3N#>\xe5\x80\x93\xb3\xb2\xf0V;]\xfdMt\x08\xe9\xba\xfa6HyM*\x9dB3\x89\xe9\xd4*6\xd4\x08\x144\xc3\xdc\x93EYn\xe4u:\xb8\x19\xa5\xfa\xd7\xaf\x87%\xb8\xbd\x81Tv\xe7\xe6\xac*\xfc\x14\xdf<\xa7;\x16R\'@\xf2l\xe4C\xd6M\x99\xcbL(=\xac\xeb\xd5\x9b\x07\xcd\xc2\x8eXA\x82;Y\xf5\xd3\xd669\x06\x9e\x1d\x1eH("\xa7J<\x94\xe5_\x86\xfdT@~\x05C(\x14e.\xe0\xc0K\xc0\x99\xb8kI\xef\xae\x87\xc1E\xeb\xabM\xe6l/rg\x01\x1d\xa1\xab|=\n\x0f\xf3\xa1&\xa5\x12\xd9\x13\x9a\xf9}1\x18\xffb\x8b~\xe0\x84Wr\x9bE\x880\x03z\x0flmJ\xb3\x9aA\xc6 \xe0\xb6\xe6\xfcX\x84\xc2\xfd=\xf0f\x95\xb7g\xd9\x95\xdbK\xacw\x89\x8b\xae\xbe8\xbf\xa7x\xc9\xd7\xc1\x05\xf7c\xac|+\xac\x9b\rrW\x94\xe8\x10\xe2\xcb\x1aE\x0cje!\xe2\xf2\xf9;\x12vr\x9d\xd0\xa0\x12\xb6f\x9b\xab*\xbfq\xbe l\xf6\xa4\x07:hz\x89%=3\x01\xaez`\xfe\xfb,\x95\xa0\xd0,\xc6F\xe3\xdd=RL\x0c\x12Z\xa3~\x93\xed\x18z\xab\xd4\xd5\xe1\xd6\x9a\xd1\x8fn\xde\xa4p\x1a\x04\x8c`\x8a\x1dl\xb0B\xb6\x95^\x900\xb0\xbd\xcb7\x86[\xa7zp\x88\xd4\x10\xfaNs\xe7\xfa\x7f\xc5\x88\xd72MHx`\x9e\xb5\xbf07@\xf3n0O6\xfb6r\x12?\x83@N7\xac\x83t\x99\x82\xa4g\xde\x07\x80\xa1v\x86\xa6\x82\x84\x1a*X\x12\x81E\x84\'\x91\xb1H\x8e\x19g\x852\xa2\xd0B\xfa\xd0\x90\xd2!\xef+\x91\x03\x04\x85=n\xe2\xfd\xa2\xa6#\xeb,\xb1:xd/P\xf0\xe0h\x12u\x8b1f\xe0\xbf\x104\x1f\xcd"BV\xfa\xc2\xfa\x12fFJC\x9a\xacD\x1c%\xbd9\xe2r\xcf\xfa\xea[\r\x9d\xcc=\x19j5\xd4\x1d\xe6\x1d\xa3\x10\x19\xae\xae}E\xdc\xc9#\xd1\xe9\xe7\x9fQ\xff\xb0\xba\x97A\x04C\xa9\xacVK\x81\x9f\xb5\xd6\x8c\xdd\x85\xb9\x96\xa1H29\xfe\x16\x9e\x966lG\xc6j"43\xf8\x05BEqU\xcfs\x17\xd7\xb3\xf8\xec\ns\xad\x7f0\xd6\x96\t\xec\x9b\x8c\xed\x89\x92\xb7\x1e\x97\x8a\xcaGYpkRb*\xb1\x12\x13\x87\x83\xf98\x1d\xa7\x1c\x9b\xc9\xady\xa7\xb4t\xf5\x9a\xd8C-^\xd8\xfd \x7f\rK\xeb_jF=\xe5_Ra\x7f6\xe8\x1a\xf4\x9f.\x05}#\xc4\x1a(\xa4\xd8\xc2e\x9b \xf2\x95\xc5Q\xbc\xd9~\x91\xee\xc0\xdfe=O_\xa2\xf6\x01\x85\xb0v\xbb]\xd6\x1c\x04V\r\x94\tj\\\x8e&\x92SI\x83\x0c\xc0wry\xbf\x9bB\xe6S\r\x11%\xe4\xad\xda\x14\xb94\r}m]\xba\xb6\x82uq\xf5\xf4a\xb7)\x82\xeeL\x8f\x1f\xf3\xfbk}!c\x14,p\x94\x1f\xa0\xbc\xff\x1c\xdf\xbe\r%x\xc8\xcbV3\x0c\x10\xab\xd2\xf3\x19\xfe\x94\xd2\x0c\xdc6\xe4&2\x1f^\xe7\xe4\xa6k\xd82\xe6\xfd\x15\xd0\x85\x8c\xfc\xc2?u+\x9c\xde(\x01\xe1\xe0\xfc}\xa5\xf43\xd59\x17\xb928!_\xb3\xd6\xb6\xf7\xa7\x80\xbb\xa8$/\xb5,\xd5@\xa7y\xbc\xb7\xbfB\x0c\xd4\xa6\xd6\xf9\\\xaa\xcd\xc6Z\xb4\n\xa36\xf0\xbf\x82\xcd\x1ez\xba\xf7/\xd6 RY\xd1\xee\xc7\xe2j\x9f#\xbd\xe3[\xff\xea,Sdr+\x1cp\xea\x92\xf6\x02\xdcUU\x10\xc8\xab\xe5\xe3=\x00h4Q\x9d\xa0\x13\x92\xb1i`H\xe5\xef\xf3IF\xaev*\xeax\x1aa\xcc\x8bJ{\x1b\xa5O\xecfo+CU\xf7N\xea\x1e\xb4\x00/\xc0\x95y!z0\'L\xb1p)Q\xff\x18\xae\x88\xea\x19\x8c\x94\xdf\xce\xafy\xc7\x0c\xd0v\xfao\xf2\xbbt\xf3\x0bG\x1d\xe7\xbbU\xdc\xad\x9b\xe9E\x08\xd7\xe9>\xab\xdcF\x05\xdc\xeeK\x9a\x9f\t&\xb1n!,\x14d\x85\xe4\x0c\x06YC\xa0H\x1b\xdb\x02t#Q\xb5\x8d\x00M(\xaf\xd9\xe3\x82\xabJ?W\xbc\xb4<\xa7\xab\x1c\xbbX=}/\xe1\xfb=\xc9\xb2\xb8\x91.\x92\xc1N:\xa2\x05\xd2\x0f\x7f\x1e\x9e\x07T/\xcaO}\x956\xaa\x8c\x8b\r\x82\xa22\xe6\x9f;KCvFf\x02\xe8\xfb\x1d\xa7\x19rB\xe6LD\x82\xa9\xa3=\xd3\xf6:%\xe9X\x9b.\xecp\xae!\xd8\x83z\xd4\x1a\t\x84\x8bYn\xe8\xdc\xa4\xa7\xab\\\x1b\xe7~j\xe3\x8c\xd8Zt\xb4\xff\x80n\xf9\x15\x05\xca\xb9$\xb8\x82\x06\x83,L\x16\xbf!\xde\x00\x7f\xf2d\xaf\x05(\r\'q\xb8 \x90\x842ZU>\xc0o\x82\xad\x02|\xfe\xfa\xc7\n\xcb\x84\xf3?\x1b\x95djA\x82C\x0bZ>h\x12\x03\xfa\x8e\xd6\x9fS\xac\x95\x1cW\xf5SOU\xad\x94\x80-\xe7Q\xe2\x12P\xf4\xaa\x157\xbe\xf6\xaa\xad:\n;\x99\xd6\xe4\xa5\xeb\xadP\xf9\xbf\xf5\x85!,}\x1f\xd1\xb1E\xe4\xcc\x04\x18\x87\x0e\xb2Y\x8a\x19\x18)\xb5\xbc\xa43\xea?\xc58\x12,\xd7O\x05\xd1\nC\x9c\xb6\x80\xa8\x8c\x81\x93F\x1e\x92&\xf5A>\x14\xdb\x16!xA\xc9#\x91\x82\xe9\xb2\xd4\xed8\x181\xa6\x17\xbe\xd4\x16\x00\xe32z\xf2\x9d\x7f?\xa0\x120,\xd2*\x9f9/\xac\xba\'\xd1\xc8|\xd0\x81\xda\x8c\xed\x83\xab\xde\x9d\xe1=G\xa6\xc9\x134]\x0f\xee$\xf2Jo\x1c\t\xaae\xc3\x8b~\x9cE\xca\xfeV\x11\x07\xea\x08\x19\xf5H\x823\xbe\xb2\x9d\xe7|\xe6>\xb6\x8f\xac\xc2O\x17\xa7\x12i\xa6\xc2\xa1\xf6\xd9R\t\x1a\x0b\x0f\x7f\x9f\xe5\xf4X\xd9\xd8\xfbb@^\x11\x08vZ\xcbU\xdb;\xf35\xbc\x9e\xe4\xacv\xee\xf1P\xb9\x12\xfff\xbc\xc8"Fx\xf4\x05D%\xb3\xa5O\xb2 \xd1\x1dfs-Z\x07\x97oR\x8c\x1a\xb4\xa1\xa25\x0c\xbc\xb4\x98&sW\x8c\xef\x15f\xc2wI\xac\xc5NJ@\xbc\xf3D@\x16\x07*\xd8\xb7:\xc9j\xee\xef\t*\x190\x8fR\x8a@\x13\x8a\x13\xed\xe2\x88\xee\xe6r&\xfd\xd2}\x96Er\xdcw\'\xa4\xdf`x%\x0f\x83\xb0,k3\xfa\xfe\x13\xbes#|V\xec3\xed\xaftv[C \xdei\xbf#\x9eK\xf3\xf78/\x12\x90y.\x9b\x04\x8b\xf0X\xd2"\xe4C+c\xd4\xbe\xc8\x99\x1e\xf6j\xdf\xf0\xc2\xae\xa1\x80\xf4\x8ak\x9d\x85\xfe&I\x8b!\x7f1\x15/\x98\xf3\xd5\x99N\xfb\xde\xd5O>4\x9b\xd3\xdb\xe5rw1OFrA\xe52\x89\xae6I\xd8"\x02\xfbI\xf9\xdbN\xb1\xd5\x80\\in\xe3\x8bn"\x01\xaaS\xa4\r\xa3i\xd5\xee\x02\n\xb4\xd3\xdd\xaf\x12J~\x8cGy\xf2C\xa4H\xabL\xe8\n|+\xde\x13\x8bW1e\xdf\x98\x85\xb2\xcfsJ\xd1n\xdafQ\xc3\x92Q\xf8P{;\xa2.\x0b$k\xc4\xb5U\xc5Q\x8d\xd2\x98\x8a@\xfb\xef\xeb\xb3\xd8\xd0fO \x90\xb9\x8ay\x94M\xac\xc0W\x17)\xc04`\xf4\x18C\xe5\x1cZ\xa8\x9ak\xf6\x86_\xe06\xbb\x87\xa7\xde\xf6\xb1\xff;\x17#\xb8\xbd\xa1\xbe\xf7\x9d\n\x07\xf0\xa56\x97-\xaf\xcf\x15\xdc\xb5\x98\x06\xa2\xa6\x12\xban\x19\x9a3\xc4\xea16\x1d\xdc\xef\x04\xb2\xb3:a\xcd\xbbM\xe3\xa4\xa3\x7f\x8a\x04J[\xc7\x95_W\x9e\xfe\x1b.\xec\x16\xf3\xb5\x96\x88a\xb6\xff\xa7\xfa\xd2r\xa7\x9d4\xccz\xf7\xb8\xf3y\xdc3;\xe67\x97\xb0;\xda\x97\xa4\x11\xee{c1Kr\x92\x00\x88\xff\xa4[\xf4\x1a\x11\xed\xab\x83<\xe8\xa4\xfe{\xa6\xc8c\xff\xa9w+=Bk\xdf\x02(\xe6\x05\x14bo\xba\x82\xac\x8c\x91\xdb\xaa\x99\x00\xf4\xfd\xe7.\xb9=\x123h\x01D\xd8\xcf\xee\xb6\x9e\xfc$\xe6/\xd5\x0fO\xf2\xf7VF\x8e\xa0\xb4-\x88\xf6S/\xd3\x90\xa1\x8f\x99li\x9bu\xb1Y\xc3Y\xaf\xb6\xcfM\xe3\xcaj.*\xa26<\xff\x98\xcbHw1\x98!\x0c}\x02EGK\xcaJ\xe3\xe9A\x07)\xe0\x8ajm\xae}lx\xc0\x9e^\xddt\xf2\xea\x93j\x0b\xab\x1d\xed\xcb;\x03B\xd9#Q\xa8\xf5\xad\x1cQ}\xa74\x1b+\xdd\x9d\x12%\xe7p5\x8c\xff9\x88\x8a\xd1\xb8\xdd\xee\xe6\xef\xd6\xd5\nm\xe0\xa9\xe7\xab\xeb\x84\x16\xd5i\xdd\x85r\x82\xb8\x17Y\x98\xa3\xbd\xbez\xc3\xe1\x93\x00^~\xc1\x8aKi\xa6\x08"\xa0\xd5\xf2\xeb\xb9s\x8f\x8e\xcf\xbfS\x13\xc7\x8652\xec\xe2\xf6}\x9a\xcb\xf05*\xa6e\xbe\x8b0\x04\x11\xf6\xa5\xef\x85\xe2\x83=\xed\xea\x0f\xc1\xac\x866\x10E\xc4)\xce&A\xbc\xb7\xda@MZ\x12\x1b\xf0Pv\x1b\xac\x18\x18\x8cz^\x94\xe1l\xab\xa2PN\xb8y2i4\x9b\xc7\x92\xe3\nF{~]i\x83\xdeR\xea\xb4\nt\xf3*\x86\xd4b?\xd4\x1a\x80\xfd\xa4Js\xbch\x8f\x11%<[\x8e"\xf9\xd0vu\xc2\x11\x848\xd3\xfag\xaa\x96Y\xe0\xb9\xee>\xa9c\xdfg\x01\xe1\xfc}iH\xa5\xf1\xa9\xccL\xdc\x93\x8f}\xfb\xbb\xab\xa6\x1c\xd2\x10\xcf\x8c\x89\x10Cs\xb0\x13\x0e\xfa\xf0\xb0B\xf7~\xc4\xd0\xf5\x85\x01-\x86\xf8\xcc\x8d\x8bt*:\xf3N\x93/<8\x0e\x1a`\xf2,\xab\xad\xa478\x9eYm\x9b\r\x16A\xee\xb6\x1c;\xa9C\xfbs\xd4rx*\x97Ge\x00_\x02\x01\xec\xf6\xfd\x98\x7f4\xf1\xc6f\xc9\x08\x8fl\xf0\x95"\xec\x0133Ms\xb6\xcf\x1e\x1b\xf3m\xf5\xd2\x84\xf1\x1b\xb8\xdf\x11F\x97p\x9e>[\x96\xd1\x97\x84\xc9\xd4\xb2?q}\xe2\xf8\xe7\xe6 \xd9\xdf\xded\xb4G8\x06}\xc4AK\xcd\x19\x93\xa2j\x11c\x93a\xe0\x12\x03A\x18\xe9\xdd\x99\x8a\x13n\x11\xed!;8E\x1b\xe5\xd3\xea\xb1JE\xad\x91TF\x98\x13S\x91\xb2g\xed\xdc\xa2\x84D\xea\xb81l\x94\x90\xb0\xbf(\xe4\xe09~\xd1v\xb3\x7f\xc4\x81\xdd\xea\x8eiH\xd5\x96UY*\x07\x17\x08\xd5\xd3\xba|\xf9\x13\x88j\xb4;\x84\x1c\xb1\xb6\xee\x834`\xc1w\xd6\'\xcf\xa9\x18xTX$\x00\x9fv\x1a\x9e\xa1w~\xee_\x11\xaeGAR\xe7\xb78\xc80\x9f1u8\xa1\xd1\xbc\x00\xe9\xdeH\x08\xa2\x0eA\xa8\x14\x93Vu\x86\xb7\x84\xb9\x0cw\xb3\x88\xd3\x80\x01\x08\xb5\xe5t@}Zr_\xbd\xc1\xf3"0\xc9\xd0\xc2\xff*-\xa9\xcd\xa5y\xc3\xce\x11M4X\xe0\xa8v\xf7\xafxy\xb4\x11\xec\x11\x14\xb1\xd5\xde\xed\x87\xf7\xbe\xb1\x83\xa0\xb4\xf2T\xaf\xf4\xf4F\xef\x1chj\x8d\x91\xd8g\x12\xf10\x8b\x8d\xd3\xd5\xb9[c6_\x81\xb7\xd2\xed}\x8eG1q\x7f\xfd\xe1>PJ8\x90\x90/\x98\x91\xd0W\xf4f\x13B\x96^\xc0\xec\xda\x8e\xef\x19\xa7\x07\xceb\x99\xbe\x94\xaf\xa0UobL\xc1\x0eeo|\xc6\xe1\xbf\x92LS\x82\xbb\x00\x952\x1c(\x9c4\xe0\x1e\x16bq\xf0U-\xb1\xb4\x1b\xb6^\xd6\x03\xa8\x9e\xdf\xab+\xe2\xe1~\x8c\\\xb3"\xb4\xf67\x8a\x9d\x97y\xdb\x8c\xc1\x02\xad>\x15\xb4\x17uN\xf6\xd5\xf9d\xa7\xa7\xb0dQpy\x81\x1fd\x82D\xe0\xfb\xdc\xf9\x06\xee\x98\xd5\x19_\x88`\x96\xe1\xf8\x05\x9e\x90v\xd0i3\xe9\xb8\x15\x1b+\x9f\xb6\xd2\xe3R\xae\xff\x06C\x98\xd7j\x8e\xaf\x8d\x9d\xab]\xe6\x92\x9b\xafx\xba\xe9\x87\xd0\x04\xb7\xec\xc7 \x9e\xf9\xad`\xb6\xb2t\xe3\xeb\x0e\x01s\x9a}\xb8\xbe\x1cI\x12h\xcdo\xdbe\xa7\xc2\x14g\xe2\xb3[\x83\xd6ui$5\x0c-^K\xf4\xed(\x92\x1aHO\xd9\x037\xaf\xbe\xff\x00\xc8/\x8e\xcfj\xb1\x05s\x00$\xbd#Y\r\xc0k\xee\x8c\xc3\x82\xf5\xa2\xc6;J\xba\x87\xa5rB\xc7\xbaJ\xe95\xc5\xcc\x95C\xff2\xcd\xfd\xb78\xa8\xce\xfa\xb335\x86J\x8at|\xbfO-\x00\x87\\\xd4\x06\xdb\xf3\xc2\xfd}\xa6\xbb\xd9\xa3\xb9tj1*\x01\x1c\xb4\xc4\xf3\x19?}\x1b\xae\x98\x02\xb1\xe3\x17\xf9\xe1,\xaa\xa8\x80\x93#\xe4 \xb3\xee\x0e\x05\x87\xddb\xa4&\xf7\x02_a\x07\xef#\x0c\xf8\x08\xb5KD6\x81\x9b\xa83\x88\x84\r\x14\x8dv`C\xe5\xf6\xcaS\xde\x1b\xb5\xbb\xe1\xc9\x8b\x9a\xc0\xf5\xdb[JA\xbfk\x9a|\t\x93/x\t\x9c\xc2p\xc2\xd0\xc4!\xb5w7\t\xce\xf9\xbc{\xb4\xb8I\xd8b\xd5O\xfa:\x03\x06\xd5_\xa5\x96G\x92\x9f\xf9me$\x9e\x0c\xf6\x8f\xef\x0e\xafS\x9a\x87u\xe7[\xe0m\xe2\x7f\xf8zN\x03n\xf7\x01\x02\x0f\xe9\xc8\xb4\xe1\x0c\x15\xab\x9b\x9aO\xf6\x96\xf9*\x89\xf0\x1c)\xa0G\xc3y\x93\xc3\x83WK\xf1\xc8\x9b\x0f\xb4#\x91\xf8\x87\xb8u\x05P\xf0\xee\t\x12\xc2`\xf0\xd4\xdfq"\x1b\xa1\xd5\x1d\r0=#y"\xe3\x06\x19\xf7\x98\x8cp\xc0b\xd4f\xf1\x00\xae^\xeei\x0b\x94\x8dZ\x8e\x02\x8d\xdb9\x98y\x02\xb9\xc7:\xa4\x03H\x05 ss\xd7I$\xcf\xe35"\xf3\x05\xb6\x15|)\x82\x89\x1f\r\xea\xf4\xcc\\9_\x83()\x94\xda3tk"\xc1\xf00[\x06\x93\xc1bw\x96\x92T\xbfQ?\xec\x89\xe3.\xdb\xa1y0\\\x14,\x19R\xb3\x85\xc4\xf5\x89\x1f\xa4\xd4\xc6\x85\xc0\x04\r\xef\x15\xc1\x89\xe63N\xc1N\x1a/\t\x8d\xb7')
|
4
|
-
|
1
|
+
from flask_admin.contrib import sqla
|
2
|
+
from hiddifypanel.panel.database import db
|
3
|
+
from wtforms.validators import Regexp
|
4
|
+
from hiddifypanel.models import *
|
5
|
+
from wtforms.validators import Regexp, ValidationError
|
6
|
+
from .adminlte import AdminLTEModelView
|
7
|
+
from flask_babelex import gettext as __
|
8
|
+
from flask_babelex import lazy_gettext as _
|
9
|
+
from hiddifypanel.panel import hiddify,hiddify_api,cf_api
|
10
|
+
from flask import Markup
|
11
|
+
from flask import Flask,g
|
12
|
+
from flask_sqlalchemy import SQLAlchemy
|
13
|
+
from flask_admin import Admin
|
14
|
+
from flask_admin.contrib.sqla import ModelView
|
15
|
+
from wtforms import SelectMultipleField
|
16
|
+
|
17
|
+
|
18
|
+
from wtforms.widgets import ListWidget, CheckboxInput
|
19
|
+
from sqlalchemy.orm import backref
|
20
|
+
# Define a custom field type for the related domains
|
21
|
+
from flask_admin.form.fields import Select2TagsField,Select2Field
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
class DomainAdmin(AdminLTEModelView):
|
26
|
+
column_hide_backrefs = False
|
27
|
+
|
28
|
+
list_template = 'model/domain_list.html'
|
29
|
+
# edit_modal = True
|
30
|
+
# form_overrides = {'work_with': Select2Field}
|
31
|
+
form_widget_args = {
|
32
|
+
'description': {
|
33
|
+
'rows': 100,
|
34
|
+
'style': 'font-family: monospace; direction:ltr'
|
35
|
+
}
|
36
|
+
}
|
37
|
+
column_descriptions = dict(
|
38
|
+
domain=_("domain.description"),
|
39
|
+
mode=_("Direct mode means you want to use your server directly (for usual use), CDN means that you use your server on behind of a CDN provider."),
|
40
|
+
cdn_ip=_("config.cdn_forced_host.description"),
|
41
|
+
show_domains=_('You can select the configs with which domains show be shown in the user area. If you select all, automatically, all the new domains will be added for each users.'),
|
42
|
+
alias=_('The name shown in the configs for this domain.')
|
43
|
+
)
|
44
|
+
|
45
|
+
# create_modal = True
|
46
|
+
can_export = False
|
47
|
+
form_widget_args={'show_domains':{'class':'form-control ltr'}}
|
48
|
+
form_args = {
|
49
|
+
|
50
|
+
'domain': {
|
51
|
+
'validators': [Regexp(r'^(\*\.)?([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,})$', message=__("Should be a valid domain"))]
|
52
|
+
},
|
53
|
+
"cdn_ip": {
|
54
|
+
'validators': [Regexp(r"(((((25[0-5]|(2[0-4]|1\d|[1-9]|)\d).){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d))|^([A-Za-z0-9\-\.]+\.[a-zA-Z]{2,}))[ \t\n,;]*\w{3}[ \t\n,;]*)*", message=__("Invalid IP or domain"))]
|
55
|
+
}
|
56
|
+
}
|
57
|
+
column_list = ["domain", "mode","alias", "domain_ip", "cdn_ip"]
|
58
|
+
# column_editable_list=["domain"]
|
59
|
+
# column_filters=["domain","mode"]
|
60
|
+
# form_excluded_columns=['work_with']
|
61
|
+
column_searchable_list = ["domain", "mode"]
|
62
|
+
column_labels = {
|
63
|
+
"domain": _("domain.domain"),
|
64
|
+
"mode": _("domain.mode"),
|
65
|
+
"cdn_ip": _("config.cdn_forced_host.label"),
|
66
|
+
'domain_ip': _('domain.ip'),
|
67
|
+
'show_domains':_('Show Domains'),
|
68
|
+
'alias':_('Alias')
|
69
|
+
}
|
70
|
+
|
71
|
+
form_columns=['domain','alias','mode','cdn_ip','show_domains']
|
72
|
+
|
73
|
+
def _domain_admin_link(view, context, model, name):
|
74
|
+
if model.mode==DomainType.fake:
|
75
|
+
return Markup(f"<span class='badge'>{model.domain}</span>")
|
76
|
+
admin_link = f'https://{model.domain}{hiddify.get_admin_path()}'
|
77
|
+
return Markup(f'<div class="btn-group"><a href="{admin_link}" class="btn btn-xs btn-secondary">'+_("admin link")+f'</a><a href="{admin_link}" class="btn btn-xs btn-info ltr" target="_blank">{model.domain}</a></div>')
|
78
|
+
|
79
|
+
def _domain_ip(view, context, model, name):
|
80
|
+
dip = hiddify.get_domain_ip(model.domain)
|
81
|
+
myip = hiddify.get_ip(4)
|
82
|
+
if myip == dip and model.mode == DomainType.direct:
|
83
|
+
badge_type = ''
|
84
|
+
elif dip and model.mode != DomainType.direct and myip != dip:
|
85
|
+
badge_type = 'warning'
|
86
|
+
else:
|
87
|
+
badge_type = 'danger'
|
88
|
+
return Markup(f'<span class="badge badge-{badge_type}">{dip}</span>')
|
89
|
+
column_formatters = {
|
90
|
+
'domain_ip': _domain_ip,
|
91
|
+
'domain': _domain_admin_link
|
92
|
+
}
|
93
|
+
|
94
|
+
def search_placeholder(self):
|
95
|
+
return f"{_('search')} {_('domain.domain')} {_('domain.mode')}"
|
96
|
+
|
97
|
+
# def on_form_prefill(self, form, id):
|
98
|
+
# Get the Domain object being edited
|
99
|
+
# domain = self.session.query(Domain).get(id)
|
100
|
+
|
101
|
+
# Pre-select the related domains in the checkbox list
|
102
|
+
# form.show_domains = [d.id for d in Domain.query.all()]
|
103
|
+
|
104
|
+
|
105
|
+
def on_model_change(self, form, model, is_created):
|
106
|
+
model.domain = model.domain.lower()
|
107
|
+
configs = get_hconfigs()
|
108
|
+
for c in configs:
|
109
|
+
if "domain" in c and ConfigEnum.decoy_domain != c:
|
110
|
+
if model.domain == configs[c]:
|
111
|
+
raise ValidationError(
|
112
|
+
_("You have used this domain in: ")+_(f"config.{c}.label"))
|
113
|
+
myip = hiddify.get_ip(4)
|
114
|
+
|
115
|
+
if "*" in model.domain and model.mode not in [DomainType.cdn,DomainType.auto_cdn_ip]:
|
116
|
+
raise ValidationError(
|
117
|
+
_("Domain can not be resolved! there is a problem in your domain"))
|
118
|
+
|
119
|
+
|
120
|
+
skip_check="*" in model.domain
|
121
|
+
if hconfig(ConfigEnum.cloudflare):
|
122
|
+
try:
|
123
|
+
if model.mode==DomainType.direct:
|
124
|
+
cf_api.add_or_update_domain(model.domain, myip,"A",proxied=False)
|
125
|
+
elif model.mode==DomainType.cdn or model.mode==DomainType.auto_cdn_ip:
|
126
|
+
cf_api.add_or_update_domain(model.domain, myip,"A",proxied=True)
|
127
|
+
skip_check=True
|
128
|
+
except Exception as e:
|
129
|
+
raise e
|
130
|
+
raise ValidationError(_("Can not connect to Cloudflare.")+f' {e}')
|
131
|
+
# elif model.mode==DomainType.auto_cdn_ip:
|
132
|
+
|
133
|
+
# raise ValidationError(_("You have to add your cloudflare api key to use this feature: "))
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
dip = hiddify.get_domain_ip(model.domain)
|
139
|
+
if not skip_check:
|
140
|
+
if dip == None :
|
141
|
+
raise ValidationError(
|
142
|
+
_("Domain can not be resolved! there is a problem in your domain"))
|
143
|
+
|
144
|
+
|
145
|
+
if model.mode == DomainType.direct and (myip != dip and dip != hiddify.get_ip(6)):
|
146
|
+
raise ValidationError(
|
147
|
+
_("Domain IP=%(domain_ip)s is not matched with your ip=%(server_ip)s which is required in direct mode", server_ip=myip, domain_ip=dip))
|
148
|
+
|
149
|
+
if dip == myip and model.mode in [DomainType.cdn, DomainType.relay, DomainType.fake,DomainType.auto_cdn_ip]:
|
150
|
+
raise ValidationError(
|
151
|
+
_("In CDN mode, Domain IP=%(domain_ip)s should be different to your ip=%(server_ip)s", server_ip=myip, domain_ip=dip))
|
152
|
+
|
153
|
+
# if model.mode in [DomainType.ss_faketls, DomainType.telegram_faketls]:
|
154
|
+
# if len(Domain.query.filter(Domain.mode==model.mode and Domain.id!=model.id).all())>0:
|
155
|
+
# ValidationError(f"another {model.mode} is exist")
|
156
|
+
model.domain = model.domain.lower()
|
157
|
+
if model.mode == DomainType.direct and model.cdn_ip:
|
158
|
+
raise ValidationError(
|
159
|
+
f"Specifying CDN IP is only valid for CDN mode")
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
if model.mode == DomainType.fake and not model.cdn_ip:
|
164
|
+
model.cdn_ip = myip
|
165
|
+
|
166
|
+
# if model.mode==DomainType.fake and model.cdn_ip!=myip:
|
167
|
+
# raise ValidationError(f"Specifying CDN IP is only valid for CDN mode")
|
168
|
+
|
169
|
+
# work_with_ids = form.work_with.data
|
170
|
+
# print(work_with_ids)
|
171
|
+
# # Update the many-to-many relationship
|
172
|
+
if len(model.show_domains)==Domain.query.count():
|
173
|
+
model.show_domains=[]
|
174
|
+
# if model.alias and not g.is_commercial:
|
175
|
+
# model.alias= "@hiddify "+model.alias
|
176
|
+
# model.work_with = self.session.query(Domain).filter(
|
177
|
+
# Domain.id.in_(work_with_ids)).all()
|
178
|
+
if is_created or not get_domain(model.domain) :
|
179
|
+
# return hiddify.reinstall_action(complete_install=False, domain_changed=True)
|
180
|
+
hiddify.flash_config_success(restart_mode='apply', domain_changed=True)
|
181
|
+
|
182
|
+
# def after_model_change(self,form, model, is_created):
|
183
|
+
# if model.show_domains.count==0:
|
184
|
+
# db.session.bulk_save_objects(ShowDomain(model.id,model.id))
|
185
|
+
|
186
|
+
def on_model_delete(self, model):
|
187
|
+
if len(Domain.query.all()) <= 1:
|
188
|
+
raise ValidationError(f"at least one domain should exist")
|
189
|
+
hiddify.flash_config_success(restart_mode='apply', domain_changed=True)
|
190
|
+
def after_model_delete(self, model):
|
191
|
+
if hconfig(ConfigEnum.parent_panel):
|
192
|
+
hiddify_api.sync_child_to_parent()
|
193
|
+
def after_model_change(self, form, model, is_created):
|
194
|
+
if hconfig(ConfigEnum.parent_panel):
|
195
|
+
hiddify_api.sync_child_to_parent()#واقعا برای 5 دلار میخوای کرک میکنی؟ حاجی ارزش وقت خودت بیشتره
|
5
196
|
#Email hiddify@gmail.com for free permium version. Do not crack this cheap product
|