hiddifypanel 3.0.0.dev63__cp39-cp39-manylinux2014_x86_64.whl → 3.0.0.dev65__cp39-cp39-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\t\x00a\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xe6\x16\x00\x00\x12\t\x04\x00h#\xcd\x01\x9a\xab9rU\x8dP\x0c\x05q\x82\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x07\x8c\x8e$\xad\xd6\xbabh\xed\xd7\xa0\xdcX}\x98~\x08$\xb9^\x08\xc0KPq\x93\xce-\xc6C2f\xaawa.\x05\xee\x9b\x7f=\x0f\x1d\x88\xd1\xc8\x92\x8b\x92.?\x1e#\xea\xb2\x86J\xf2\xe9\xc0\xa4\xc5\x95H\x0c\xd3en8m\x8e\xca\x1e\xb2\xf0f6SP(qG-\xbah=\x80\x07\x01rD\x9f\xbd\xb5\xed(\xbeulJ\xfb\xb1%_a\xf5\x93\x85\xaeb\xb8oA\x8b\x13\x81-\x84\xf9V\xe9\x87\x86\xda&\xd6\xb6\xa8\x92\xf6\xf4\x95\x0c\x1e\xbcC\x95\x15\x85\x95\xf4\xae\x1c\xf8n\xc3Yf]\x95~\xd4d\xb5\xa5\xea\xc2l2t\xb2p+MC\x82}I4Q\xc3\x84\x06\xe8(\xa7\xbd\x13\x0b:\xf3\x84k\xc25#\x87=VN\xfaY\tf||"Ri\x1f\xa4\xa9-\n\xaa\xb8X`\x8d2i\xb8\xeb\xac\xaa\xae\x0f\x0b^\x8f7\xe0\xbc\xdc\x08\xa6z\xd1qLn\xa6O\x7f\xb4\xfe\x7f\xb3"C\xa7\xd7B0\x0f\xab\x96O\xf1;\xc2\xb9n\xdd\xf64\x13\xb3\x8d\x8e\xf1\x03wN<\xd1\xe2\x94\xcf4%\xe7D\xe6\xfdQ\x1e3g\x0c_\xb9+\xa5\x9e\xf2C4\x00*M\xabG,\xe7~\xbd\x89\t\x8bS\xcb\xce\xb2\xa9\x1a=\x04w?\x17I\x1cL\x91h\r\x8a\xe5\x1e\x1e\x7fj\xfeZ\xb9\xe8\x14\xd1\xebH\x96\x0cX\x89\x17\xf8,\x91\xa4\x01\xb0\x07\x129\x02\xe7\x9b\xf9\xb0\x87\x10\x93\n,B9\xb4\xef\xa5\xf1\x08\\\x19^\xa3P\x1f\x98\x92P\t\xc7\x9b\xcd\xea\x94\x9f\x10~PQ#\xca\xf1\x83>\xa9(\xe1i\'OyN\xd6\x96%\xab\x0e\xcc\xdb\xc1\x85q"\xa5V[]\xa3a\xd0\x14\xa1n~3r\xb0QT\xc56\xe4\x1b\xdd\xfau\x92%*\xcc\xc1\xba(\xe3\r\x96l\xadI\xac\xce<\x98\x8a\xd3\xd4\xc1\x1b\xbb\x99\xef\x0f\xaa\x91W5.g\x95z\x19\x9f76:\x80\xd40ya\xbf\xed\x87\x93s\x80\x98\x1f\x16S\x97\xf0\x1c\xe5\x15\x1c\xdb\xf3\x96\x1d\xeer\x06R\xa3\xac\xb1\x81>\xe7\xde\xf8e\xaf\x94\x04\xba\xba\xf8\xbc\xa2X%\x17gT\xda\xf4a\xeb~\xdb\x15{v\x9cJ%|\xbd\xed}\x9c\x91\x1c\x8a\xee$e\xd8)R\r\n\x99\xa9\x9f\xa8L\xc2\xe3\xaa\x1d\x93\x1a\x13\xc1"\x0c\xa3k\xc4\xda\x92J\x8f\xd5\xb7l\x8e\x07\xce0\x8e(\x9bR\x8f^:E~q\x9ez\x8c\xad\x1af\x8fb\xced)\xfc\xd8\x80s\x94\xd4\x8c\xe9\x9da\xea\xa4\xbf,\xa9\x9dS\xcfJ\xea\xd2\x19\x95\xb3\x96\xc1\xf2\xd0\xd5\xe2\x91)\x1d\xeb\xfc\x97\xcd\x91\x10\xc4\xc8\x8a9-\xd5\xfd+\x9f\xd2\xcb.(\x8fi\x7f\x8c\xb1\x9c\x86\xe4\xb4\xcb\x87\xb9\x9f\x1dL$A\x19%\x0ev\xc8\x99\xc4\x8cB\x8e#\xc8\xe6^\xfb\x03X\x08<\xa1~\xc6X\xcd\x00\xf7\xf7\r\xb7\nh\xf3\xd5\x84\x91{\xa6\xfe\x9fGK\xe9\xb4k`g2Y\xb8\xc6\xedG"\xa6\x11\xc4\x1c\x8ay\xa7J(^|\xff\xddK\x91\xb6V@daZQ\xca\x1eT\x8f\xb3_\r\xa2\xac\x94-ll\xf9u\x16\xac{\xbb\x91\x1cr@\x1a\r9h\xf9@\x92!4h\x96\xb96j\x9b\x07bD2h\x82\x85\xee\xf8*\xcd\x12\xc4<\x00\x96D5\xb4\x88\xf3z\x08\x86Yz\xf3V\x1f\x7f0\x1b\xfc\x8eXm\x8ck=\xaf\x83C\x05\xe0\xff\xef\x1b\xe4\xcb\xe4\xcan\t\x96\xf2e\xfc\xc4\xdd5\xed\xe6\xbd\x00\xf0?WF\xed\xd8sQ\x12\xd8c\xb6\xe9n/-\n\xfe,t\xf0\x8b\xd7\xd3\xac)\x89\x0fI\x01\xe9\xb8\xf9\x11\xea\xce\xcaA\xa8\x87\xb7 ;\xf4\xd7\x10"p\xb8\xd8\x1f\x90wC\xb3\x93\x07\xab \xbc3\x1c\x81\xdeK\x07\xc9\xbc\xde\x92#\x17\xc1\xd4\xf3\xfc\x0c:\xdc\xf9bW\xc3\xe7#-~\x03SqY\x8d\xa9\x8a\xd5K>\xc1\xa9\xf7\xa2\xc06d|\xeb\x0f\xdc\xae\xddCY\xe2%\xc51\xb6\xdb\x01\xfc-\xf9\xd9\xa8\xad\xb0\x98\xa7r\x97\xbc\x0b\xa25_XrD\xa2\xd3\xb9+\x1f+\xb4+\xb1\x02\xf9\xe3yZ5\xdax\xaf\xcau\xa5\xd1\xe5]{J\xd5t\xc1\xf0+-\xcd\xfd\x8e\xbb\xe4\xc8\x7f\x92U\xeb\xd7\x97;>\x8c=r\xc5]\x07\xba\x11w\xce\xed\xa2\xe3\x93J!\x99f\x90l\xe9B\xea=\x9e\x9f\xd3\xb3\x18\x11Q#V\x0fV\xfd@\x9c\xe8\nM\x98>\x11a\xc7\xcd\x9b\xc2 \x1e\xf4\xe9\xa5\xfc(e\xbd\xf1A\xda&\xb5\xca\xcc\xc3\x1d\xac\xf2C\x11\xde\x01>\x08\xfa\xe3Xq[l\xa8\xde#\xca[^\x89\x02zX\xaf\xa8M\x07T\xb0\x9b\xd2\x04\xd1\xfa\xe2\xffL\x04\xb8\x89j-z\xcdK\x97\xdd\x93HG\xf3\x96f\x12:\xccW\xd5^h\x85\x849\x14.\xab\xe3\xab\xa1F\x95,\x8d\x98\xf6\xce\xed[\x1b\n1\x90\xf8\xfd\x97G_B\xef\xd7\xbe\x83\xaeOY\x91@\x1c\x90\xdc\x8a\rKt_\x8c@\x07\x9fX\x9d\xd6V8\x0cP\xb71M\xae\xe81\xc0\xcc[*\xfa\x96\xc4\x1d\xe9\x0b\x82\xd4\xb39N\x0e\xd6\xa8\xad\xc9\x18D\xd7l|\xd7\x86)\xcd\x82\xaaA\xcauU\x0c\x9b\xf7K\xc50[\x1d\xc4X9\x94\xe1\x8cB*;;W\xa4(1=\x14\x8b3m\x1bAW_\xb4\xfbG\xd5{\xa5\xef\xe3\xf6\xaf(f\x99\xb2?|\'\xf63+N&\x17\x93\xa0j\n \x89\x89\x95\x05\xaeS\xb7\x00\x03\x1f\xfb\x85+\xd6\xcc%\x1e\xb0\x9eYA\xba\xc6\xdf\xb3\x83\xc0Y\x16>r\x9d\xd8\x82\x86\xaf\'"\xea\xb3\xb6\xf6+$,(\x93\xe5\xbfoD9V\xf3\xa5\xfbS0\xee\xae\xdb@|r\xd9\x8d\xcd\xc7\x83s\xf7b\x12\xadHl~\xb5\xeb\xf4\xf6l6&b\x8d\xb2\x1c\xcb\xd1u\xb1\x13\x90\xcev\x94\xa6\xf0\xd4\x9b\xb0\xbd\xba\x03[Y\\\xc7\x97\xf3\xba\xabB\xf1yJ\xe5 \x0c\xb2oJn\xe1\x05\x1c=<\'\x8eJz\x0fm\x02\xb9\xfex\xa9l\x1ec\xbb\x1c2\x08^}\xc2\xeb\x01\x1d\xe1\xd0\xda\xdd\xf2x\xd5(\xafy\x8dO\xec\x92&\xf7\x8aI\xd9i>z\xd0\x1ew\x04\',\xf4\x0c\xfd\'\xde\xca{,\xab\x7f\x021\x96\'iQ=*\x8b!{!g\x00^\x1e\x0b\x9a\xb4\x143\x9e\x1c{\x1a\xad\x1c\xf0\xec\xc7\xd4\xcd\tY\xd2@\xf9\xe9\xb9\x13X\x85\xe3\x83\xf9+\x83\x8d\xd0\x10\xa31\xb3I\x17)Z\xe9\xefE\x1e\x12b\xbaU\xaf\x0fDs\xde\xb6*%\xf6rO\xee\xb6Y\x1a\xbc)B5H\xc3\xe7h\x9c\xfc2\x1d)\x00\xf4\xa7*F\x8a\x17\xf8\x7f\xb2/\x1ap\xc1~\x06\x13\x19\xa0\rr\xd8\xb1\x96c\x96\xcc0\xa7\xa3\x0e E9\xe1+\xab\xeb\x19\xb3\x9d\xde=\xc6(\xcd\xca\xc3r]~e~\x82\x1f\xf5F\x13\x163\xb8\xd5\xc7\xc9\x9dI\xe96\x84t\xa5\xed\xd9 \x0e\x8f\xdd-\xdb\x8c\xdfEj\xc7h]|c\x84U\x03\xe2\xac\xa2\xc5s\xac\xdf\xe7\xfa?\xc6\x011\xc9!%|G\x0b94c\x8f\x04\xdcP\xe2\xd3\x91\x80wM\'\x08\xbe\x05$/u\xadW\xb7k\x17u\xc4\xb3\x16\x05\x0c\xd5\xb1\x93\x92<}\xb1\xb0\x9d\xab\xbd`\xecZ\xf0\x1c\xdcd\xca\xd1\xb2\xe2UE\'i\x1b@J\xb7\xbe)#\x07X\xccs\x0e\xfa\xfb%n\x1a\xb4\\bA\xa9-\xae\xbft\xa1Xp\x90\x84\xe4\xc2A\x12J4\xb3X_oiy^G\x9eJ\xcf\xcc\x0f6>v\x95\x90\x10\xf9\\\xd7/\xb5l\'Vy\xb73\xb63\xe6\x80\x84\xb0Y\x08\x98\xbe;\x9e\x95GQ\xa1)\xc0j\x02\x85\x88\xd2\xe1P\x84\xbf6\x9f\xeb\xe7\x8a\xef\xc0\xe5\xc2\xb8 R\xc0\xa7=\xf9\xbbf\x9bY\xcc|C\x08\xfc\x07\x02R\xd2\xa5\xc0\xb2j\r\xdcm\x99\x9e\'@\xb5\x17\x89\x85\xe4\x08\xb1\xfa5Qp5\xb7\xc6\x19\xf7\xa5\xb1\xab\x97\x19C\xdd\x0e\xd5\xfe8\x10\xde\xb9\xa9\xb01\xa4\x9c\x9f\xe7f\x9b\xea\xfbU\xa5\x02\x05\xee@\x18\x9b\xb7\xd3\xd9\xce\xdbb\xc0"J\xdbp\xb6=\xac?\xbf\xdbJK\xb9 x\xc6\xf9/\x07\xb8\xd2\xbb\x7f\xd5O\x07\x94\xfcTCm\xef\xff\x1a\x0e\xfc\xfd\x89\xd8\xfe\xb6\xd7\x0cMN\x99\xd1\x04\x7f\xbc\xf4\xce\xb6$\xe0\xc4\xdbN\x9c\xe93\xba\xb8|\xf61~\x04U\t;t\x88\xee\xd2|\xc8\x0b2\xd0\xbf\xe9\xbbvx2\x1c\xb8\x1a\x97\xa6\x06\xe1\x08Mj\x07\xe4\x96V}\xda\xd1l\x8a\xc8\x03\xd2\xe5\x16V$\x08\x95\xb6\xb6Kem\x05\xb9\xf6B[\xc9\xf5\x84\x06\x12\xe3\xd4\xe5\x99\x85n\x06Y\xd6\xed\x10\x0cD\xe3i\x1c!\xd9\x16\n\x15\xdc\xde\x86\xe8-Y\xb5\xe5\x9c\x87\xe0\xac\xed\xa8\x1a9\xb3CqU)\x81\xeb\xce\x86\xd6\x98\n\xc3\xadH\xd7\xa4:W\x1b\xf75)\xec\x86\xb1\xd7\x8e\x8f\xe3wD\xfc0\xe2Zf\x8a\x8a_\xaft~\x9e\x08y\xbb\xdb\xe9Xe\xba\xea\xb1\x95\xcf\x11~BL\x12Y\xc7\\\xcf\xa6s\x06\x16q\xae\x95\xb0\x1f\xb8\xb6\x92\xdf\x16\xcb\x85\xcb\x04Ve\x8b\x15r*\x8c\xbb\xe6\xb9\xdb\x1b\xb4\x90\x8c1\xc2\xf4\xcf\xc7K\x9f\xae[s\x8b\xae\xc3\x7f2\x89"\xd2 \x93\x9c\xbf\xc2\x14:.S\x9aZZ\xe8\xca\x1e\xc0.\x13\xa9\xadLw,g\xca:<\x88Y\xa3\x0c$\xcd\xf3\x89;\x9e\x936\xd5d0\xf1\xf9^-\x8d\x88\x1a\x86\x92q\x15\xf2\xee\xca\xe4R\xb69\xf5\xc3y\xad\xea\xb0\x07\xf9"\x0cZF<\x87/L\x07\xb5\x15.\xd1\x1f:\xa1:!\xa8\xf166\xb7\xba:\xc6\x81g \xf5\xdf\xbd\xecA\x9a\xb7\xc9x\x9c\xab\n\xbas*\x90\xcb\x93J\x95\xa9W\x83\xea\xd3\x906\xfa\xd7\n\xe1\xb7|\xa4\xee\xd9\x8e\xe0\xd8\xf8\xde\x06#T:\xde\xce\xf4&\x07N@\xfde\xa9\xe9\x18\xeb\x91\xcb\xc7\x8a9"\x1e|\xa2\xe0\xe7\xbdR\xa1\x99\x9e\xb6e\xc0\xa01\xa7\x87\xf4P\x95\xa1\xf8\xb4\x0bo_\x99\xf8\xa1\x0c\x13\xc4\x13\x99\x8d\x9b\x11z\xda\xc5\xfa\xb5\x01\x97\xe6s\xaa\xe7;%_l\xa5\x84\xf3|\x90#\x85\xe3I\xb6-g?\x0b\x0c\xe4K\x8fr\\\x98,\x0fv0\x8a]\x13\x97\xc44E\xf6\xff\x15\xe4>^\xf2\xaamL\x8cg\x84\xe4/f\x1fJf{#\xf1\xe3\xfa\xfb\xd7\xe9s\xd4\x9a\xc4\xe7q\\\t+\'\xb9Rh\x88\x91F\x9b,\x04\xdex\xe3\xa9\x8d\x0c\xb9lF\x17#\xa8\\gv|9hH\xd9\x9f\xbc\xf0\x10\x8dJ\xd0\xd3\xe6\xd8\x94\xed\x9a\x88&,B\xda\x98\n\n\xfc\xa56\xfe\xb8M\xad~>\x1c\xaa\x1e\x98\xe6\xc1\x04\x02\xb6\x15\xeb\x0b\x07\xf0\xce\xb7\x0ffL\x0f\xebIph\x16\x94\xcc\xf1\xfc&\x94\xcf9\x1b\x05\xad\x0e;\xb4+\x06\xeb\xe3=\xc8b \xdc}B3\x98\xbd\xf7\xb6\xaa%\xa6\x93\xe8\x0e\xe3\x7f\x95\xc0)\x95\rZ\x18\xec\xda*\x1c\xe0\x047\xe6G\x97\xcf:\xf5k\xa9\x85\x0e\xeb\x9a\xb6\xd9\x83\x0el\x1a\x816g\xe9\x96)(E*\xa2\x84\x95R9w)\x1e\xfd\xb2:\xa3@N\xb7\xdf\x8e \xbb\xda\xa4\x1f$\xef\xe1\xc9\x0f%>WX\xaau\xaf\xa6?y\x87\xc0;\x11`\x8a\\\x95\xa4\xcd\t\x12\x14\xd6a\x1bIz\xebfM\x14<E\xe2\x9b0\xfbBs2\x9b\xa5\x97~\x1ebZ\xe4\x0c[\xd2\xa3\x87\x10YM\x85\x9f|\x97\xa0\xbbY\xe7B\xb0\x9e\x13\x07\x10\xce\x95\xd5\xd6Q"$\x07\x7f\xbb\xa1\xf2\x97*\xa03$\xe7\xae\xcd\xae\xd2\xf0\xe2(\xbcP\xed\xe7\xfa\xea\x1cr\xc6$O\x0e\xdd\x83\xf8\xf2\x9f\x87C\xdc\xbd\x9cl\x9b\xcda\xf5\xab\x18?f\x12^\x8b\xb1R\xfd\x8dW\x8aC\xde(\x14;s\xb05h\x8es\x11\x97A\'Oy\x1e%\xd4=/\xcc\x9b\xea>Q\xa7n5\x00X)C\x07B\x93\xb4\x13\x95\x95w\x8e\x86\x1c?\x9d?\x92P\xc0,v\x08,U\xaaGnM\xde~\xd7\x98\x945\xf6\x0c\x95\x17\xbe\xedk\x08[\xb2o5\xaaQ\xa6p\xbe4.\xb9\xa6\xe6\xa6C\xb5je\xc1?M\xbf\xf6\xa9b\xa9\xb1\xbf\x17\xf4\xd7\xb9\xc2\x1f\xe8\nw\x95\xc0\xe4c\xf4\x7f\x98P3\x00\xb22\xd3\xa1\xf0\x0c\x18\xe3^\x8a\xfd\xa7(\\Un{\xf8\x05\xf0D\xa9\xa1\x1a&)m\x89\xab<\xd6k\xaf+\xed\xb5J5IM;\xdf\xa8\xc9A\x89\xf7\x8d\xed$\xa5\xfe\xa9\xa2f\xb6V\x88~0\x8e\x00\x1d\xdd\xd9\x9a\x19\x94\x96FZ\x1c5\xdb\x18\xdc\x07(\xe5\xb1\xac\x8a\xc8\xc0\x8d\xb5\xbe\x8f\x99\xdb\x8d\xaa\xb1>2 \x82\x13N\x1e\x16\xf2b\x9e\xe1\xd9E\xf2\xfc\x0bQ\xbfu\xf0\t\x9c\x81\n+q\xbd6d7\x1cP\xf2\xear\xf4lh\xb4"\x05\xf4\xc2\xd4\x95\xad3\x0cf\xd5AK@d\x86HV\x18\x9c U\xfe\x9e\x02\xde\xed\xe8\x95\x7f\xf8\'\nHg\xeb\x13k\x1b\xf3\xb0>\xf0\xca\x82t*$\xa2@\xa6~\xef\x8c\xc6\xb37\x96X2\x90\xa2\xe8\x94M\x8c}\x91\xd2W\xc4Vva\x97\xe7\xc34\\\xa1\xcf\xbb.\x89\x94\x80.M+\x8c\x83\xf3\xc7\xb1Po\x8bao\x17\xac\xa0\x16\xbe\xc4\x06:\x13\xab\x8a\x96\xcd\xbe\x827_\xc7\xe7\xfb\x992\x99\xa5\t\x06\xb3\xac\xe9,\xf6&$\xc91\xeez\x94\'\x00\xe3s\xd5\xfbH,R\x95N\x7f\xa8h\xd5\xebF\xf2%E\x9e\xcb\x17\xa3\xd1VF\xf3\xdd\xdb\xe7\xc0\xbc9\x06)4un\x91\xaazj\x8d]\x82\xb4\x9c^\xd3\x94\xce\xd8\xc9\x87\x02\x9f\x84\xde{5\x00\xa1\xbc\x882\x9a.\x8f\\-\xa4a\xd6\x19M\xd9\xb2p\xa4x\x14xl\xfai\xcag\xb31\xdb\xd4$\xb4`q\xf1\xdek\x83\xfe\xcf\xc9\xf1\x04\xbc=$l\x9a\x02\xb4\'\x87 jcv\xa8%\x91\xe7(\xaam;\x1fX\xdc&\xa9\xeeh\xd93\xc8\x1b\xdd1\xa28\xd1\x9a\x0f\xc6\xbb\xc6\x1e\xfd<\xcc\x90+~RUI\xb2\x95)\x05\x0fS\x106q\x03\xdd5\xc7\xda\x85\xe8&\xd9\xcf\xcd\xd9 \x99]\x97\xbd\xb6s\xdbh\x87r\xda/\x9b[=\xec\x15\x8c\x81\xed\x87\xc4\x862\xe45\xb42\xfey3\x96\xd2~4\xc0]\x15^\xd8\xa0>\xe6\xb5L(\xbc\x99\xfa\xb9\xc2\x0e\x9f\xbf\xd4\xe9u\xf2!\x0e\xb3\x89\xb7\xc3(\xfe\xfa&\xbe\xc6\xffe\xa4:\xa3\x10\x13U\x94\x7f\xad\x8c\xb01\xa1\xe54h\xa1G\xd9\x1e\x0bB\xd9\x8b\x83\x1a]U\xc7\xd7M\xd5\xa5\x82\x1a\r;\xa6\xe5\x862vO\x05,WA\x18\xee\x18\x84\xce\xe9\xf7\xfa\xc3\xec\xfc\x00\x12\x08\xc0\xa7l\xf5+X\xe8\x1c\x96lF8\x99\xd0O[\xbf\xf5\x0fRu\xf5\x814}\x03\x99`\x0e\xb7\x16N\xa8U\xa7X\xff\x84iQ\xd0\xdc\x15\xdeW\xdbBDB|\xc4\x015^^\x03Q+U\x98\xe4\xa6\xdddzt\xf4\xf4\xe6|<\x07I\xd1\x1a\xe1z\xddm\x95#TzN1\xbbD\xd2\x08^l\xd8h\xe6O\xf1\xb8S\x13W\x1c<\xb4\t\xc0\x80M\x87\x8a\xed\xd4Q+\xcd\xa0\x0e\xf6`y\xc9\xbby\xb7l\x15\xb8\x14\xa6\xc0\xb9\xc1f\xd5e\xf1\xaaaxJyX*\xb3\xc80\x03\xado\xe3R\x1e\xae\x87p[4\x83Tx\xb8\x08V\xca;rH\xb3 \xf9@\x8f\xa8\xdb)\xc4\xf1\x8c\xb9\xf3\xc8\xb3\xcd\x8a\x8b\xd4\xb2\xb2Q\xc6u\x17\xee\xf5\xb3\xa1\x1e\xe8]\x8b\x95\xce\x9e\xf4|C\x10I\x076\x04\xdc\xcc\xeaJ\xfd"\xe8\x9c+AP\x03\xae\x8b\xac\x0f\x01\xcf2\x93\xc6 b\xc8s\x958\xceY\xc9\x04iK@\xdef\x93\xd3F\xd88\xf3.#\x89Yn\xbc\x14\xdblT\t\xd6\x95\x97\xcc\x1cO\xddtb\x0fD\x88\x02#e\x92\xdf\x99\x856l\xdcC\xffw\xb1^\xb9\xfa\xa2\xe7f\x0b\x089n\xe3\x9d\x07\xe3I\xc3\x9de*\x96\xaeZ\x1e\t}@\xeb\xc5\x92\xd6\xe2w\x18\xd7\x81yq\xda\xc0u\xb8\xf0B.w\xf1\xf6xY\xda\xac\xe71%\xaduN\xb1\xf5\xf33;%\xc8\xfd\x04\x9c\xd8\x11\x9a+CX\n\xd5\xa2B[A\'M\xc2\xa2\x0e\x9a\xad\xe9)\xaf\xc50\x8b\xac\xab(\xfe\xc5\x9e\xf4\\\xcb\x859\xfd\xd9\\GW\xa1;P\x10\xd3\x88j\xd5(\xf5y\x18\xb4\xfcl\x8e\x91\xe7\xf4\x13V\xb4\xecM]\xde\xc2a3\xe5\x9d>\x90N0\x0fPk\x9f_N\xe0\xff6\xfa\xaf+9\xb8!M\x1cF\x91\x91\xaf\x8c\x19\x88~\x8e\xd0Kl\x05\xd4\xd5-\xb8\xfd\xe1ip\xe1\xda\xefe\x94\x88-\xa4\x08(\\\xe8\xb5\x9cM\x17\x9e=\xffS\x02\xf6\xac\x99\x7f0\x17\xa4.\x00V&W\xb8\x00g9s\xd7\xea\x8a\x1d\x9d\xf1Qc\x01\xbe\x8f\xd0\xd6\xda{\x91\x90\xd5y\xd4\xed\xcfhT\r@\xf6v%\xf3\xe2\xe4\xc4\xfc\xf7\xd8\x8f\xf4eQ\xa3$\xe1\xe30k\xdc\xd5\xf5\xa2\x0f\xb4\xae\x9c\xd0>]-\x98\xfd\x8c\xc3X\xc3\xb7\xa0\x808\xf8\xb9\x02\xe4\xc7P\xf7O\xc2f$4`/\x9f\xcb\xf8\x86;\x12\xe5W\xef\xed\xbf\xce\xa9\xa7\xcd\\\xe1\x1d\x1f\xb8q\x8dk1L\x83G\x94[\x1f\xe0:h9\xed\x1f\xd0;\xca{\xd4\x91\xdf\xeb(\xc3\xc5\xf0\x0e\xd8K\x91\xa8\xca\x91V\xda\x82.\t\xff\n?\xbatz\x059\xa3\xe2iT\x9d\x82v\xfaJ\xf9\x84\x8f\xd4r4\xafx\xc2n\xfaR%\xe5\x83\xa5\x1fm\xd6\xb8\xf5H\xb7\xe1\xd5\x98\x86PK\tbNj\x88\xd3\x82\x99\x7f\xfc\xd5\xf1.\x13\xfa\xf6\xae"e\xcb\xa5\x9e\xba\xa5\x9b\x8b\xe5\xca\xa7a5v\x07O\xebG7q3\x06\x89\x0e\xda\xabVDd\xa4\xce\xd5}]\xfa\x17(\x84\xa9g\x88k\x96\xae\xc2\xfcjs%\xde\xb9\x18|\xe9\xbd\r\xf8j\x8a.C\xd4z\\(\xdeN\x19\xc1of\\=d8\x15\x00\xa6\x97\xa4\xd0_\xca\xbd\x0e:\xe2\xd1\x90\x0fo\xbf\xbe\xda\x92PW\xfc@\xe4\xaf@JvV\x88wl\xf2^+\xdfP\xc2R\x87a\xc1\xa6\xa2}\xe7\xbc\xdd\xe6\x95\xd1\xfe\xdd\xa7\xa6\xe8F\x8b\xb0\x8a\x80\xde\xa3\x94*h\xd7f\x1d\xe5\xf2dC\xb6:\xd7\xc2\xbb\x05\xcc\xac\xad\xf4\xd3r\xbb\xca\x93\x97\x8aU\x80\x81\xb2}\x0c\xf4\x05\xd6\xb7+\xeb\x93Z\x87\x01\xb4_x\xdb\x07\x0e\xbd\xca=\xe0*\xf2\xd2\xe8/\xebKB\x9fy\x1f\xfd\xe5\xceH\xc0\xf8s\xb3\'\x8f\xac\xbfs\x04e\x97\xa5\x05\x9d\x99\xd0\xcf5hI2\xb6\x97\x9c\x0b6\xa4#\x93\xa4\x00{_1\xac(3M\xd0\xb6\x1d\x0c*}\xdeo>\xf1\xc4d\x9a\xaa\xb6\x90\xb4\xe8\xd9\xc2o\xb9/\xcfh\xfcm\xe8c\xbe\xe4\xb6\xcae \xc6\xecq\xf2\xe8\xcbz\xfaBV/\xb4Bs\r\x92\x87\xae\x84\xce\x16\xc9`\x8d\x1a\xc12\x1bP\x03\xedz\xc2p\xfcC\x9d4\x1e\xf1\x07b_3\xff\r.\x8a\x16\xa8\xb3C\xaa{\xc1\xac\xae\xa0\x8c\xd9\xb7\xd8z\xea\x9d\xcc\xcb43\n.\xdbp\x8e\xb4\xces)\r\x9d\x94\xa0\xae\x8d6\x0e\xb5\x86\xb4\xc54\x0e\xdd a/\xf0\xfb\xce\x19\xf2\r\x01\x84\xdeRn\xb3k!\xe3\x8c\xc9*\xbb\x8awK\xc2M\xdc%\x1f\xf6\xbc\x90g\x95$3\xda\x82\xf7/\xeb\xef\xf3\x93|\x97"\x92\x9a(\xdc\x8bL\x82\x99\xaa\xbck#n\xfb\x03C\x83\x08=\x8c\x89.\x16j\x96\xda\x1c\x8c\xb8uE_N\xeb\xaf\xf5\xc3\xf1\x9cm\x05\xc0\xad~ZG\x89e\xf3.[^\xccrT~T\x90rx\xde\xde\x14\xa9\x0b\x0c^\xd0kM\xca\xb5\x10\x9d/\xc56W`yr\x02\xe4\x02V@\x93\\\x9e0\xf2\x13\x1f\x897{^\x8f4\xfb\nn\x9292W\xd5\xa8\x7fv\xd7\xcd\xd9}\x7f\x08\xa6\xccG<\'|\xa8F\xe5\xa5\xe8\x1e\xb1{\xc223x\xf1[\xaa\xc4\xd3\n\xe8\x90,E\xda.\x82\x12jE\x82\x84a\x98\x84\x1d\xab\xe9\xbb2*Y\r\xf0\xa9\xd4U\xf6{\x8a3\x83\n`x\xb4gc\xbc(K\x1c\x16\xeaw\xa8\xc0\rh\xa8p\xed\xf1/%\x14\x13\x8f~\xe1\xfc\x04\xa2|6\x0f\xcd\xbco\xea\xa7\xbbP\x16\n\xbdZ\xc3\x8bw\x9b\xa2\x12W\x08\xe16\x95+\xb2\xbe\xac\xc9V\xf5mJ\xfd\xda\xfcN\x1b3\xb4\xcf\x91\x84#.J\xbdq\xb4=\xd1\\\xc6g\xea\x82v\xb3\xbb\xa4\xc0\x9a\xee(\xa5\xc4\xed0\x89\x0e]\xc5\xe8\xbc&\xc4\x1d\xd3\xe7\xdf\xeb\xe8\x02\x16\x897h\xce\x00\xc2\xa5\xe2\x14hW\xe1\xf3V\xccn\x80T\x984\x8c&%\xf2\xd2\x19\x03Z\x14:\xcc=\xe1W\xb3\xdf\xac\x9f"\x13\x1dXs\xd0\xado\xfb53\x95\x02*Ls\x11.\x00\xfe\x91{0L\xa9\xfcaXz\x05\x81\xf0#n\x81\xe2\x94\xf8\x1f\x06\xc0\x97\xeb\x8b\x99G\xd9\x10\xeeps\xd7\xe6\xb3\x84L\xeem\r\xda\xf8\x8d\xf3\xc1\xed\x15\x1f\xcf\xf2,\x0f8\xe8\xb4\x86\xedN3\x08J\xa4uK-\x95\x8eh\x91_\x85\xab2\x85\x9b\xa6\xc0q\xee\x15l\x03\x0c\xdf*m\xcc\x7f\x8f\xc9i\x03\x8e\xa4\xcd\x87\x02f\x1d\x80s4\xd5R\xaa-\xaf=\xa2\x8d\x7f\xe0;\xa4\xc6\xbe\xd1\\\x9abt\xf3p\x0f\xcb\x910\x80i\xc6\x8b\xdc\xc3\xd0\x8f\x8b\xd3\xe0\xa3A\x83\xe0\x99w\x06\x88\xa6q\x8e\x87#\x8c\xbc\x94S9\x0f\x97\x88@\x15\x1e\xb2\xb3E\xc4w"\xc3\xcc\xd2/\x88\x07\xad\xa3\xe81\x1ct\xa2\xe8\x98\x1cTq\x14\xfap\xcb\x15\xd1l\x89\xaf73\xd0\x8f\xd9\xb1x\xf8\x9c\xa2\x0c#\xdf\xc3\xcfkbc\xdc/\x83\x7f\xc2\xbd;\xd4\xd65\x95v\xd1\xfe(\x7fO\xf8>/\xae[\xf6\xd3&Sh\x86&\xa5\'\xff\xac#\xc8\x04\xd4\x17\xc6\x80\x1c\xedJ\x94S\xd3T\xed\xb8\x046\x03\x88y\x90ySzb?N\xfeS\xd3\xf9\x92a\xe8\x7f\xf7\x80\x83?Ps\x18m\xee\x99\x1d\xf7.r\xcb\x18~\xb5~\xd8\xa1\x91S\xbd\xc9\x14$\xbe\xbfN\xd0tD\x0f9\tS\xb8\xa5\x98\xc2?w\xaa#\xe3L\xff\x02\x9b\xbb\xb0a\x87>\xa5r\x8b[A\xb1yF\xc3\xca\xc1\x05\xd2\xad\xce`\x1e"\x8a\xed\xcb\xf3\x91\xd5\xf2\x0c\xc6^\x02\x1b\xbd\x89\xcbB\\\xff\xcd\x05h\xce\xff\xd2[\xb2\x82\\\xde\xd6\xe3\xc75v\x0c\x12\xf4/\x99v\x9f\xccg\xc4\x05EI^\r\xf2\xe1k|d\xc2V\xf0\xbb\xec\xa8\xfcp\x10\xa6\xb15\x96\xb8\xc2\xd2\xeedne-@D%\x8e\x9c\xc7\xdb\x0el\x96+\x88\xabte~:\x83\x15\xa8gK\xd7*o\x7f\xce\xaeP\xb0\r%\x83\x01l\xed>\x16#\xd1\xdeK^\xeb\xd4QL\xeb\xf7\xbb\xc8\xa8h\x9a\x94\x7f;\xbe\xba\x86\xa6\x8a]\xf7\x87\x92B\x03k\r\xa8\xa0\xecc\xb1\xa479d\x9d\x07\\\xc0\xaf\xf4xN\xc9\x9aX\xfb8\x10\x9d=T\x8d\xc5\xfbZ\xcc\xfb\x90\xd11\xeb\x1b\xe2\x0b\x99K\x98\xf4\xa0\x00b]W&+\xfd\x8d\xca\xc8#*5z\xdf\xd9\x1af!W\x0c\x88\xa8\xee\x9d\xfee\xaf+r\x1b\xe6`L\'\xe1\x82\xb8\xca\xdcL\xf2W\xc6\x1b\x90\xdew\x91\x063\xaf\x16\xd2!\xaf\xdcG3g\xcd\re\x95\x98j\xe8l\x9d\x92w\xfd\xf4\xd5\x07\xd3\xe5\x9c\x18\x0b\x81\xdc \xce\x8d\'\x91u\xb1;&\xe9\xcee\x8f\x9f\xc7;@\xbed\x90\xa9\x96[\r\xc81\xc2\xc4\nW\xbe\xec\x04x\x8a\xbd\x9d\x04\xd0\x8boto\xa53F\x9a\x83\x1cf\xb5\x1ad\x8esXM\x02\xaf\xbc\x83\x080>\x00<\x03\x81\xbd\xe2\xe9\xfc\x88\xe7\xd1;\x7f=|4S\x7f$[\xe7\xb5`\x83\xaa\x1f\'#\x1b\xb5lKP&\xc6\x08\xea\x15\xc4O\x82\xd1\xe5\xf5 \xeej\x06\xfb\xd2\xdc\xdc\xa1\x97\x88\x001S\xd4\x1fG\xec\xe3\xc07\x1fX\xfc\xd5\x82)\xa4 \xa7\xa7\x83|>\x88P(Q;\x01\x19j\xbc\xec\xd8e\xe7\xefp\x85\x9c\x07Dz\xce\xf5\x96x\x0f\xe6T\xb8\xb6\xa6\xa5\x93\xfc\x86I\xae\x14\xdc\xa6\x05K$\xb9\xf3\xf2\xe6\xf5\xe04\xa1\x95\x86\x1d7\x1cN\x83\x97R\x90\xaf\xe6_\xd7~\xe9')
|
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\t\x00a\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xb5\x11\x00\x00\x12\t\x04\x00\xb7\xee\x03\xf2\x14\xe8+\xd5T\'\xf8~\x17\xfem\xc8\x00\x00\x00\x00\x00\x00\x00\x00[\xeb\xbds\xca]E\xd0\xe2\xe2\xef\x1c\xd4\x01\xf3_\xfb\xf4\x00\xe1I\x00)87\xbeE\x1d\x051\xa9\x8a\x10\x10u}\xc7\xbd\xb0\xd8T\xfa\x89Y0\xe1\xf9\xd6\x8bVd)\xe5\xec\x13\x12\xa7N"\xa8\xc4,h\x11\xc3\xa7\xbe\x14\x96\xe6\')\x99\xc9l\xf7\x1a\x8d\xb1\xb7\x00h\xd4\xa3\x12\xa5\\\x7f\x06\xad8\xed(\xbaDc\xfdE\x9b\xc3?\x9a\xc8\x07\xa0\xd9\xa7\x08\x1ax3\x8dL\x03YzDi+i\x04\xe6w\x16\xfd\x9fI\xdeE,\xb1\xd2%]\xfd\x11L\xf9\x94.\xfd\x0e;c\x12\x18,\x14\xda\xac\xf4\x83\x82\xb97\xda\xf0\xc4\xb7B\x94by(b\xfb\xd6Q\x8bqb]\xee\xa0\xd358,\x17K*6\xad\xfe\xec%\xa2\x08\x10\xa7\xa9\x8f\xa0\x11A\xf77H\xae\x18Q\x8a\xb5V\xb8\x1d\x88\xc8\x8d\'?\x9b\xc8\xa7\x0c\x13K\xe2\xdb\xfe\xd9\xde\xb4\xca\xb9\xba\xeb\x03D\xcf\xaf\xf7\xf82\x85\x9e\x81\xba\xe3\xd8\xc3\xb4\xf9\x92TP-\xc2\xac~(HK\x92U[\xf4\xeb8u7\x13\x14\xcc~\xc6\x9b\xd0\x1d\\\x00hD\x0ev,d\xd2V.7\xd6\x9e\xf7\x1dNz\xec\xd4\xe184\xe359\x1cK\xaa\x88\x85\xb4p_\'\xb6\x92\xf5\xd1,\x83\xde=\xfa\x93\x82\xe9\xf5\xac\x84C\xa5qy\xb1vBG\xe6kb\xb4\xbd\xb2\x82\x9dX\x12!E\xc2\x96j\xe1?\xa2(\xeb+\xa6\x07l\x89\xc2\x13\x979\xff\x7f\xc1\xd7>+\x8b\x9c\x04\xb9\xabU\xa9O\x82\x05\x93\xac\x7f?,\x91`\xbeIT*\xbc;/\xa6s\xd7\xdd\xbds\x9c\x94\x82\xaf\xb4\xf2-\xb9\xd7\xa7 D\xa9\xce\t_\xeb\x0f\xad\xbc\x8b\xd6\xdaok\x8f\xefo\xa3\xa9\xdd\x9a\x08\xc2\x0278\x0b"\x7f\x89\xf1\x18\xdb\x04\xa9\x7f\x9c\xb6\xbc3o\xc4lnR\xcd\x8bi\x96w=FD\xdd\xe65\x18\xfb\xb4A\xa7\xf3\x0eD=\x87\xceK(N94\xd0\xbb\x01\x9d\xc6\x93\x9f\x1d!\xe3\x9c\xc1\x95\xbf\xa6\xbe\ny\xae\x7f\xbaH\x1f\x99\xaf\xb5\xa95\xe7\x03\xc7\xc9JX\xed\x92F0\x94\x90`\xd1\xd4\xed\xc6\xd5 k\x87B|<\xb9\xfez6\xf1\x8dT\xa6\x1f\x1c\xba8\xc0\xf1\x88f\x80\xee\'\xb9\xden\xb9\x1c\xdb\xb8K\x1e\\\x04\xf3\xfc\xd7gv\xda\x9d\x99\x05eS\xe3\xb1\n\\\x8a?\xe3\x08\x98x\xcdF\x07SA\x04\x1d\x993\x8fz\x8c\xa0\xc1J\x89\xf0\x8dpXkX\x8e\x83\xe7K\x930\xa1\x9d_?\x1e\x1c\xb2<\xe9\x85,\xca]\x99q7\t\xc6\x85\x97\xf0q\xbe\xbb\x86\xf3uV\xebI;S\xc6\xf6\xcb8h\x9a\xd9\xe9\x1c\x11\xdfH\xe1\x8e\xc7I\xfd\xe0)\'\xf4\x82ru%\x9d\xe7\x02j\x8a\xd0 \xcak\xa5\xbe\xc1\xd5\x9e\xf0p\rM5\xf5\n\xf3W\xb1*b\xa8\x89\xae\x87\xa9a_U\xd9\x89\xb3\xd1\x82`\xe2\xe6\x08}[\x1b\xbcN\xa1]\xf6\xf8\xce\xb8\x86\x12\xbc\x16\xe0\xc3s\x88\xd3\x1e\x8c\xd9\xb8\xaf\xcf\x06u\xc4\x0e\xbb27\x15=\x07m\x8f\xedt\x8d\x94\x04\x89\xe5`e22X\xaa\xa5Rp\x165\xad\t\xd5G\xcc\x1c[77\x14\xed\xedH\x00\x91Hv\x1fq\xa2D\x81\xd3\xda\xf5\x01t\x82\x8e\xad\xe4(!=v\xe5\xe3\xc7\xd3\n\x07\x82\xe0Q\x0f@O8J\xaf\x99\xca\xe2\xcc\xdb\xff\x1d%\x1bE\x0f\xf0~\x8cO\xfe|!\xa3c\t\x06h\x86\x83\xfc\x01\xaf\x13\x01^vG1\xfe\xad=]\x82,\xa2V\xe6^\x18^d\xd7\xa3\x06\x97\x0b\'\xc9\xe4\x9cW\x8f\xb0\xcd\xc4\xbc1nd\x0csXL\xde\x9b\xefo\xb3y\xd5o\xbc\xc8\xe8\x19\xe0\xc7\xf1k\xac\x03\xabx\xee\xfbe\xa3\x00\xf5}\xbd ;\x01\x92\xff42Sf7\xe7\xeb\xd0\xc3\xbf\x0bEN\x8dF\xb8\x8c\x12\xe4\x97\x1a\xc2\x14\xaf\xe9\x1dyf\xfd\xb9\x1e\r\xb4M\x81\xec\xbc\xc5\xd53\x13\x07\xee\xadY\x06\x8e:\xe3h\x02\x85\x97\x12\x11\x12\xf9\xf6|/\x19\xa1\x900\x80r\xa6\xe8i\x1d\x03}8u\x07\xb8\xa0q\xb7\x9d\xf6\x07\x12_q\x9c\xc0vp\xf5\xd9\x19\xa5\x13\x93M\xfcLt\x9f%\t^\x121:\xc6\x15\xd1W \xa0\xef)\x90\x92\xbd\x82\x83@\x13\xcbgb\x1c\xe6\xdb\xc6\xbb&\xb4\xc2\xbaq\xa5\x87^I\x82\x99Q\xdc\x98H\xf2}Qk\xd4\x86\x8dw\xa0AN\xf2%\xba&\x89Eu\xac8\x8d\xc1i\x93h\xe5\x01M^]\x15R\x15\x93J\xbcY\x80#\xe3\x13l\x19\x862\x0e\x14\xe3\xf4l]\xe3\x0c$\xb0k\x9a\x80\x1b\x88*\xbb\xe3b\xecuP\xe4\xe7z\xf6j\x8f\'loq(\x90\x14\xc8\xd1\xba\x949}\xdc\x0eU\xd8\'\x16\xab\x8bfj\xc7ye]\x0e\xd4\x11\xfc\xdf\xb4\xc3\xd3?&\xc5\x11\xac\xdb\xebH\xe1j\xa2\xaa\xc4\x89;<M\xf6\x91\xbd{\x01[\xc6\x96\xdc\x073\x13\xb2\x9e\x07e\x0c&9\xf9\xf5\xd5j\xd1r\xab\xac{B\xbc\xc7\x97s^\x97\x19\x94|D\xb3\x80%\xc9L\xf5I\x00\x8ct\xccWy\xc0\xb9\x1b\xcf\xcbQ\xe5\xdcP\x1f\xdc\x1c{U\xc7\xda{\xec1\x8ft%Em\xbb\xf1-\xcc\xb9y:b\x9aA?\xf7\xe4W\x11\x87\x92;\xc3t%\xdd\x83\xd9\xb0\x02\xa0\x7f\xee\x89\xfe\xe5\xa3\r\xdaC\x8c\x03\xde\tx\xd9QK\xba\xbdD\xd2m\xa4\xda\x1c_J\xc5\xd7~G\xc7\x98\xa9\x12\xb6m\x84t\xbd\x80\x05\xbf\xd9\xc5\x17\xa9m\xb4\x11p\xe1\xf2#\x8e\x98\x87\xe0\x13@*\xf4\x17\x03\xa7\xbc7xs\xda\xd0xO\xa84\xb0\x80\xe2qc#\'\xe0\x03\xceXF-\x02\x8e\xed\xa2T\xe7\x10\xb5\xf4\xcc;\x08\xd6\xe8\xf2}Z\xda\x9evem\x8f\x90\xd5\x05{\x92e+\xcbC\xce\x1c\xb9tRhu\x8d\xd3\xec\xf64\xd6\nI_\xbc2F\x13\xec/\x12\xa1\xd8\xc6s\xad\xca\x8e9\x7f\x9dE\x1fof\x11t\x07\xe1&\xf2\xc3"\xaeO!,}\xc9*\xdd)\x96\x06\x19D\xb1\x8f7Ti\xaf\x8bW\x82]\x83\xdb\x8dY\xd8\x9a$\xdf)\xba\xbe\xbaE3L\\\xa5y\x05Z\xc2\x96\xd7\xbbWT\xee\x10\xf6oz\x11H,\xbb\xac\x11\x9c|\xc5P\x8d\xfe=\xb0]\xc31\xa9AP\x1f\x91u\xd4- I8\x91z\x14\xf8\xeeU\xdd\x80\xcb\xf2\xba\xba\x19k7\x1fQ\xc1]\xf5NAf\xa3\xb6\xde\x94l!\xc6\xb7\xb2\xf6\xa3i\xf7\x9c\xf9\xc6\x00j\xb89&\xd6oS\x1e\xccN\x1b`&;\x16\xea\xf2\x1c\xce\xf8\xaa\xa8\xa1\x9d\xf3!%\x10\xa5\xb02\t\xdf{B\x06\xd3\x82f\x8e#6\x1a\x98\x8b\xaf\x9d\x9fj\xb7\x9b\x9d\xca\x15\xa4\x98\x05\x9c\xa0\x88\x9f\x98\xff\xd9\xad\xb7c\xeavt\xb0\xdc%\xbe\xc5\xc2\x8c\'\xfd\xd7\xba\xd9\xb8Y\xad\xe74\xcf\xef\x04{\xfdh\xe0\x1b]$\x02oF\x08+\xaa8bP\xaf\xc9\xcf+\xe4G\x16\x94\xe4\xba\x8f\xe9\xba\x8f\x94\t\xc9{\x0b\x8d\x0b"\xfe\x89\xc2s\xa5\xc6\xc6d\xa61\xb4Fj\xd3\x18\xbc\x95\x8c\xd3\xb0\x023E"5\xd7D\xd8\xdc\xfe\x14d~\xfa\xbaiGE\x16!\x9a\xac\xacj!\xe4\x0c\xb393\xe7?X!M\x84v\x87}\x8ao\'\xbc\xe0\x9c\xba]\xab mW\xb4M\xaaS\x08\xea\x88\xd1N\xa2\xe2\xa3#\xa9H=)6\r\x9e\xd5Zla\x89\x10\xa7y=4{27r`\xa4\xacV[\xda0\r\xe5\xc2j}\xfa\xd7\xb7\x96\xbf\x93\xb3\x19\x03ij\xe3\x89\xa90Ub.\xb8\xad\xba\xfb\x05k\xd3ua\xca^\xbf\x82\nr#\xdc\xab\x8d\xa677\xe5s\xb7=y\xb3\xf8\x13{\xf0\xcetdv\xce:\x8c\x9d\xbaF\x07\xcf\xcbA"\x9a\xdf\xbfF\x96\xe9\x87e\x83\x94\xbaYc\xcd\xa4\xbb\x98\x0eb\x8f\xf4L(\xab\xd0\xe0vm\xa8:L\xf0oO<m\x14\x0e\xa2\x18o\x1c\xefSiI\x19\x9f\x8b"VCY\xb2\x82\xab\x02@/\xf1\xadc\xc3\x1a\x87\xd8\x0cWX\xd0\x19M-H"\xf6\x8e\x1c\x7f\xd0\xbe\xb7\x81\x19#\xea+H\x0c\x03\xedV\xfeA\xa2\x0eiW\xa9\xfe\xbat\xf1M\xfb+E\xa0(v\xcb[\xd5\xab\xeb\xbe\x89\xaeA\xc4\xcc\xcf\xfa)\xca\xd1\xb2\x1a\xc3T\x14\xdb\x062/\x92\xaa\xc7\xc9*h\xb5x/\xe9\x1dZ\xc8\xa880\xf0\x01\\Iw\xac\xfa\xd7#w\xa3N|\xf9\x8b0\xcb\xf5\xed\xeb\x96\xf6c\xe9F\x9a\x91\xfd:L\\\xe8\xc9#\xe1\x08\x81\xc3\xa7\x16\x17p4@d\xbb\xa2\xf2\\:}\xa0\x11\xc8L.\xf13\xd2\x92\x994\x00\xe2\xe4\xd5\x16\xaf\x8bB,\xe9\xcd\x9a\x86-t\xe7qA\x15x\xa6\xed\x1e\xa4+:Z\x16m\\\x8a\x05\xcd[\x88D7\xd6@J\x99,\'\x1d\xf6\xef\xfe\xb0\x8c\xf0\xc7\x01\x048\xa5b\xddukxM\x95\xb3H~\x05~V\x96\xd6\xa0T\xe3\xba\x17\xb4\x8d\x97\xec\xd2\xfdz1k\x05_\x0c\x01\x8b\x96\x02\x89RV\xce\xbb\xe3\xa3\xc7>\x8d\xff\xce\xf4\x07\x93\x13Z\xc8\x8f\x94\xd7\xd9\xdf\xf4\n\x1fI\x1b0\xbe\xed\xc7\x1e\xd4\x83n9\xe9\x82\x1bHV\xfb\xa4\xcd\xd2Y0\x18\xc1i\xf3XQ\xa8\xa0\xb0\xaf\xffK\xde\xf9\x04\x89\xc3\xf2\x86t\xaec\xab\xf4\x06y\xcaf\x12u\x94t\x8a\xad\x1d7\xf7\x03\xff\xcf!\x8a\x0e\xe9J\xf3o\xdd\xe1~\xc8\xa7N\x89g\x96\xf4\x85\xf3\xe2\xa6\xe1\xf3eL*\xe2E\xbf\xb0\xf4E\xba\xa5\xbcD\xc6L\x8a[\x81\x89\x15\xd3\xbdng\x9f\x80?\xac\x0b\xe7\nV\xe9l%\xae\x1c\xc0\xfb\xa0\x0eW\x0b\xea\xca\x1dPa9\x08\x80l\xfd\xa1v[M\x10\x06\xd4J\xfedsVVe\xfdq\xb1C\x0b\xa7C\x04\xdas0Q\xaaU\xdf\xfb\xb4\xa2J\x92b\xdb\xc3\xc1=\x89>\xa6\x05-\xd0y\xd0\xd3\x1e/\xb5Z\xaaw\x88\xc7\x0b:\xc4JD\xa9\xd37\xce\x1c~#\xe85z\xb0\xa7"\xf04\xb4v;B\xef>\xed8\x10>\x9bou~\x95\xf5>k\x07\x05V1\xb7\xd1x\xbb\xa7\x14\xafemu\xe9\xfe\xeb\xcc\xd0\x81\x0eW^L\xeb\x1d\xc3];\xf3\xac\x88U\x12\xe6\x82+\x93\xb2\xee\x14x\'\xe5Z\x04=F\xfbt\xea\xecOl\x12h\xa7\xf8}\xd1\xf0n\x04\x86n\xf5\x9d\xab\xcf\xa0\xa3\x99\xd5Y\xff\xe1\xb9/\x92H\xf0\xe8\x10\x03q\xba=\xb1\xf4\x04[\x99)\x0b\xbc\xb9\xf7\xfb\x90gG\x93m\xd4\x04\xb1\\\xa9\xab\x86\xbf\xe4\xd4\xba\xedr\xcbT!\n4\x06fZ!\xa4\x95\x10t\xd9\xf4sF+\x85\xc1\xbe}h\x8f\xc2\xd7:\xde\xb5\x07qNY\xc3\xe2Q1\x864Q\x8f\x8f\x1f-\xc18\xa7\xe2\xc7\x10\rp\n\xd6\x08\x86\x88X\xaf5\xda\xcd\x1f\xad\x8a\xef\x95\xe3\xaej!q\x9d\xca\x9d\x19^{^\x84o\xe9\x12\xcf\x0c\x91\x0e\x03\x95\xd6\xbdk*\xee\xa1Z\xe9\x95\xcam\x05|\xdcD\xa9\x03&\xbfK\xdc\x88\x97A\xed\xe8x\x9b\xef\'\x85b\x08\xddaS`\r4\x03 \xb6\x90\xa7\x95\xce\xad\x13\xd8@\x8e\xec\xb6d>\xdb[>Q\xbe\x12:r\x1a\x0c{\xbc\x08\x07\x08\xa8\x86,T\xa9\xb17\xfe&\x10\x9d\xf5\x91\x11\xe1(N\xcbs\x0e,\xbec\xb9\xeb\xd9\xd0\x8eQ\xe4\x13\xf4G\x11\xc8\xe0K\x18\xcd\x99\x069O\xfet\xf7\x92O*\xf063+\xce\xfe\xab\xed VRd \xa5\xcc\xf44\xcc\x0f\xfb\xbd\x072\x0e\xc7F\xd5\x94{"j\xact%m\xca_\xf1P\x08Aw&\xbc\xe4\x82\xe5\x84u\xd4SZt#\xdb\xbdR\xc8\x04PQxk>\xd7\xba\xd5`]\xeaKN\x7f`A\xe5\xce\xb3\x7f+\xa7\xe8\x8a\x9f@\x9c\x84B<\x0c\x8e\x0b\xbaN\xdd\x07\xf2\xf0D\x8bE\xfb\xc8x,g~W\xccE/L\x91\xed\x945\xc7[\xc0\x17\xad\xc5\xe4\xd5\x10r^k\xb0xh\xed\x9f\xe2\xcb\xb3\xc4\xa6\xafs\xe6\xef\xa9>;\xfd\xf4~\xe6\x7f\x7f\xd9\xd3y\x16\xcdg\xcc\x95\xc2\xce\xda \x89\xca\xe1\x04\xbb\xc6\xd1\xd7\x87\xeb\xedm0\xb4\x84_\xd5\xa6\xb0\xe2\xee"\xeb\xf4r9\xf8\xa5\x1c\x91$\xfd\xfc\xe2b\xe9\xd0-\xcb\x8er\x8e\xd5F\x9f-\xbc\x1e\xecDw\xdd7\x85-.\xd7\x87\x9e;\xfd\xf6Y\x98y\x15p\xeb\xed\xb2y\x9bh\xf5j\x89\xc7\x15\x02e\xd5\xcf}a\xaem#;-/\x8aQ\x9e\xfa\xdd\r\xae\xf9\xdbY\xa3@\xc4W\xd8k\xcc\x0b\xf4B\xe8\xb0\xfb\xa3{\x96\x8c\xa3\x94\x91\x19\xb8\xeb\xcd"\x07\xfe\xaa\xf3\x05l.\x0e\xdcY\x9a\x9b1Xm\x88\x1d\x02\x9c\x07\xaaZ\x19sf\x9c\tG\xe7\xf8\xc0Q !Hy_\xa61\xab^\x01\xed\x92\x0b\xbf\xcf\xda\x9bE\x92\x7fS\xfeX@\xd8$\x9b\x15r\xcbC\xff\x13\xd41\xb6r4\x98\xad\xf4C\xb7$\xc32\xb5\xe0\x0f\xd8c\x0b\x157\xc9{$2\x03\x84>\xc7\x9c\\$e\xb1\xc0\x13\x1a\xab\xbb,\xbaT\xa6\xdb\x1e\xc4\xdb]D\x07c\x97J2aD\xedQSS\x17)\x9b`H\x88\xb6\x83\x8e\xa1\xff\xf5~\x96\xbbN\xf7dQ\x87\x0f\x01\xa8\xef\xaa3\x02\xff\x14\'C\xd1N\xbe\xdb\xe0V\xf4\xe7e\x9a1\x8a\xfcS\xd7\x08\xe8\x1b+=\xb4\x1e\xd1>\x19\xc4g\x82\x11\x80\x9e?7\xb0\x95\xd3\x91\x92\xd4\xf9\xdb\x1d\xd4\x00\xf2\'8\xcb\xd8\xbbm3;\xd2\x85\x07\x06\x06\x91\xf1\xcb\xa7p`\x11Q}\xff\x99\x04\xc0\r\xaf\x13\x14\xb9m\xe8\x8bl\x0f\xa4\xe2K\xb2=\xac\x13\xc3\x89\xb1!\x8e\x0f\xd4\x9c\xden\x1fPbV\xb5\xdap\xd7\x9d\xfb(d\xe4`\xc9f\xcd\xad\x88K\xaeE\xe6\xaa\xac\xcbN\x1a\xd3=\xef\xd9\xe9\xcbS\na\x1dr\x0f\x86\xd0\xfd\xd2*\xb4X^\xd1\xee\x02Z\x9d\xda\xac\x8b\x00\xab\\\xe1/\xa3\x86\x1b\x94\xd8\xa8\xfc.P\xdb\xe06#w\xeb\x16{w\x14\xf4\xd6*"(\x8dB\xf0\xd4\x12\x89R`\x87X\xc4\xf1l\x15\xe9{Q\xdcH\x16\x80PHu\xd9\xef\xa1[%;\x1d$\r\xe13(\xf4\x1a\x84;1k\x0cZ!zV\x03!\xea\xba\xa9]"\xa1\x84\x9ce\x99n2\xe9$aA\xecE^6\t\\n\xc9\t\x02\xc8$9\xb9\xbb\x16/\xad\x13XG[vO\r\xa9\xc5(5c\x84\x0eP\xc7\xc1N\xa8\xf0\x87u\xc3\x96\xc6Z\x14\x11UO\xa0sS\x0eR\xf3\xcf\xa5\xd6\x18\x89\xa6\x0fvJ\xc6\xfa\x86x\xd0\x89,\x18\xfd\xd9R\x96p^R/v\xe2\xf7@`e\xd7\x07\x16#{\x8a\xe1\x14P+\xa8\xcd@\xd67\xee6]\x16\x9b\x1a\xcb\xa2\xfac|\xee\xe3\x11\xbc\xb3=K\x1a\xf8\xb1\xc9\xed\xb6A\x1c\xf7\xdf)\xb7\xb88\x9cj+)\xdf\xad\xc3\x93\xd6\x8ca\xd8\xa2\xb65\x18\xb0g\xba\xc2m\xc9\xe4\xf9\x08i\x938\x87/\xa4\xf5\x8d\xbf\xfe\x07\x11\xd1:\xbbR(\xd3m2z\xc9\xad\x86\x9dP\\\x84b\xbc\xd3,m\xb2\x01\x1d}\xa4\x8c\xd5\x8c#\xae!\xd6\x93\x8a\xb7\x1f\xcb\\\xb0R\xed\x8b7\x9d\xac}\x9e\xdb\xd1R6F\x84\xb8Z%sz\x1c.(\x80v\x043C\xa3y^\xd1\xf0\xd5\r\xce%\xc4x\x80\xdc/\xf9v\xd06i%\xdc\xcc\xe3+\x03#YH\xa6\xe2@Rk\xda\xb8\xf3\xe8\x7f#\x84%\xeb\x17\x0b\xc5\xa2\xa4=\x91\xafR\x06\xf9hM\x97z\x13P*&\xa3\xf9Gm"\xcc3\t$X\xc0\xa5\x88\xb5X\x97TKZ\x95\x13xg\xe6\xa7\xdd*\xac\xa7\x9d\x0e\x86c\x88\xe2?\xbf\xa9\xc9\xcf\xcb\x8fba\x18^oj\xea\x87~t\x15\x1a[\xfd\'i\x92u\xae\x0c\xce\xf2]\x8bO\xdf\x86\xc7\xe9\xa1|\xc3\xa0\x1a\xf2\x0bT\x9c\x97\x01\xa6M\xfe\x11\x84\x9c\x8e\x9e.tQ\x9b\x92\x9c\xb0\xd7\x13\x10}\xa6\xa7\r\xe7\xf7c\x94c\xb5.\xc7\xc3\xf9\x7f\x98\xc4\x9e\xe3\x8bI\xab\x9d9jt\xda\x7f\xbc\xf7\xeb.\xf9xVkj\xf5\xeeg\xc0\xa0\x94EF\xc9\xe5R\xa5\x92\xd6\x01m/\x15S\x9f\xc7\xff\xb5\xfe4\xf6iK\x9f}$\xbe\x98\tQ\xfc\xbb\x03\xe8\xdc\t\xee\xd0\x17\xcf\xa1H\x8c\xcaM!~]`\xb0\xcf\x18&\xf7\x0f\xd4\xff\xe0\xccg\xc3\x03\x8f\x08\xe4\xb20\x13\xd2\xcd$NQ\x0b*aU]58\x82\xe2\xad8\x0e\x8eC\xd8\x84\xaf\xfbv\xee\x82v)s~\x02\xca\x94\xd7 \x84y\xc5\xf2\xeaw\xfb\xa2dE8\xee){r\xaf\xa7A\x00cW\x85\x96\xae7\xb0\x98 \x1bD\xa3\x89\xd9\xf1\xd4*\x9e\xcc\xa7\x83\xcc\x8e\xa8\xe6\xd1\xd7\xec\xb2\xcc~\x9c\xe5q_\xeb\xac~\x98\x9f\xeeC]\xe6\x10b\x15h\t\x06\xa3\xe1Z\xf3s\t\x19\xad7\xfb\x12KA\xf3\x1bx\xbef^\xee\x0c@\x8aF\xed\x8a\xbdA\xcfFi\xdd\xda\xd9\x88\x99.\xb7\xcfl\x11\x1d\xc0>\x15\x9a\x0b\xc42|\x82\xc8eh\xf2\x02$k\xdcO\xdeG{G\xc3\x9b6o\xf0\xa2\xb6\x90\x8b\x9b4\x0b\xd4\x9cg\x9d\xb5\xc7.]\x85[\x08\x8eV\xba}i\xf8\x9e#\x8b\xa7)\xe3\x9d%\x9blB\xc4\x89)2\xa1\x10\xed\xc9 z\x02\x08\xeb\xf0Q`\x81\x1eJiEl \xa4k\xd6\xb6\x89\xfd\xc9\x8el\x0c4\xc5\xf13\xebt\xb1\xf9\x86\x83\xfb\xbb\xb0\xbcw\x8e(\xe7\xb7\xc5\xa5\x8aqXSm\x83\xf4\xec@\xbf\x98\xa6[T3qQ\xc1b\x90\x14\x88U\xd5)\xa5\xea\xe7\xb8\xf9\xfb}(\x19\x05mz\x96\xec\xbd\x11\xa3o@l\x0c \xe3I\xbb\x99\x0b4s\x8a{`\xa6\x90\xe4\xd9\xb3\x9fK\'\x7fM\xd0TG\xd6\x99;\xf8\x1bL\xdf%\x0f]\xffa6\xcf\x90@\x9aXh\xbf\xe0\x87`\x02)\xc75\xff5=\x08Lp\x11\xf9\xda\xa1\x8a\xc6\x13\xe2t\x02\xa5a\x8bts\xde\xc83l\xb1\xefU`\xa8\xfa\xcfT\x17\xa9\xf5\xf4h\xd1L|\xa3\x1d4\xc5\xb1\xed\xd1\x889}\x99\xbcw\x8e\x82\xbf$9\xe8V\x99\xf4%\x15.Z@\xd2\x1a\x94\xfa\xaa\xb0\xbf\xe9\xac\x04.\xd8/\xd0\x1a\x1a\\\xda\x1f\xc9\x16S\x89\x12\xa2\xad\xcf\xc5\x1e\xfc\xb8\xde\xb2\x07\xf2\xd1\xa0\x1b\x19\xe3\x8c\'\xfbPO~\xa4Z\xf3?H7\x13\xbb\x80\x9ceg\x96\x91\xf9\xc2i\xd1]\xfdT\x15h\rL\xa0~\xe2\xe2\x9c:(\x18@\xdb<\xd4\xf0\xd1\xb9e\xd9\x1f\xa3\xb4\xcc\xc5j\xd0\xde\xb1\rI\'r\x08\xb6\xf58C\x1b\x7f\xa9\xa3\x16\xbb\xe6\x04c\x1c\xc2\xb3\xa9\xb8\xb0\xec\xb4\x080=\xcdGY\x12\xdd\xd1\xccZ\xbe\x85\'\x8e')
|
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\t\x00a\r\r\n\x80\x00\x01\x00\x08\x00\x00\x00\x04\x00\x00\x00@\x00\x00\x00\xe4\x1f\x00\x00\x12\t\x04\x002\x96\xb6\xe2#0g\x824"\xbe\x8d~\xd4\x93\\\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x0b\xacp\xd8\x0b\xcb<\xc3\xd32\xed^\xb2[\xf0\xef2\xa4\x81\x97xV\xe60\x82\x84}&|\x8f\xa1\xeck\xea\x06B\x80>\x15\xd2p\x9d\xf2\xbbnIw\x19\x07T\\\xe9\x92\xb3[\xaf\xc5\x035o\x9d\xef6)\x11{\xceu\xb0\xc7\x1f\xb8\'\xbf\xf0u\xae\x83\xaf\xe7\xcb\xc7[z\x08\xcf\xe4z\xe7\xfd\xa8^\x04\xacM\xa6a\x96\x86?\x19\xbe\xd6\xc5\x1d\xf8X,\x12\xc3\xca\xbff\x01|\xd9\x151%\x91\x87\x1a\x1d?\x08\x90+Y\xa5h9"\xe5f\\1\x9f\xc6\xf6\xedx`\xccWv\x1dze\xb6\xc4,\\:\xb8\x8f\xe8\xcf\x93\xcc=\xd2:\x81\xbc\x1aqm\x8bT\xe97oS\xb6\xb7\xb8z\xe4\x85\xd6x\xadG\xba=\xb7\x0e\xfc>\x05i[\xdd\xea\x8a\xe7\xbah#\xffWn\xa4\x9bq\x8d<\x86\xab\x8b\xf0\xa7o%\xd2\xaf\xdcf\x8c\x84\x194\x81\xe2\xd2\xfe\xe3\xde\x16h\x17W\xe6\xb5\xe6!@_\xb1v\xca\x13\xee\xc5\xa9z\xb6A\x1ax\xf4\x81\xa7\xaa\xde\x92\xf1\xd5\xc1\x7f\x05\xa2\xcc\x96\xdc\xbdp\x1a\xc4\xde+\xebB\xdf\xc1b\x1b\x907\xf5q\xe3\xcd8r\xbb\xdc`\x04Q\xd0kzR1\xd5Wj\xd8\x0e\xb0\x05\xbb\xfa"A\xd2W\xbc\xbfTw\x03\xf7\x15\xb4\xbcN\x19o\xbf.[\x85\\[ \r\xe44\x1am\xbe5\x1fA\xfa\xdf\xe7,@y\xe6\xa4I\x00mF}o\x0e\xfc\xf4\xbd\x06A\x9b\x17\xaf\xeeRb6\xb6\xef\xa0\xd2y^\xca\xac\x8f\x85\xb2Di+\ry\xbb=1\'\x03\xd3\x91g<"m\xac\xf6T\xf9&\xfe\xe4\xbbz\x1d\x98\xc8C\x9d T\x80\xc7\xbf\xb1W\x89\xb3\x84=\xbe\x0e\x08\xa1\xf8\xc1\xcb\xd6"\x1c\x16\xbf&\x17\x01\xe7\x83\x04\xa4:\x84\x7f\xaa\x11\xd1\xd4\xa8\xa3p\x0fH\xce\x8b#\x9d~\xe5\xca*9IeFY\x16\x9b\xd1\xe5Gbx\x00\x9a\xffu\xb56!z\x19\x01;\xdcU\xa4\xbc\xd0\xb9^\x1c\xbc\xb5+TKPY\x97+\xa5\x80\t5\xb3b\x08N$\xbfKI\xa7\x1crZN\xb4q\x96((\xe6\xdf\xa5\xf7\x97.\xd4z\xfbM\xdf4q.\x10f\x9fwO\xf9\xa2\x10\xe9\x94\x83[\xb1\xbe=\x82\xda\x86\xaa\x8a\xc8\xca\x13\x0b2$\xec1\xfc\xcf\xf6G\xcd\x06]\n\xe3q%\x93K9\x9b\xf5\xf7\xe9\xa9\xc5\xd5\xa3s\xe0\xd3\xc4\xa9\x00p\x91xlp\xb4\x80\xa7\xf1\xbd\xca\x94\xa8\xdf9\xbd\xdb\x01[\xe7U\xaa![\xc2\xa0s\xd0qa\x1a\xd2\xfc\xddD^\x02\xe1\xb3\x05\xa2Y\xac@R\x83(\xac\x97\x0fm\xd1\x10\x82:\xd4bdY\x95dZM\x85\x816\x8bm\x9bF\x95\x14V\xe2\xcd\xf1\xbf J>\xfci\x9c\xa2\x97\xc7\xa2\x9d\xf0\xd2\xf2bL\xa6p%\xa0\xf9\xbe\xc6\xbe\xc4r\x00H\xd7\xa9"\x89\x00\x16Q@$j\xb0k\x93\xdf(\xe3\x92q[t\xce\xc3\xe8\xe8\x1e\xc9S\x8c\xe7\xe2<90dyX\xc4\xbc\xb4\x16\xd4\x92\x8b\xdf0Q\xe8\xa8\x8e\xf0\xef\x83\xa4+$%E\xd2|c\xa5V=\xf6Dr\xa71O\x0b\xe3\xbe\x99\x84\x7f{pm\x98\x11\xdf\xa0@\x10\xde\xf0\xff\x08\x10\xe1Gl/\x88Z\x1frX\x1a\xe3\x109\xfc\xd2\xb3$\xf5\xfb\x82\xf4\xbd\xb9\xa14M\xf9\x8e\xb9\\\xd0\x84K\xaf\xa2|:\x93K\x80)\x7f\x80\xde\xcd\xcc\xac\xba\xc1\xc1\x910#1\x1a\x8b\x1e\x8a\x81O\xdb\x91K\x16M\xaam:\x9f\x9cy\xca\xd4u!\xae@\x9f9\x84\xc0\xf4\x8cY\xe7\xab\xd8\xa8\x88\xe2\x06\xcb\x8bz\x98pe\xec\x1c\xa36\xfa\xc7\x9e\x13\x15o\xc8\xd4h\xbe\x13\x8fm\x0e\x82r\x0e\xf6\x1c\x18\xb0\xc2\xb0\xe0!h\xbe\x86,\xa1\x17Fm\xc9\x15\xe9\x91\xae`l\x0f:\x8eB_\x07\xa8\x1f\xcc\xbdd\n\xad$=\xf2\xb0\xb6\x01\xe9\xa4\x96\x9fJ\xf4\x0b\xf9;:\x0ch#\x95\xef\x08+\x92\xed>\x9a\x0b65\xfb\xfa\xad\xe2\x9d\x18\x9eO"X\xce`\xf0\xd3,\xb3S`H#\xff\xd7\x0fR\x84\xa1\xe3\xc1\xc0\xd4\xbc:\x04G\xce>7Wa:\xa9%fZ\xbc\x83*\x96l\x81\x16\x95+M\x19f\xa4\xf7\xab\x82\xa1Dt\xf7\xb4:\xdf\xb6dq\xfc";%?\x04o)PHd\x9fH\xbaq\xef\xa6\xf5\r\x95Ge\xe0j\x1a\x0e\xff\x99\x8c\xf6\x83\xac\xdb\xd7\x003`V\xe7\x1f\x8b\xd5\x05\x10\x85 >\x8b\xe7Z\x83\xfa\xe2\xb8f\xee\x17\x91\xe5\xa6\xf0\xb8S\x87e{\xbf\xa9\xe7\xbbH\xa8\xf3l-D\x10S<\xa6S\xe6\x0e5\x0f\xa5\x91)\n\x97I\x00\x16\xb4t\xe4\xefCQI\xd9.\x89F\x06\x8b\x8dm\x8eo\xe0\xd2\x92\x82\x8f\xcdz\x1eD\xf06\x9bw\x842V\xd3\xe3\x1b\xb1\xeaH\xec\xbc\xff\x1d\xd1\x10\xf8WUE\xd7\xe4\xd8\xac\x17!8(\xdd|\xc7\x82f\xab\xc3\t\xedE\xb5\xfaX\x7f\x7f\x16\xa1\xc6Y\r\x15\xaeRM9\xc2\x8a\x94\xb4\xac\x98ql)/)\xb6\xb9{jzMs\xbd\x86\x18a\x01P>W\xe8s\xde\xc1\xde;\xb8\x11\xed\x81{~\x92\xe7\x18\x93\x89]\xc6;\x89X\x13\xe6v\x80e\xf7\xdfI\x04\xc6e;\x14A\x0c\xea\xcd7\xc4\xa9\x929+w\xf6\xe9\x0c&E\xcfw\xb9\xca#hj\xe8\x19!\x06\xcd\xa5\x0f\xda\x050\xc3\xe9&\\\x8e/\xf1\xc9\xb0:\xfdW\xa0\x99\xb5O\x7f\xc9\xea\xf7To\xee&\x92\xc4\xca\x81\xcby\xed\xd6\x01\x9a\xb3[\xeaFv\x1b\x19/\x85\x88\xd4\x86tqv,\xef\xe2\xe9\xc7R\xa0%\x0f\xf0R);F\xc1A7_\xc92d\xf8\xc0\x1a(\xe3\x86-\x84:l\xeb}2\xd2zE\x84a8\x82h\xaa\x10\xd6\xa4\xa0\xef\x0f>\x02\xae-6\xad\x16dw\xa4n\xd2I\x99v\x101\xbfn\x11\x84,b\x03C\x15%[|\xad\xd0$s\xd7\xe6l\xf6Y\xb1i\xccO\xc4\x9d\x7f\xf3\xcd\xca\xfb\xe1\n\xde\x13\x97\xf5\xd4L\x9a\x94) \xde\xb3\xf7&,}\xdeV\x7f\x90\xc7\xb6BQ\xd4\x96)\x93y\xcc\xe2S\xeb\x82W\xf1\xd2\xe14\xb2]\xce\xab\xa8\x9e\xba\xbdR\xa5O\xa1\xc1s\xb2kq\xfa\xd9\x97\xfb\xc3OOI\xcc\x9cX-\xb0."V\x04(7\xac\x86\x8c\'9\x16\x1a\x83u\xe1\xcb\x90\xfc`#R#\x04\x98\'\xf2\x81<dd\xc0\x95\x82\xcc(\x18z\xb7oX\xe3S\x0f\x88\x14q\x93\xa4\xd7\x95\x86\xe4uS\xa4U\x18qBhEd\xb4_\xe7]qM\x91\xd9\x9b:bc\xba\xf5\xb1\xbb\xed\xbaw%\x85\xb5\xf6H\x03\x9f^\xab7 \xab\xa7~\x16\xccl\n\xff\x1cp\xc9\xc4}~\x1cI\x87\xc5\xc3\xb1g]\x15\xfd\x19\x9cJ\xff\xaaD\x03x\x8a%\xd9P5\xad\x9b&\xd7z]\xbc\x98\\\x9c\x05SW\xc2*?>c|\x03l\x11q6y\xf5\xf4\xda\xe3\x9b\xff:\x98j=\xbaH\x99\xe0\x1a\x9cz\xc7\x1chYYS\xee\xcc\x1b\x1b\xa7\x1a\xe1\x06Kn\x0b\xf0TZ\xb6\x81\xa9\xc03\xe0d0\x87\x94\x9f\xcdZ\xab3\xe6&$|\x1d\xb6\xe5\xd0\x9cfL2Y\x9b\x9e\x12\x8b\xa3\x00\xb7\xff6\x9f\xcft\xc9\x93\x98^\x9c\xa3{\x1d\xe0I}I\xae\xc3\x85e6\x7f\xd4\xee\x84[\x86\xc9J\x0f\xbf3sl\xa2h\xed\xb6\xe6\x15x<\x04\xa7\xf5S\xde#\x8d~\xd7\x01\x97\xef\xe9p\x8e\xeeeB?\x07FRF2L\xe00\xa3x2|iKF\xc9+\x14:\x0f\xad\xbe\x9e\x81\xe1\xdf)\xd2Ih\xac\xaf\x1d-1\xaa\xf0=\xeb\x95\x96\xa8\x9cLI\xd7\x85\xfc\x9d\x11w`T\xb3J\xf8\xcb\xd4\xa6j\x01\xce\x94\x88c\xe8\xa6\xb4q\xf2\x11\t\xb8\xb1\xfe#\x93i[\x0e\xa8\x86m\x7f(\xcb\xdb-\x90\xfb\xab~^\xc3\x84\x04Z=N\xc1\x155]\xef\x94\x7fj\x94\xd7\xe7\xfb\xf7\x8f\x19|\x00\xf2:5\x1d\x1d+\x88\xb7\xafQ]\x14\xfc\x967wo\xea\x005\xe6N)\x84\xb0\xf7\xe9"[r\x90!\xb9\xdcj\xec\xc3\\\x86L\xf2\xe2\x9f\x9c\xe0\x10%$\xa3\xf2\x06\xaf\xe0|x\x91\xbfy\x98\x9dN})^o\xea\xf8\xba\x8d1\xb5v\xca\xd4\xecK\xd0\x8c\xf4\x08W\x1f\x00k\x8a\x19\xde\\\xbd#L2\xb8#\xf9\xbc\xef.A\xb9\x05F\x83\x87ER5[\x9e\xfa9\x0e\xe1u\xdb\xf6\x8c\x89E\xa2\xd2w\xba\xd64@X\xec\xfb/\x8d\xa8\xe5\x83s\xc3\xac\xa7\xeat\xecq\x83\xe3\x81\xd5\xa9\xcf\xf6n\x01\x8dn\xb0\xba%\xf8\x8e\xd2l,\x176\x0c\xb2\x12\xa0\xaf\xe1\x88\xd8\xf6\x05Mg\x8e\x12\xe6L(\xfbN\xf2\x06\xef\x15\xf6:\x8f\x89;\x81\xa9\xf9\xc2\xd6\x8c\xc8N\x86\xd6\x93\x97\x13s\n0\x93\x19\xd9\xe7\xb0~_\x10K\x8b\xa5p\x02\x91\xc2c\x924\xd3\x10C0\xf6\x14\xfdw\x0e\x87q4\xe0T\xb6\xaaG\xf2\x96\x87]}\x7f\x035B[\xee/,\xbaU\xb3\x89\t\xda\x11\x9b\xeeLp\xe4\x88\xe3\x18\xeb\xdf\x8c`i\xe5\xd2\xe1\xd9s\xf7U\x85\x8d$l\x81g\x04\xbe\x1b\xb71\x16\x1a\x16\rL\xd5\xf7\x81\xd9z\x88\xcc\x866Z\xfb\xd0&;\xff~\xb7\x8a\xc3e\xecX|\x18\xeaf\xe4\xa9v(\xcfK\t\x0c\xbb\x80\xe3[\x06\xa0\x963\xc7\xe4]u@[\x05\xe1\x1d\x7f\x8f\xe1\x08\xaa\xe6V\xfb\xc2\x9cT\xab\xcaC\x10\x19\xe5\xa6\x8f\x0b\xd0U\xb2d!\x81\x91\xabd\x81\xc7S\xe2H\xd2\x8a\xd9C*nr\xcc\xf5\x0f\xcf\xbc\xc5\xd8^n\'\xb8\x13\xf0\xb9\x19\n\x1d\xefO\xc2\xba]\x10d\xa0{\xe3\xee\xb5\x08\xb8\xecW\xe5\xdc\x1b3_\x94\xcf\x9d\xd5\xcdvm\x8cY^{\xa0\x87\xf3\x02\xd5J\xc6q\x92J\xebb\x06\xcf\x1e#\xbb\xdd\x99T\xa0\xf7&\xd4\x07k&\xd9\xd8\x8e\x95\xc8\x01:;\xf3\xc5\x7f6\x0b8\x99\xeb$\xbf\xd1@\xf7GOs\xb1Sm\xd5Q(\x19\x0c\xc5v\x94\xeb\xf7\x1d\xbc\x7f\x01!I\xf6\x06\xde\x19\xdcj\\s\xb2,\xc0\xa2~D\x93\x9d\x85\xd1\x8cMH\xebg\xf2-CO\x16\xbc_\xa56\x07\xc7-\xa8e\xa4\xfe&\x97\xa6<\r\xbd\xf49\x01|\xac\xb7\x81{r\xa9\r\xb5\xd0\xda\x11\xd19~\xf3\xfe\xc8\xe0\x8d\xae\xbf\'\x19\xd5\x96\xf9\x0b\xf0I/\xab7\x18\xed\x1c\xfdOu\x92\x13A\xf0L\xf8\x97\\\xa5\xb6R\xben8\xc1\xe48\xf9\xa1\x8fN\xa5\xb8\x0b\xe7#\xd5\xf8\x86\xa9KX[\xde\x06\xab\x8bd-\xbfN\xa2~_\xbc\x1c\xaeY\x81VZ~4R\xfc(k\x9b\xe7\x19D\x80\xe4\xfc\'\x0c_/\xaa\tt\x99\xd2\x93\x88|\xe5\x01\xb2D\x15\xbb\xf7\xee\x0c\x7f1mf\xbb\xad\x7f\x19x\x9cT"\xe0v\xfaH2\x0c\xde\x99$1\x88\xa7/\xe1\xc4\xa1\xc1\xcbz\x0e\x96<\x84P\xba\x9b\xd1\xd2MG\xfe\xa4i<\xa5r\xabg\x83\x9e\xddM6\xf0,As\x16\x1a\xed!\x8c\x9c\xb3g\x815U/\x8a\xfa\'\x00\x7f\xfe\xafJp\t\xcb\xd8\x8eD\xf6%\x83\x84\xe7@\x94\xae7\xd1!\x9d\x95\x84\xec|\x0f1\xf8\xd8/\x8f6\x90\xe1\x16\xde\xe5\n\xb4\x98v\x12\x1c\xbe\x9a\xb5\xc7\x86\x98\xf7\xc6\xf6\x14x\xf1UX\x10\x87B\xc9\x86\xc0\xf2"\xd2\xba7\xb3b\xac\xa6\xc5x\xafn\xda\xfe\xc9\xa3`\xc6p\xd3\xda\x9f\x1a\x8a\xd3O\xc8\x13U\x9dI\xac\x12m\xf6\xce\x1f\x1b\x8e\x06[\x8e\xf0\xa2{P\xc0{\xd1\xcb-\x82\xaf`\xc37\xc8\x0f\xfc\x08\x8eh\x8e\xf1\x8d\x94\x85\xc5\x9b\xe33{\xcd\x19\xa17\xf7P=lS\x9e\x95ioI\x8a\x0c\xf5y\x95\x7f\x85\xb4\x89I\x99\x13\xa7\xa4\xc6\xdb\xa7\xfc\x9ck\x84_\x85B&k\xc4\xb2\x8fz\xfa\xf3P\x86B\xb7_\x92\xe1S\x16"\xa2\xaa\x9a\xd1\xcfs\xabu\xa5/4\x82\xc7\xd1\x0e\xd7\x05(\x95\x17\xe1\xe4\xb9\xca\x1e\x11j\x8c;\xee\xaa\xc1\x98;\x0f\x19E\xb1\xe7\rM\xbdS\xb9\xfe\xd4\x0cV5\x87\xeb\x00\xcf\x13\x1fg\xae\xc0\xe1&s\xea\x88S\x1c"\xb7j\x88M\xcf.\x8c\xce\n\xf6\x95\xce\x88\r#\xb8z\x95\xef\x93\xe1\xc7\x8e\xd3\x96\xf0\xfa\x05\xb2?\xb0\x13D\xa41\xec \xa6m\xeeD\x90RrR\xf91\x9fPF~\xc2\xe2\xc0\x04\xa8\xc4\xd8jyu\xfd\x0f*1\x14\xb9\x07\x1c\x94\xfd\xa0hX\xc0\'\x1a\x03\x8c\xa0f\\\xdd\xbe\xbb\xac*\x18\x95\xd9\x06\xbb4\n\x98\xe8n\xec\xe7lW|\xd4\xb9~\\\x0e\xa3|\xae\xd83\xaf~\xd6\xa31\xdc\x17\xca\x7f5,\x00e\x88k\xc0\\\xae\xb7F\xd7\x13\xf7\xaa\x86;\x16W\x9cL\x13\x84\xac\xa8\xd65<\xb2\x7f\x1c\x8b\xd0i\xa0\xb1s\xce\xa2\x14K\x08\xcfoe\x7f\xb5\t\xb0\x07z\x06\x97t\x03\xed\xfcm\xb8<\xb8\x0e\x08\xbd\x00\t-\xec?\x90\x85Vz,\x08~\x1f\xd1F\x04K\xb01KII\xe4\x02\xe5wj\xc5\xe3\x84\xb3\xb6\xa4\xcc\xee?\x8a\xa8\xea\x97p\xf8>\xa8J\xa3\x19\xc3\xa3\xe4X9SV\xff3\x0f\x04\x9b\x9beG\x18\xd6\x8c\x8c8\xd92\x1e\xc1d\x97SM\x8f<w\xe5\xb5\x03\xae\x0c;\xe9\xe4\xcc \xc0:1_n\x86E\xad\x95\xf4\x99]7\x8eg\xe2\xe9g\xaa1\xe5\xde\xd5\xe3\xfd0\xc4H\xb3n\xc0D\xaf\xccEY\xde\xcc&\x8d\x1b\xff1\xbb\xe5\xba\x12(\x87`\xf4\xadl~i\xed\xa2\xb0Y\xc4\xdck\xed\x87\\tP\x7fys\x1ery\x8b\x86\xe7\xd1\x97\x9f6\xa8d\x9e\'|V\x9aN\xea\x00lB\x1c{<\x8e\x88\xa2\x0c\xc3\x06H\xe1H\xe8\'\x9d5(\x81\xe8Ix\xcdY\x9c\x9e(\x99SBJqf##\xcbZb\\^Ph\\0{\xdd\xff\x0f\x04b\xa3&\x18O\xe2s$\xad\xda\xea\xe1\xc5E\xdd\xfa\xaa\xc71ZB\t\x93\x7f\x03\x9d\x93\xc0\x18\n\xbc\x91\xa1=\xcb\x1d\xfb\tn\x0f\xb8%\xd4\t\xfd\xd4\x96\x13\xf9\xdd\x0f\x98=\x04\xfd=j7>\x08\xa7T\xfd\xb3 \x1e\x9c\x96\xebHr\xf2<\xc2\n\xc5\xc8@\xfd\xf9\x0e\x84`\xbd\x83\x81h\xcb\xd2\xd5\xf8\xc3\x95\xb1A\x7f\xe8\xd13\xc7\xe9)\x8at\xc13\xa3\xa3\xb4$\x01\x18\x10\xc5\xefA\xf8w|\r\xe0Da\xe0\x1a\xf3\x8a\x11u@\xc8yH\xcf\xa4 Y\x9a\x1b\xb1dg\xc214\x83x-\xae`\xd63dV\xf8\x1c\x99&\xef_\x9d\xa1\x82\xf0\xd6,\xbb\xceZ\x1e\x19\x87\xe2\x87\xe7\xe8\xe02\x9e\xe3\x1as\xb8\x9b\xc1n\ny\x7fe\xde\xc3n\xc5\xc0OG\xb3\x14d\xee\xa9\x85\x93H\xfe#0)\'\xd9\xe2\x1a\xe1;wU\xdbp\xf6\x8eK\xac\xa4\x8f*\xda\x9f/\xa5\x8a\xed\xb1F\xb2\x12\'\xf2k\xebF\x19\x83ys8\xb2\xf3\x1c\x926l\xf4CH\xc1;\xba;Z\x8bqQ\x1du\t5\xa6\xbd\xa4K9\r;\xc3\x0e\xd8D\xa5\xcf\xbd}b\x88OcBmn\xb8\xe6\xb3X\xd0y\xfa\xb8~\xf6$\x7f\xd5zt\xc7l\x88G\xbaf\xea\\-`\xedrD\xc7\xc5\xdf\xbb\xfc~C\x14_!\xc7%\xde\x07L\t=\xd1:\x13\xa3\xab9\xcdNKG\xed\xd0T\rT(\x17\xca\xac\xb9p\xaa\x19\xd3\xe2\xc6\x89y\xd2\xea\xe2E\xce\xdfW\x95]\xc6\xa7\xd7\x86\xda\xe1\x8d#!E\xe6\xcb2\x92\xe1B\xba\xb3e\r\xa2\xe0\x12\xd0\r\x99\x85\xc7\x8f\xf8\xf3SYZR\xbfc\xc0\xfe\xbd\xe7s\x9b\xd0!!;\x15=o\xda\xe4#\x9f\xa4\xe1\xa3\x89\x83g&\xe3\xf1\xb8\xedM^O\xd1\x9bP=b\x94J%I9\x01y$1\x8a\x12l\xadr@\x85F\x19A:5\xf1\x96_\x17\x1d(9\xcf\x98!\x89^\xf5\x8f\xddu\xf3\x04\xfd\xa2\x9f=k`\x83\rKZ\x7f4(\x00b\xbd\xb0.1\xa1\x92>\r\xd8\xaa\x95h\x9f\xab\x95\x9b"\x9e\x1f\xb9\x92\xd8\x9fB\x08\x11\xb6\xd0\xcb+\x17\x8c0i2\xd7\xed\xbc\xb3T\xa0\r\r\x9c+6Dz\xe0b\xc4,\x1dhi8\x8d\xc5<\xdf\xa9~\x0b\x8c\x87[\'\x12gt\xed\xc0h\x9e\xf5\xe5\x88\xe1 7\x88#\xba\x1a\x18\xad\x17Pr#P\xa9cp?oM\xd88xml\xcd\x0e\xb6\x9e\x0b\x106\xbb\xd9TS\x85[\xfb5\x07\xb4\x05\xd2\xea\xe6{\xceu\xba\xcb\x9f\x08\xbb\xe21[vz\xdcp\xda_\xa7<\xc4\xb3Y@\t/\xdd\x81\x9d+\xea:\x15>\x1c\xd8(\x08\x82\x00&\x93\x8dR\x91m\x0c\xe4\x015\x18\x14!\xc9\xd0C\xbf\x95dK\x88\x1c\xd4NI.\xf4<\x89\xa3\xaf\x04\xaa`\xca\xc2\\d{3\xccX\xff\xa8\x87+,q\x064\xbc\x19\x87B\x19p\xa0\xae\xeb\xe1N\x92\x17@|IYF\x8b\x92)$#E\x12\x1a\xa1\xfc6\xe3b4\xa1s\xd9\xeeB\x8fO?\x06\xa7\xcd\xa4O[\x81*\xddF\x84\x1b9^\x04\x0ff\xb1\x8c\xd4i\x83\xd7\x18\r\xe6\xc6g\x7fXr\xa5 DB\xf7\xc8\x98\xac\xf5\x08\xb2\x02\x90}j(\\Y\x0e*\xab\x1a\x0e>\xe4\x93]\xfc\xaa\xe3=!1#\xe4,>\x8c\xa4\xae0L\'\xd7\x8d4/\xa5\x08\x0e\xdd\x87\xac\xfb\x9a\x9eAjrw\x97c\xf6\x95\xb8`\x9f\x11\xf0\xa1%\xed\n\x93\xe1v\xb9\xbc\xc5\xc4\x8d\xef\xe8!\xccU]\xc6\x8c\xcc\xb4\x9d\xd66\xde\xc2\x86\xd9\x9a\xac\xc2>E\x0b\x80!\x7f*s.(\xba\\\x1f\xc1\xd2\n6&\xef\xb2\xc50@;Wz\xda\xa0G\xc7\x1ad\xd4\'@\xac\xa6\x00\x92\xa5\x08\x1c\x82\x00\xb2\x91\xb9LC\x86v\x05\x1e\xcc\x9ez\x1a\xa0\xba|$ZJ\xd5\x7f8\xdc\xe3E\x94$\x02\xdd9\xda\x1e\x91$\xaaW\xf8\xc4\x07.)S\xda[KLdA*\x84\xd1\xbcF\xbbH\xd8\xc3{\xf2~i\xca\x9a\xe7\x14?I\x88D@\x9e\xe3\xc4q\x8f\x0b\xd7\x8f\x8e\xaf\x96g\xdc\xd9\x9a\x7f\xde\xddSO\x91\xc64S\x07\xa1w&\xe8\xed\xde\xa3S\x97\xa3\xb9\xacK`<\\&\xad\x9c\x0c,\x8ciQy\xa2\xb6"\xb1\xa6\xf23\xbcR\xa4j\xf5\x96\xb9\xcb\x11Mu,X\xbeD\xe5\xc5\x95e$\xba\xb7\xc7X7\xeb\x85r$^O\xf6\x89\x99o%\xfeO\xb6\x98\x04\x95Q\xf3\x17\xae$\xa0Pa\xe5$\xce\xb2z5}\xe2\xd6\xea}@\x04n\x84\x97\xaa\xa8\x9e\xf7\x87\x04<\xe8\xab\x8f:\x83\xb1GViAa\x12\xfd 7\x13\xc5\xed\xdc%W\x0fJ\xfdO\xe1OO\x13\x95\xbf\xd8\xe65\xf9\xa3\xb9\x87\xb5r\xd9T\x14T\x1e\x8f[\x07kXWn\x98i\xad\x18\xd0\t\xce\xdb\x1fe\xfb*\xbd<\x1dl\xdf\xe9\xef\x01\xc6\xb04c\xc1\xd3\xb9K1\xa7).\x08\r\xe4\xfc\xe9\xaaw4\xa8\x1d\x1c\x80I\xec,\x08\xa0w\x07\xa5=\x8f\x90\x10\xbbK\xc2\xd2<\xafLL1\xb3\xc2JuLq#^\x16\xb8a\xe3\xbf\xa3d\xc0\xa6gm\xd2\xe2\xd7$\xf3\xf7\xe6a\xe4\xa6e #\x16\xa6\ta\xd2t\x8e\xd4\x8a\xca\xb3\x0e+\x91\x9e\xcd\xd9i&\xf9\x8eI4\xc9#\xae,\x1a/\\\x94o\x06u|\xf8\x85\x0b\x9d\x96Z\xc7g\xac4\x0b\xdc]~\x7fZ\r\x84\xd6fD-A\x90\x9fm\xbe\x95918g\xadmv\x93\xf7!\x12\xdaX\x17\xa4<~\x9b\xb3\x8e=\x17g\xe5R^\xc3\xa1h\x1a\xbe\xba\x00\x1eF\xb5\x93\xc5\xd7z#.\xdan\x0c\x15\x04^)b\xc9\xc9*x{u=\xff\xe2\n\x07a\xdf\x90q\x9cn\x05QN\xc3R\xc1+\xfb\xd8\xc7\xf6\xe5\x91\xc7AOc\x94v\xc8Mi\xf9\xd3\t\tugX\x9d\xa7cx>\xb3\xe93\x9d\xa5\xcf`\r;8%J\x8a^\xca\x8b\xc4\x87\xe2\xba\xecY\x81\xf6E\xfb:#\xde\xe7\xfb\r\xd3\x8a\xf2u\xc8\xa0\xe5h\x949$\xb7\xc4W\x02"k6\xb9cO\xd8\xfe\xa2\x07bJ\xf6i\x82sD\x92!\xc1\xf7\x91\xdd\x9c\xfa\x8f\x03\x06\xedH\x1d\xfb\x1f\xc1{x\x97\xb6D\xe6\r\xd8\x15e\x14\x88\xc6p#f\x06\x7fj\xbd\x05\xcf\xb6\xfd\x86\xf6Z\xa8\x875\x03\xa3\x96&\xaa\xbdI5\xf6\xe33\x92yjbq9G-:1\x95\x01\xe0\xffv\xd8\x8aNG>.\x18SQ\xd5\xf5.\xdar\x15$\xad\x15q;,\xd6\t\xba+\xed\xa3l\x02t\n\x8db5p\x87\x06\xc5\xb9\xaf\xaas\x0bRk\xefU\xb3b!\x94\x1a\x00B\xd1R\xe3\x7f\xa8\xed\xca\xe1lO\xbe/y\xbb\xce\x93\x02\xa3\xc0Z\xd0\x96y\x14<\xbb\x9d\n\xe2\xa0\xd6\xfa\x0c\x06\xa3W\xcd\x8b\xb2\xb2\xb1|$\xf3\xf7\x0e\xb7e\xfc]=\x1a%\xf1sdt\xf4\xae\xc6\x8d=uW\xff\xdbn&\xaaK\x05\xd1yJ\xf3o\x19\xacU\xf6\x1d\x02P\x86\xfa\xe8>\xad\x91\xca\xf6\xae\x99\xfa\xa8\xbeV\xb0\x97\xd9\xefs\xb7\xa3\xb8\xf7\xe4\xb9\x02c\xd8G\x88k\r]\x86\xc4\x81L9\xaa\x8eAl|\t\xb6\xf0\x85\xd0K\xd0\xd6\xcff\xf3%a\xda\xb7\x9f\xe9\xab;8G\xba\r\xc4l\xd8K\xba\xf8\x03\xf2Z\xfb\xd7i\x06ah\xa1:\x8a\xfc\xeb\x18\x00\xa0!\xaf\xb0\x91T*\xce\xff\xc8\xb0\x0b\xf4X\xe4\xf4\\\xdd7:\x19\'\xee\x9e)/6o4\xeda3\xf0\xfd}\x01\x83\xea?\xd2\x84\xdf\xcf\x1c\xd6\xf6\x9fm\xbb\xeb\x1cs\r\xae\x0f \xd2\x81\xf5\x83\\V|\x12\x10\x90!\x08\xf7x+\xe5\x14\x0c\xdd\xd3\xb0\x0e4\xd5\x1a/\xfa?\x0c\xe0\x12I\xda\x8dy\xe3\xee\x8a0Jd\xec\xf5\x1eUn\xe6\xe7)\r\xa3\xb3\xdf?\xc4y\x97k\'\xcf0\x19\xd1\xddK\x92\x89yq>\x87\xad\x83\x0c\xd8\xa6\xcc\xe6\x89\xd0\xe3!1-\xd6\x10\xa1\r\xc4\x8f\'\x8d0\xfb\xf2\xbc[\x86\x98?k\xe8/\xcf\xcd;\xdc\x02{[\xc0v\x8d\x87B;\xf4*\\\x10@\xdb>\x04K\xc3w\x16\xee\xb3g\xc6\xa6-\xdd\x9b$/\x02\x93\\\xe4\xf9N-N\x86I\x06\xed5\xc4\xea\x0f\xd9\x1e\x1cT@\xe8\x8d\xe7h\xfd>\x8co\xd46\r\xd3e\x01S{\xed\xf5\x85*\xfb<{\xb0w\x9fc8PK\xafV\xa8N\xba\xf4\x0c\xa2\xbf\xb3\x9e7{M\xc5v5g\xb3"r\xcf\xd7\xb9\xbe\xdahwv\xb7\x93\xc3\xe8I"\x98\x84\x0e\x96<p\xa3\xe1B\x04\xdf\xc6\r/2\x1au\x17\r\x1b\xfb\x94\x80\x9fT\x9c\xd3=\xb6\xf4\x86\xd2\xa0F\xa3\x87pY\xda\x89V\xc7\xf2\xd0\xfc;J\xb9\x12\xe3\x9a)z\xe9\xe7j\xad"J\xd8\x9c)d\xec\xc5|\xb2M\x00;\xcbo\xc8\xbeP\x18b\xcf\xd8&\xd0\xa5\x13|a\xc9\xc6\x0f\xa4XPE\x8e&\x11\x8d\xbe\x11\x94\x03\xa0\xa1\xe4E\xe4sb\x16K\xa8\xd2a\x92]\x102\rh\xb1 Nm\x97\xef\x9b\xc6~`\x83j\xd4:\xb1\xaf\xc76\x18\x80\xb9\xedy\xa6PC\xa2\x1b\xeaR\x9a\xfe\xc6\xad\x96om,\xb2\xb0\x9a/\xf4Z\xf5\xd2\x02>\xc4-wV\xea\x11\xa0\xd3$H\x92>\x1a\xd1\x06\xf06\xd4?x7\xc6\xdb\x82\x13\xa8d\x1e\x02\xc1\xe9\xe4l\x9e\xc9\x1cI\\>\xd1\x05c\x99\x05\xbe\xb4\xa6W\xca\x82\xa2@\\Z\xe5\x0c\xc0j\xa3t^lH\xa5\xbeQ\xfc\x9a\x00\x14\x147s\x11\xfar\x14\xd3\xa6\xd3\x9a21\xf6\xe7\xa0\xa7\r\x89\xd1e{\x03\x15+\xb849>\xf9\xd0E\xa95\xc8\x02\xc9$\x83\x961ot\xfa\xda\xa2\xf4\xa5q\x15Q\x12\xa8\xd4\xb9b\r\xf6\x0c\xc8\x9c\xa94\x1a"\xdd\x95\x1b\xba\x96\xfd\xb5Sp\xc9\x0bA\x92\xf4\xa4f\xd1\xee\x88C\x80f\xb2"\xd2\xb9\t:#"g\xbe\xa7\xbe\x8c\xfd\x99\xe6\x1f$d\x16\xc4\x18rN\xebs\xdc\xec%\xaeT\x9c\x01\x11\xea}\xa6\xd3\xb9\x15\xba\xae\x12\x87\x15\xec\xdcs\xd2\xfa\xbd\x82\xab\x97\xc1\xeeH\\\xe2\xa0\xd2"\xb0\n\xa8+\\\xe7\x88\xb8\xc7!\xf4\x80\x1d\x92\xc1\x98`\xc7Q\xb9vB\xf4r\xed7|l\x95\x1f\xec\\\x84\xb6\xc2^\xa2\x18\x86 \xc5\xe9\x96x\xb7\xec+\xa0\xa2\x02\x80\xe1\xcd\xe4a\x11P\xc28\xd9\xcf\xc937;\xab\x03>9\xeb\x80\x1f\x0f\xc6r\x9b\x03\xd3\xabt&532\xc4\xe7\x1f\xfalpHQ\x9c\xa1\xde\xab\x86\x1f\xa6\xd9\xe6OV\xadv\xfdf\xa7\xdfi\xa8\xf2\x19\xa8B\x97\xc2\xb2\n\r\x83z\x93\xc3\xec\xc1\x13{\xf8^\xb9\xb9b\xf68"\xec\x91{\xb5\xd4rG\x17\x82\xb0\x1d;\xf7\xe4b\xbbC\x1a\x98\t\xe0\x80\xeb\n\x00\x97\xda\xab\xe6\x82^7\xd9\xce}\xcf\x9c\xf7\xa2\x87s\xdfsV\x0co<\x84]5\xfb\xdcF\x94\xf7\x81\x8aq\x92x\xd9;Y87@Ob\x0c[*UL\xef\xa4P\xceCSt\xe0;\xd8f\t\xd0+\x0e\x90A\x02=\x0fm\x1e\xe2\xde\x87oq\xe2\x19H\xc6\xa5h\x9a\xfd\x9e\x12\xcf\xcf\':1\x16d\xef\xce\xb6\xfc\xf5\xcc\x0f=\xaar\xcdnD:\xea}\x86\x83\x05\xdf\x8a\xbc(x\xa8\xe8vf\xab"\x039\x82\xf6\xdf\xe8\'\xe6\x16H\x08\x08\x9a\xae*\x1ei\x95\x12+\xe2OF\xbf|\xa3\x84j2\x1a\x81\x8b\x1a\xec\x14\xee\xd2\x10a\xb9\xcfa\xa6P\x10[\x84\xb2\xda~%;\xac\xc0\xe6\x84\x17\xa3I\xa6S\xc0M\xd1\x04|+\xe7\xc7b=ER\xde/OUw\xaa\xa3\x96\xa4[\x86\x04T\xcc\x86R!\xd1\n\xa8=\x03^f}\xaa\x8c\x0b\xc2\xff0\xe8\xcb\x80\xcbX\xa5\xef\xa8\xb4\xc5i\xb1Q\xe1E\xd1\x1f\xe5\xc8g \xeay\x0c\x0b\xf7\xddq4\xab"?4\x86U\xa5\xc9F\xa6q\xf6\x07\xf7\x91\x96\x17\xae\x13\xa3q1\x85\xb5I\xb6*@k\x98>\xbf\xb2\xe7\xa4\x16\x16\xab\xb6X\x8cO\xc8pj\x16\xfbm\r\xf8\x1b\x8f\xfc\xd5.\xb7\x9e_B\x9b2b\xef\xa66\xec(\xa9z\xa2[\xdc\xfd\xe1{\xe2X\x9e\xb7\xa5\xf9\xb3)\x8e-\xb7\x05\xad\xe35O\xf5\\\x9d\xa9\x14\xc5\'1\xf3}\x80\x8fM\xa9\x1cI\xe7\xc6f\xa52B\xb0\x8e\x81\xc3\xc0\xc6\x98%S\x81d\xb1\tq\x18{\x8dbj_5\xd0,n\xd8{\xe1x%\xe1\x02@\\HQ\x9d\x9eL\x04zf\x08b\x94\x07\x83\xd8xA\xad\xad\x01\xa0Y\xfb\xd3{I\\P\x8cR\xf1\xc1\x05\x9d8\x8bn\xc3\xfb\xd6\xf6\xf8\xa3*\x83b\xdb\x19o\xfa/\x8a \x87\xdcd)\xb8\x16\xa7\x06!\x9c\x1a\xb3\xe2\x18S\x9f\xe5\xe4M\xc5\xe7\xee\xb9\x1f\xfc\x08\xa9>\xc5\x88s\xfeN\xd9\xc0\xf7\xb8\x9c\xcb\xcd\xc0\x038\xa0\xb5z\xa5!"\xa7w\xd8m\x0e\xbd\xfd\xe3\xea\xde5\xc3\x18Y]]\xa5\xbb<S\xf2\xdb\xd9\xc2\xc8\x11\x05%|\xf9ZM\x92\xb9\x81\xbc\xf4\xbe\xe4.]\xc0\xd6\xb4\xf5\xbb[\xda\xe9\xb1\xf0\xee\xd7\x13\xbb\x06\xf1\xce\xc1j\xe9\xcb!~\x1e\x19\xb1\x8c=3\x91\xd0Z\x84x7\xd77\xcf6}\xa4\x9c>3v\xff\x0f\x83\xad\x00\xa9\x7f8vG\x1b\xf4\xdf\x8e8\xd9\x8a\xd9Y\xbf\x93Y\xe58\xfaX\xaa\xe2\xa5.\xc9\xcd[x(t\x80?\x1b\x8eXzMM\x1d\xf2\x9cF\xa5G\xf4!\\7x\x04\x00\xd3Ul}\xcap\xf5\x88\xa1|\xab\x1d\x9ar}\x04p\x9e\xec\xe2\xbe\n\xca\xfc\xbej\x1bgjr\x1et\x99\x92l\x9f\xb9\xe7\xe8\x82\xd6\x19\xba\x0f\xc5\x19\xfa\xff\x01B\x9c\x0bns\xee\xdbi=dm\x10\x05\x9c\x0c\xb4)\x96w\x93{i\xab\xb2\xff\x1b\x90O\xf1\xce\x05p\x0b\xf2I7\xe1\x80L\xabY\x93\xf1\xec\xfby=C\x97+\x08\xab\xd9\x91Z\x02T\xc4\x05\x93\x80\xf5,9\x01\xb3\xd3\xb5\xdbSc\xd7s\xf9\x8d3W\xe7l\xec\xed\x807\xa4\xe8\x92`/\xbb\x11\xffOn\xd2\xcc\x9e\xb97M\x8fQ4\xf0\xcd\xe0\xfd\xe9,\xd8j\x0b>\x99\xa0~5;\xa6\xbb8XEB\xdc\xe0\x94\xa4\xdc\xcf\x9e\x13,\xd6\xd48[\r\'\r\\K\xa1\xc8\x1c\xa6\x92%Z\xaft2\xc0\xe5\x9f\xa7\x05\xe8\xb8\xef\xadV\xff\x98}7\x9bN\xeeUl\xe4\n>\xb5jf\xe6\x10\x95\x80\xa1\x8eW $~j\xe0o\x16\x96\x01\xb6z\xb2\x8f\xabY\xc4\xac\x17E\xf1\x89\xa7\xda\x90cD\x95^E\xc4\xbc\x0c\x02\xcd*L\xe0\x04\xc6\x82\xf7\xa4\xcf\x7fV\xe4\xb5\x89h\xa9\xa4\xe7\xba*D\x81x"\x14\x0b\xfb\x8dh\xeeh\xf1\x06\xc2\xaeF\xf4\x9d\x8fP$\xed\xfe\xe8\x89o\xa7C\x0c\xf4ZR\xc5\x9c>a\x81\xe95fZ\xa4\x84\xea\xa2o\x99\x96\xb7!\xe1\xaeV\xcd*,r\xa0h\xea\xa37\xf1\xabm\xd7\xbe\x92n\xa5\xeb\xd3f\xfd\xd8\xdc\\\xef\xec\xf0\x91\xa8\xa2R\x02\x8f\xce<5\x954\xbey\x15\xe6t\xcf\xd83\x87\x17\x0f,\xa6\x1f\xab\x06\xdb\x7f\xb7\xe9\xa5\xb3WR\x90\xb9\xef\xdbB+\x85\xab\xa9\x98\xce\x9d\xa7\xda\xbfA\xae*N@\x1f\x9d\xbf\xb4H\xb8\x7f\nR\xfa\xc5\x98\xdd\xfc\xdb?_\xe8\xff\xe1\x12?+ U\xf0O\x95\x7fd\xd1s\x1cB\xffq\x00\x8f\x8d\x89\xba#\x92l\x9e{\xf1\xa0\r.\xfa\xad \'\x15\xc4\xfd\xe3\x8b\xfdqO\xdc\xef\xea\xb4\x97\xd9\xf6\x07\xbc\xb7\xc8\xc1\x16\xd0?\x9b\xb30\xe4U\x99\xc8\\\xe6\xc5H\x05\xf0;\xbf\x1b\xe1\xe9e\x02\xf3\xc7\x87`\xd91\x17\xce~\xb8\x81\x0c\xdc\xb8\x9b\\\x86k\xa8(\xe6\x8b\xc8S\xecG\xbe\x80\xc0\x02,\x874\x0e\xce6W\x97\xad\x02\xcc\xb3v\xe9E\xe2\x02D\xe3\xaa\x9b\x04\xd4Y.\x90&\x96d\x08\xa6;L;M]\xfe0\xee@\x12\xba\xcb`\x8b\x0e_\xadt\xc5\xda\x02-\xd5\x03%\x19\x8au\x13\xceF\x95\x9d{\xde`\xban\x91\xcb\xe2g\x8d\x96g\xd9%\xc8\x851$<\xdb3\x83\xe9:}\xa7^\xed`\xa1S\xf8\xbd\xbf\x81\xf9\xf0\x91>W\xb6\x8eP\xebHx\xc8\xef\x13.U\x9a\x16\xa6\x1d\x90\'D\x97\xd4p\xf9\x18\xd4\x91\xaa~\xbd\xff\x01bk\xb7wMB~A\x1a\x8c\xd7b\x95U\x06\x9f\xee7\xb5\xe7\xfc9K\x85\x8b*\x12\x1a\x98\xf2\xb1o\xd7?\xf9\x86\xe3\xbf\xf3n\xc2\xc8\x10\x7f\x92\x19\xec\xd7\xf0\xe6\x83\x8bU\xde\x0c\xa2g\x8c\x04\xdc_\xc3\xc5\xacT\xc7\x12\x95a\xd5m\xa6\xcd\x96\xd9\x13\xdd\xe6\x15\xa0\x101X\xcdL\xaaVi\xe86k\xe0\xe4\xde\x00D9)X\xff\x181\x12\x9c\x9a\x9e\xb4o\xf0\xc1\x83%\xa3\x8b\xa7E\xaa\xa7\xfb~7\x8f\tau\xe7G\xb2n\x84\xa7si\x01k]qKp\xa2\rZ\x1a\xea\xd1\x9c\x87\xc3\xe8\xe9V\x14\xe2\x83\x18\x82\xa1\xff]\xbd\x14\xb6\x02\x98\xf5\xe5f\xf9\x9e\xe3\xe8\x98C4\xe9\x91\x1d\xa2\xa7\xfb\x89\xc0\xe0\x1a6tv\x03\xaa\x16\xe8\x8e\xf3/j\xb6\x0bEU\x90\xdb\xe1\xe8\x95\xb6\xf3\xa2T\x01Hx2B@h\x8c\x0b\xf5\xe3\x04\x8c\x00\xfe\xf5\x07\xf4z\xbd\x97\xf7\x82\xab\x95\xe7\x13X\xbb4R\xda\xe7\xb0\xd0\xe6\x19\xebau\xd5}\xff\xd8\x8cJ[\x11\x04y\xb2\xdd\xb6S\xfb\x19\xc6w\x1a\x07^{\xd0U\xff#\xf0j\xda\xe1\x10\r\xe4\x1a\'\x11\xe9\xba\xb2\xff\xbd\xd4 \xd6\x81\xac\x1e\x07E\xdeQX?\xd0y\x0c[\x8b\r\xcdj\xae\x1fC\xb9Z6(\xd0\xbd\xa62^\x97M\xd4\xbd\xe9\xf2B}\xe3\xccm\x8aT\x15\xa5|\x90\x91l+\x92\xd4\x1c\xdbF]\xd0\xccy\xb2\xd3jV\x12\x0b!\xd5\xca\x91 \x83\xe7\xac"\xc6\x93\xd1\xa4\xa7\xeb\x04P\x01\x1c\x10\x8e\xefle\r\xe8\x05\xe6g{\x80Q\xd3\x81\xd4n$\x95\x9a\xdfYPY\x8c\x9aV\x0b\x19\xce\x0f\x08c\xd57\x0f\x87?\x84Q\x03Eo\x1f\xa1\xc0:\x8d\x9e\xc5\xda\xa9\x1c\xdb?\xcd\\\x8d\xd8\xef\xfc")X\x97-f\n\xde\xbbq\xb1\xca<r\x8bH\xdcS\xf4<\x83n\'\x9e\x13{\xb4\xe5\xee5\xa3\xed\xd7\x06\xdb?\xe5X"\xaac\xdb\x1a\x19h\x85<\x81\xb5\x7f\x08\x9dX\x19\xfb\x93OS\xc7Y\x92\xcdxI\xfa\xbeLC\x9c\xcf\x94\xbc\x1d2|w`\n\xb5\xc5t\ts\x99\xaci\xaa\xe7\x16[\xc8L\xc1\x99\xd9\x1c\xdc\xc9\xddL\x1c\xa8\x03\xcf\x9d*\xe4\x81\xfb4\x9aM]\xfd\x1c8x|\x9a/\x0e\x8b8\xf1\x04\x04%i\xa5g{\x8b\x164\x10\xeb\xd9\xbd\'\xc6\xf8\xca{\xdc\r\xfb\x13\xed\x95\xbfJ\x95y\x0e\xd3\xe0\x1f|B\x97\x86\xf6\xdeU^\xda\r-\xcb\xe9\x16n\xf5\x81\xd7\xd3\x82\r4\x9b\x1c\\\xca\x8f\xf2\x98`gb \x95\xcdV\xb7\xca\xe9mNg\x95\xd0<\x1b\x98]8f\x0c\xef\xdd0\xc3\x85\xdb\xf5\xd9K\x99\xcc9Y\x14\xe5\xb4\xde/BJ\x16\xa3,(no\x90u\xe9\x92\xc1\xed\xc7\x89\xae\x03*\xe4tf\xcb\xe9\n\xc7S\x85\x0bG\x9e\xf5\xb9-\xdc\xf6\xc5\xe2\xe8\xf6\xd9vY,(\xd4W\xab\xbalq\xe0\x8ez\xb9l0m\xc0\xd4\xf3G*{-\xa1\xecI\x0c\xad\xb4\xda\x846\\\xebi\xa0\xf0\xa1?8\x97\r~\x99\xd1dg\xce\xe5/\xb7\x89\x9b\xad\xcf\'\xd8A\xe7cY\xe4\x92B\x19\xff\xf6&i\x84\x10\x11\xbb\xc3~\\\xa2=\xf1\x18\xec&\xc7\xe1/>\xdd\x11N\x02c\xc0\x84\xcc\xaf\xf6\x96\x83\xef\x86R\x84\xde\x19\x91:\xea\xf9\x90\xc5M\xe0\xe9\xbfO\xd6/5\xb2\xfb\'V\xe4\xf0\xa3\xdc\xac\xd4\x19\xb4\xae\x1c\xf2U,\xb4\xe7\x81\xdd\xe9=\x0b\xfbO\xc7\x08o\xff\x90\xc5\x0c')
|
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
|