Rubka 4.3.4__py3-none-any.whl → 4.4.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rubka/rubino.py ADDED
@@ -0,0 +1,1100 @@
1
+ import urllib3
2
+ import json
3
+ from typing import Any, Dict
4
+ from tempfile import NamedTemporaryFile
5
+ from os import system, chmod, remove
6
+ from base64 import b64encode
7
+ from io import BytesIO
8
+ class confing():
9
+ headers= {
10
+ "User-Agent": "okhttp/3.12.1",
11
+ "Connection": "Keep-Alive",
12
+ "Accept-Encoding": "gzip",
13
+ "Content-Type": "application/json; charset=UTF-8"
14
+ }
15
+ server = {
16
+ "rubino": "https://rubino17.iranlms.ir",
17
+ "messenger": "https://messengerg2c137.iranlms.ir"
18
+ }
19
+ android = {
20
+ "app_name": "Main",
21
+ "app_version": "3.7.3",
22
+ "lang_code": "fa",
23
+ "package": "app.rbmain.a",
24
+ "platform": "Android",
25
+ "store": "Myket",
26
+ "temp_code": "34"
27
+ }
28
+ th=b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x08\x06\x06\x07\x06\x05\x08\x07\x07\x07\t\t\x08\n\x0c\x14\r\x0c\x0b\x0b\x0c\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c $.\' ",#\x1c\x1c(7),01444\x1f\'9=82<.342\xff\xdb\x00C\x01\t\t\t\x0c\x0b\x0c\x18\r\r\x182!\x1c!22222222222222222222222222222222222222222222222222\xff\xc0\x00\x11\x08\x00\x80\x00\x80\x03\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x1f\x00\x00\x01\x05\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xc4\x00\xb5\x10\x00\x02\x01\x03\x03\x02\x04\x03\x05\x05\x04\x04\x00\x00\x01}\x01\x02\x03\x00\x04\x11\x05\x12!1A\x06\x13Qa\x07"q\x142\x81\x91\xa1\x08#B\xb1\xc1\x15R\xd1\xf0$3br\x82\t\n\x16\x17\x18\x19\x1a%&\'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xc4\x00\x1f\x01\x00\x03\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\xff\xc4\x00\xb5\x11\x00\x02\x01\x02\x04\x04\x03\x04\x07\x05\x04\x04\x00\x01\x02w\x00\x01\x02\x03\x11\x04\x05!1\x06\x12AQ\x07aq\x13"2\x81\x08\x14B\x91\xa1\xb1\xc1\t#3R\xf0\x15br\xd1\n\x16$4\xe1%\xf1\x17\x18\x19\x1a&\'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x92\x93\x94\x95\x96\x97\x98\x99\x9a\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00\xf0\'\x8c\xa6\x18\x1c\xabt5>\x9e\x86k\xe8\x93 |\xc0\x9c\xfbT+)\xd8c<\xafQ\xecj\xc6\x9a\xfe]\xd1\x93h;T\x9akp\x13S\xc7\xf6\x8c\xf8\xe7\r\xda\xa2\x8eL\xa0\x89\x80\xda\x1bwJI\xa4\xf3fg\xc67\x1c\x9agL\x9a:\x81n\x04YfuF\xfe\x1c\n\x80\x83\xb7\x90s\x9c`Q\x03\x98g\rS]\xc2\x11\x84\x8ar\xaf\xcf\xd0\xd3\x11T\xe74\xe0\x0e\xe0\xb8\xe5\x88\xc6i>R\xbc\xf0i\xf0\x96i\x90.\t\xc8\x14\x86i\xdd\\5\xb5\xb1\x89H\x1c\xf0\x0fZ\xcd\x8ap\x8d\x9d\xb8\x1d\xea\xe6\xa2w\x91\x91\xf7{\x8a\xa3\x1c~c\x0c\x0e;\xd3{\x89\x1a-2\xc3\xa61S\xf3\xb9\xaa0\x1d\xeeT\x9e\x0e(\xbb\x93t\x9b\x00\xc2\xafj\x859=y\xa1\xbd@\xbblM\x9c\xd2N\xc3;Q\x82\x9cq\xb8\xf0*\x91#\x1bGO\\U\xbb\x99\x8f\xd9#\xb7\x07\xa3\x17n:z\x7fZ\xa5I\x8c\xb5-\xb1Xcq\xf7H\xc9&\xab\x10GPjq.\xf8\x94;\x12Tm\x03\xda\x9f9\xcc#\x07\xa9\xe9@\x15*\xfd\x8a\x01\x04\xf26p\x17\x19\xaa>\x95\xa5o\xb5t\x99Y\xb3\x96\x93h\xe7\x8a\x10\x99C\xe5$\x03\x90=ibe\x0c\xd9\x19\xe0\xe2\x92A\x83\x9e9\xedH\x83,=;\xd00l\x9c6z\xd5\xe5\xc5\xcd\x81P~h\xf2qRi\xfa-\xe6\xa9pm\xac\xe12:\x8f1\xdc\xb0T\x89?\xbc\xecxQ\xeeMtvz~\x9f\xa5\xa3%\xac\x03Z\x9d@\xf3\xae&c\x05\x8c\x07\xeaH/\xf8\x95\x07\xd0\xd3\x11\xc6A\x0c\x93\xc8#\x867\x96C\xd1QK\x1f\xc8WI\xa6\xf8C_\xdd\xe6\xff\x00b_\x92G\xc9\xba\xd9\x87\xf3\x15\xa1>\xb0\xeb\t\x88\xebR\xf99\xff\x00\x8fm\x16\x01m\x0f\xd0\xb6\x14\xb7\xe2\xa7\xebT\xae\xf5-&\xddAm*y\xd8\x9e\x1ak\xd6\xcf\xfe:\xa2\x84\x82\xe5]c\xc3\xba\xf5\x94"K\xdd\x16\xfe\xdd\x00\xcbH\xf6\xec\x14{\x13\x8cV,\x12yA\x8ex#\x15\xd2\x8doO\x80-\xc4v\xba\x9d\xa3\x1e\x15\xac\xf5&R?\xef\xa54\xf95\x0b-P$f\xfe\x1b\xb2\xee\x07\x97\xaa\xdb\x88\xa4\x1f\xf6\xdd\x0f\xea\xc4\x0fj\x1e\xe0r\x04\x92I=M[\xd34\xe9u+\xa1\x14c\n9v\xec\xa2\xba\x91\xe0\x83s\x7f\x1cPG=\xb4\xc7\r\xf6;\xa2\x0f\x98=b\x95~Y\x07\xe4}3I\xa9\xcdk\xa0A=\x84Q\xbcw\x92\xe5]1\x8d\x83\x1d\xfb\x83\xedB\x8fV\r\xf49\x89<\xb9.\xe4\xf2\xc7\xeeA\xda\xb9=\x87CT\xd8\x8d\xc7\x1d*h\xd7\xf7L\xdb\xbbt\x07\xadAI\x8c|N#\x90\x16\x1b\x97\xa1\x1e\xb5bF\x8eW\x05S`\x03\xa7Z\xabR#g\xe5n\xe7\xad\x08\x08\xfd\xea\xfc\xd8\x87M\x823\x82X\x97\xfc\xea\xac\x11y\xd3$c\xa3\x1a\x9a\xfe@\xd3y`}\xc1\xb7\xad\x02+u\xeaz\n\xd1\xd1\xf4\xd3\xaaj\x1eP\x99-m\xe3S,\xf72\x02V\x18\xc7V#\xa9\xea\x00\x1d\xc9\x03\xbdf\xe7\x8c\x01\xd6\xba\xfb\x8b(\xf4\xb8\x1bL\x9ds\x05\x92\xa5\xc6\xab\xb5\xb6\x99f?r\xdf?\xec\xe7\x07\xdfy\xec(\x195\xce\xa3b\x9aP\x89\xa2\x9a\xdfC\x07u\xad\x82\x9d\xb3j.\t\x1el\xec:/^\x9c\x0e\x8b\xdd\xab\x9e\xd5\xf5{\x9dU\xe1\x8eGX\xe0\x851\x1c\x11\x8d\xb1\xc7\xdf\xe5_\xeb\xc9=\xc9\xaa\xd7\xf7\xf2\xea\x13=\xc4\xc5|\xc7a\xf2\xa8\xc2\xaa\x81\x80\xaa;\x00\x00\x00zT\n\xad)b\xa0\x96\xcfjb/i\xf3-\xb9\x91$\\\x92\xb9P}j\xbd\xdc\xedrw\xb1\x1d;WS\xe1\xef\x00j\xda\x9c\x1f\xda\x17\x05l\xec\xd4\xed\xf3e\x1dI\x1d\x87z\xe8\xafm|1\xe1+;h\x8a\x89.wnw\x99\x033\x83\xe8;t\xae\xda8)\xd4W\x93\xe5\x8fvsO\x13\x08\xcb\x96:\xbf#\xceYC\xd8\x9eFTg\x19\xa8l-\xbe\xd3r\xa9\xd4u#\xd6\xbd\x82\xff\x00\xc3\xfe\x17\xf1O\x86\xad\xe5\xd2\xa4\xb6\x8a\xf4\x00\xa7g\xca\xd9>\xab\xdf\x15\x81w\xf0\xefX\xf0\xf3$\xc6\x06\x9e\xd88\x06h\x97\xa0\xf7\x1d\xaaj\xe1%\x0bIj\x85O\x15\t{\xafG\xd9\x89k\xa9\xa7\x86\xf4&\xdf\x1f\x9do!\xe2\xdeC\x80O\xb7\xf7O\xb8\xfdk"\xfako\x122\x1b\x9b\xbf6F\xc2\xda\xdf\xcf\x85\x91Oh.\x0f\xe8\xb2\x7fN\x16\x97\x8c/L\x971Z\x0c\x01\x10\xc9\xfa\xd6&\x9bs\xf6[\xa0\x1d<\xc8%\x1b&\x88\x9cy\x89\x9eF{\x1e\xe0\xf6 W4\xde\xb6:b\xb4\xb8O\x1c\x96fKy\xe0x\xa6G*U\xc7\xdd#\x82\r@\x90\xf9\x99\xc3\xa0>\xed\x8a\xe95\xcbcyb\n\xb9\x96\xe2\xca0\xdef1\xf6\x8bl\xedG#\xfb\xcb\xc2\x9fl\x7ft\xd70\x08\xc7Nj\x18\xd0\xa3(\xff\x000\xce\x0f<\xd4\xcb\t\xba\x93\x11\xa6\x18\x8e\x14T*\xb9\x19\xed@vC\xc3\x1f\xc0\xe2\x81\x93X\xb6\xcb\xc8\x9b\xd0\xd4w\x00-\xcc\x98\xe7\xe64\x80\x15\x90m\xedH\xe5\x8f^\xbc\x9c\xfa\xd0\x06\xbf\x86\x12$\xd5\x8d\xfd\xc2\x86\x87O\x89\xae\xd9OFe\xfb\x8b\xf8\xb9A\xf4&\xa7\xd7\xcb\xd9\xd9\xd9XK!\x92\xeat\x17\xf7\x8cO-$\xa3(\x0f\xd1\x08?Wjn\x8d\x0f\x9b\xa1\xde\xc2\x84y\xd7\x97v\xd6\xab\xeb\xb4\x96c\xfa\xaaS\xfcK|\xb3x\x9bT\x9e5\x0e\xe6\xe1\x91\x18\x8e\x11T\xedP>\x8a\x00\xa1!\x190\xd8K$\xb1\xa1\x003\x90\x02\xf7\xe6\xbdW\xc3\xde\x0e\xb5\xd1\xe4[\xdb\xe3\x0c0C\x83%\xd4\xe4c\x91\x92\x15{\x9ez\xfdk\x85\xf0?\x95s\xe3\xed\x15o>x^\xed\x03\x03\xc8<\xd7\xa0|l\xbb\x91uK-&\xd9H\x85\x10\xbb\x05\xfe\'\xff\x00\xf5W~\x16p\xa7\tT\xe5\xbb\xe9\xe4qb\x1c\xa5R4\x93\xb2f\x7f\x8d\xfe$Gz\x91iz\x0co\x05\xac*G\x9ez\xbf\xa9\x03\xb5y\xbb\xc8\xf3j\n\xf3;\xca\xc4\xe7$\xee$\xf5\xad\xed\x0f\xc33j\xba\xd4\x16l\xf88\xdf.?\x85G_\xc6\xbd\x03Q\xd4\xfc-\xe1U\xb7\xb5\x86\x14I@\xde\x02\xc4\x1eB\xd8\xc1\xdcO\xadTi\xcf\x10\xb9\xaaJ\xd1B\xe6\x85\x0f\xdd\xd3\x8d\xd9\xe5P\xea76\xba\x94W\x11;D\xc8\xd9\x1bx\xcf\xf8\xd7\xbe\xf8\x17\xe2D3\xe9\xdb5\xff\x00\xdd\xc9\xff\x00?\x18\xca\x91\xee;V\x1e\x91m\xe1\xcf\x1fG\x046\xe8\x0c\xb1\xa9S\x13\xae\xd9\x10z\xe7\xff\x00\xd7X>6\xd1\x7f\xe1\n\x8d\xec\xe4m\xd1\xb8\x02&\xe7\xe6\x07\xaf\xe5SR\x9f\xb2^\xec\xae\x98\xb9\xa1]\xf2\xca6\x922<{i\xa7\xeb\xda\xb6\xa1\xach\xc4\x11\xe6\x12\xea\xa3\nTq\x90\x05p\x11\xa1,\xbc\x9f\\\x8e\xd5\xd2\xf8Y\xae\xae>\xdf\x04\x12\x10\x85C:\x91\x9c\x8c\xf6\xf7\xe7\xf5\xac\xf9-\xcd\xb5\xfc\xf0\x18\xd9Hr\x9f\xee\x8c\xf7\xad1\x94\xa9\xca\x8d<D\x15\xb9\xae\x9a\xf4\xeamE\xb8\xb7M\xbb\xd8}\xb6\xa4\xc2X\xe7h\x04\xb0\xd9\xb7\xef\x13\xfb\xd0\xbf\xca\xea}\x89?\x81j\xcf\xd5t\xf6\xd2\xf5K\x8b6m\xc2\'\xf9[\xfb\xeayV\xfcA\x07\xf1\xa5|\x0b\xc7C\x80\xad\x19S\x93\xb7\xb7\x19\xfc@5w]o\xb4Y\xe8\xf7\x85p\xf2\xd9\x08\xdc\xff\x00x\xc6\xed\x18?\xf7\xca\xaf\xe5^c:Q\x8e\x1c\xa9\x18\xc7\x14\xf9\x14\xee\xdd\xc1\x1c\x13P\xd3\xd1\x88$v#\x14\x0cyu\'p8c\xf9S\xa1\x88\xdc2\xc6:\x8e\xa7\xd0TQ\xc6\xd28D\x19&\xad\xbd\xca\xdbB`\x83\x96?}\xfb\x93@\x1bZD\xb0Ecn\x14\x12#\xd6-\xd9\x9b\xdb\r\xfe\x06\xb1\xf5\x88\x9a\xdf]\xd4 b~K\x99\x14\x8f\xa3\x11S\xe9e\xa5\xd2uh\x14\x90\xe8\x91\xdd \xf5(\xd8?\x92\xc8\xc7\xf0\xab~)\x8f\x7f\x88f\xbf\x8d?w|\x89z\x98\xe9\xfb\xc0\x19\x87\xe0\xdb\x87\xe1@\x86\xf847\xfc%\xdaS\x01\xf7n\x15\xb2G@9\xaf`\xf8\xcf\x046Z\x95\x8e\xa1\x8c\x89bo\x9b\xdcW\x9b\xf825\x8b\xc5zU\xc9P\xd0\xb3\xf4\x03\xaeF\x08\xf65\xe8\xdf\x1e\x83I\xe1\xbd\x0e\xe9A\xd9\xbd\xa3\'\xae\x0e\x01\xfe\x86\xba\xe1uG\xef\xfd?\xc8\xe2\xa8\xd3\xc4G\xd0\xe1\xfe\x1c\xea\xa8\x9a\xfd\xe4\xb2\xaf.\xa0\x0ey\x03=\xab\x9e\xf1\\r\xff\x00n\xdd\xb4\xe0\xf9\x86BW\xfd\xd3\xd3\xf4\xac\x9d\'R\x97K\xd4\x12\xea>q\xc3)\xfe!\xdcW\xa8i\x9a\xa7\x84\xbcK\x02A\xaa\xf9I \x18F\x91\xf62\xfbdu\x15\xd3K\x92\xbe\x19SN\xd2O\xef\n\x97\xa3U\xd4\xb5\xd32~\x11[\xdeM\xf1\x06\xd6KM\xc1\x13&_M\x98\xe6\xba\xbf\x8f\xb3\x99/4\xd8Ur\xb1D\xe5\x89\xf58\xfe\x95\xdei\x13\xf87\xc0\xfe\x1fi\xedd\xb6\x8cl\xdc\xe6&\xdf#\xff\x00Z\xf3\xff\x00\x1aK\x17\x8c|?6\xb1opV%bT\xba\xf5\xc8?.;t\x1d}\xea)\xe1\xe5Q8Gu\xfef>\xda\xf5cQ\xab#\x82\xf8uo-\xd6\xaf2G\x8c\xe1X\xe7\xbe\x0eqU\xb5\x99DZ\xe5\xf4d6\xc5\x9d\xc3(9\xef\xd6\xbb\x1f\x05\xe9\xd6\x9e\x15\xd2o5\x9b\xb62\xcac\xf9\x15\x7f\x88\xf6\x03\xf1\xae\x12\xe2\xe9\xb5\x1dV\xee\xe9\xd5\x10\xc8\xe5\xce:\x0c\x9e\xd5\xa6)J\x9d\nt\'\xba\xbf\xe6oI\xf3\xd6\x9c\xd6\xc6K\xba=\xce\xf6\x1f\xbb$\x90\x07_l\xd6\x96\xa6\x08\xf0\xb6\x82X\x93\x93q\x8e:.\xf1\xfdsYj\nK#\x03\x90\x01\x19\xfa\xf1Z\x9a\xec\tgk\xa3\xda\x07fu\xb2Y\xa5\x04\xfd\xd6\x91\x8b\x80=>R\x87\xf1\xaf)\x9d\x86 \xf7\xe9N\xff\x00V\xd9\x18>\x86\x9b\x8c\xfd*M\xad\xb3\x9e\x84\xf0)\x0c\x93w\xd9\xd3bcy\xe5\x9b\xfaT\x1dNM)\\\xb6I\xc0<\x8ay\xe7h\xc0\x18\x19\xfa\xd3\x02\xfe\x89w\x1e\x99\xa9\xdb\xddN\x9b\xe0$\xa4\xc8:\xbcL6\xb8\xfa\xed\'\x15\xd2_\xd9\xbc\x1a=\xc6\x9f\xf2\xc9y\xa29x\xe4\x03"{9\x0e\xe0\xea;\x80X7\xd2S\xe9\\s\x15\xdf\xbdr\x14\x1a\xea\xb4MJ\xea\xfd-\x85\xb1_\xed\x9d1X[\x06]\xc2\xea\xdc\xe7t\x0c?\x88\x80[\x03\xba\x96^\xc2\x9a\x13*\xf8b\xe2g\xb9)\x13`\xc6\xdepo\xee\x9e\xf5\xe8^/\xf8\x83a\xaf\xdaX\xe8\xda\x8c>\\\x91\xfc\xf2\xbe2\x8cq\x81\xf4\xef\\\xb6\x85c\x08{\x9dV\xc1q\xa7\xc9\x84hI\xdc\xd6\xaeO\xdcoo\xee\xb7q\xee\rq\xfa\xe4\xff\x00i\xd6n\\t\xdd\xb4}\x07\x15\xd3F\xbb\xa2\xd4\xd2\xbf\xa9\x85J1\xa8\xf5:\x8b\xef\x04\xad\xc4\ru\xa6J\x06yX\x89\xc8#\xd8\xd70\x9a]\xd4:\x9a\xda\xdcB\xc9&\xeca\x85M\xa4x\x86\xfbIu\x11\xc8^\x1c\xe4\xc4\xe7\x8f\xc3\xd2\xbd\xcb\xe1\xed\xf7\x86u\xad6MCU\x16\xd1\xbc}#\xbb\x00m\xf7\x04\xf5\x15\xd5S\xea\xb5\xe3\xcf\x0fv]\xba|\xbf\xaf\x91\x8b\x9dj:K\xdeG\x9fj\x9au\xeb\xe9\x96\xfau\x84\x129\x90\xe1\xb6\x0e\xc3\xd4\xfdH\xae3PmCKyt\xe9\x1a\xe2\xdd\x1b\x06H\x8b\x10\x1b\xb8$t\xafv\xf8\x99\xe3=#E\xb1\xb5\x87LKy\xe5\xdaWd\x18\xdb\x1e@ \xe4w\xaf\x02\xd4u)\xf5\x9dH\xdd]c{\x906\xa0\xc0\x03\xd2\xb9\xea\xaaq\xa6\x9a\x93\xe6\xfd\r(\xceswq\xb4K\xb6S\xdc\r5\xe4y\xdc\xa6\xe1\x1a\x06bG\xa9\xaa\xd6l\xbet\xd9\xe8T\x9c\x03V\xa4\x0b\x14\x11\xd9I\xf2\x95\x05\xf6\xfa\x12;\xd3\xc6\x93\xfd\x9de\x1d\xcd\xda3\xdc\xdc\x8cZZ\x0c\xeel\xf4\x91\x80\xfe\x1f\xee\x8e\xac}\x87<\xed\xbd\xd9\xba*YX\xb6\xa1\xab\x08\x9c\xf9V\xe0\x19\xa7q\xc0H\xd4e\x9b\xf2\xce=I\x03\xbdA\xa9^\x7fh_\xcdu\xb4/\x98\xd9T\x1d\x11G\n\xbf\x80\x00~\x15{Sv\xb3\xb4{E?\xe9/\xb4^\x10~\xe9\x07"<\xf7\xc1\xe5\xbd\xc0\x1d\xab\x14\x12\x07\xb5f\xcaD\xa20[\x19\x07<\x0cv\xa7\x1d\xb9\x07\xa1\xfe\xe84\xebr6eT\x13\xceA\xa4\x08$\xce\xdc\x02:.i\x81_%\xa9\xfb\x9d\x0e\xd2x\xc7L\xd22l\x00\xf5\xc8\xcd4|\xe7\x93Hb\xb3\x17>\xc3\xf4\xabv\xb2\x1bgI\x94\xb8e!\x94\xa9\xc1\x0c:\x10{U`\x81\x98\x02v\xa9\xa7\x16?*\x8f\x94\x0e\xf4!\x1e\x83\xe1\x8d~;\xbdN\xea\xe23\x1d\xb6\xab,[e\x0f\x81\x05\xe8\xcf\xf1\x83\xc2\xb9\xef\x9e\x0f^\x0f^\x7fU\xd2,\xae\xaf\xe4\x8e\xd86\x95\xa8\x06\xfd\xe5\x85\xf3mL\xfa\xc7#v>\x8f\x8f\xf7\x8ddX\xb6\xc9\xdd\xb3\x80\xc8A\xc5=.\xee\xeem\x16\xd6i\x0c\xb6\xc8\xdf"\xc9\xc9O\xf7OP=\x87\x15OT\x02\x9d\x1a\xf2\xd6\xeda\xbd\xb5\x9a\xdc\x9er\xeb\x80G\xa8=\x08\xf7\x15\xd3\xdek\x16\x1a~\x9e\xb6\xd0)}\x8b\x8d\xa0\xe0\x1f\xa9\xac\xdd>\xfe\xf7K\x87e\x9d\xd4\xa9\x1a\xa39\x1b\xb2\x87\xdbi\xe3\xadgM\xad\xdcH\xe5\xa5\x8fO\x94\xb1\xc9f\xb2\x8c\x1f\xc4\x85\x14\xf9\xb9P\xadr\x9d\xfe\xa7q\xa8\xca^b1\xd9T`\n\xb9\xa2h\x9a\x85\xec\xd1\xdc\xc7h\xff\x00eG\x05\xae$\xc4q/\xd5\xdb\x0b\xfa\xd2\xa7\x88.\xe1\x94y"\xc6\xdf#;\xe0\xb2\x8fp\xfa\x12\xb9\xfdi\xf6\xf7\xd7\x1a\xa5\xe8mB\xe6\xe2\xed\xf1\xf24\xf2\x92\x14}9\xe3\xe9\x8a\x95\xab\x1fC^\xeaM2\xd3V\xb9\x92\xd1?\xb4\xefwd\xc9"\xff\x00\xa3[\xfb\xe0\xfd\xf3\xfe\xf6\x14z5e\xdc\xeb\x8d\x03\xbc\x90\xdc=\xc6\xa1&|\xdb\xc6<\xaez\x84\'\x9c\xf6\xdd\xc7\xa0\xf5\xaa\xf7\xb7,\x1a\xe62\xc5b,YbC\x85Rx\xce+\'\x19\xef\xf9\xd0\xd8$N\x8c\x82#\x90\xf8a\x82\x01\xe3>\xb5_?\x95H\xa7q\xd8\x0e3\xc6i\xb2*\xab\x90\xa4\x95\xed\x9aLa\xbbke\t\xc5J$S\x92\x00\xc8\x15^\x9c\xa7\x07$P\x04\xac\xa6M\xbcaI\xc0\x14>\xcd\xbbW#\x1f\xad<8\xfb6\x18\xe0\x97-\x91U\xcbd\xd0\x04\x91\x8d\xf2*g\x82y\xa1\x94\xedfc\x92y\x18\xa9-W\xf7\xae\xdd\x91\x19\xbfJc\x9c\xa0\x01}\xa8\x01\xd0\xb1w\xc6x\n\x7f\x95\\\x95~[h\x97\xe5\xdc\xa1\x98\x8f@*\xad\xaa\x0f=C\x1e\x08\xc1\xc5X\x8d\xc4\x97\n\xf2\x11\x81\xf2(\xf5\x02\x9a\x11$w;"\x96YyF]\x81\x7f\x1e\x95\x92NI54\x8cc2FI85\x05&\xc0S\xda\xb54\xd6\x0b&\xd6m\xa0)\xe4\xfd+1\x00,7\x1c\x0c\xf5\xad("\x02F\x19\xcf@)\xa0dZ\x9e\xc5\x95U3\x9c\x02j\x90ROJ\x9e\xe5\xbc\xc7.F;T\nH9\x1d\xa9=\xc6<#/\xde\x18\xe7\xbd\x05ZWm\xa3\xa9\xe0R\x16b\xd9\xe4\x9atJwu\xc0\xeb\x9a\x00\x89\x94\xa9\xc3\x0c\x11@\x1b\x8e;\x9a\x96\xe0\x0f7r\xe7i\xe8MJ\xb6\xd2C\x07\xda\x9dp\xbf\xc3\x9e\xe7\xfc\xf3E\x80\xff\xd9'
29
+
30
+
31
+ try:
32
+ from base64 import b64encode, urlsafe_b64decode
33
+ from Crypto.Util.Padding import pad, unpad
34
+ from Crypto.Cipher import AES
35
+ except:os.system('pip install pycryptodome')
36
+ class cryption:
37
+
38
+ def __init__(self, auth:str):
39
+ self.key = bytearray(self.secret(auth), 'UTF-8')
40
+ self.iv = bytearray.fromhex('0' * 32)
41
+
42
+ def replaceCharAt(self, e, t, i):
43
+ return e[0:t] + i + e[t + len(i):]
44
+
45
+ def secret(self, e):
46
+ t = e[0:8]
47
+ i = e[8:16]
48
+ n = e[16:24] + t + e[24:32] + i
49
+ s = 0
50
+ while s < len(n):
51
+ e = n[s]
52
+ if e >= '0' and e <= '9':
53
+ t = chr((ord(e[0]) - ord('0') + 5) % 10 + ord('0'))
54
+ n = self.replaceCharAt(n, s, t)
55
+ else:
56
+ t = chr((ord(e[0]) - ord('a') + 9) % 26 + ord('a'))
57
+ n = self.replaceCharAt(n, s, t)
58
+ s += 1
59
+ return n
60
+
61
+ def encrypt(self, text):
62
+ return b64encode(
63
+ AES.new(self.key, AES.MODE_CBC, self.iv)
64
+ .encrypt(pad(text.encode('UTF-8'),AES.block_size))
65
+ ).decode('UTF-8')
66
+
67
+
68
+ def decrypt(self, text):
69
+ return unpad(
70
+ AES.new(self.key, AES.MODE_CBC, self.iv)
71
+ .decrypt(urlsafe_b64decode(text.encode('UTF-8')))
72
+ ,AES.block_size
73
+ ).decode('UTF-8')
74
+
75
+
76
+ def changeAuthType(self, auth_enc):
77
+ lowercase = 'abcdefghijklmnopqrstuvwxyz'
78
+ uppercase = 'abcdefghijklmnopqrstuvwxyz'.upper()
79
+ digits = '0123456789'
80
+ n = ''
81
+ for s in auth_enc:
82
+ if s in lowercase:
83
+ n += chr(((32 - (ord(s) - 97)) % 26) + 97)
84
+ elif s in uppercase:
85
+ n += chr(((29- (ord(s) - 65)) % 26) + 65)
86
+ elif s in digits:
87
+ n += chr(((13 - (ord(s)- 48)) % 10) + 48)
88
+ else:
89
+ n += s
90
+ return n
91
+
92
+ from requests.exceptions import HTTPError , ReadTimeout , ConnectionError
93
+ from requests.sessions import Session ; Session = Session()
94
+ from json import dumps,loads
95
+ from requests.exceptions import HTTPError , ReadTimeout , ConnectionError
96
+ from requests.sessions import Session ; Session = Session()
97
+ from json import dumps,loads
98
+ import requests
99
+ from requests import get
100
+
101
+ import os
102
+ import re
103
+
104
+ import io
105
+ import urllib
106
+
107
+ def get_video_thumbnail_bytes(video_path):
108
+ if os.path.exists(video_path):
109
+ try:
110
+ from moviepy.editor import VideoFileClip
111
+ from PIL import Image
112
+ video = VideoFileClip(video_path)
113
+ frame = video.get_frame(0)
114
+ image = Image.fromarray(frame)
115
+ byte_arr = io.BytesIO()
116
+ image.save(byte_arr, format='JPEG')
117
+ byte_arr.seek(0)
118
+ return byte_arr.getvalue()
119
+ except:
120
+ raise Exception("An error occurred while processing the video file.")
121
+ elif re.match(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', video_path): # if it's a download link
122
+ try:
123
+ response = urllib.request.urlopen(video_path)
124
+ video_bytes = response.read()
125
+ video = VideoFileClip(io.BytesIO(video_bytes))
126
+ frame = video.get_frame(0)
127
+ image = Image.fromarray(frame)
128
+ byte_arr = io.BytesIO()
129
+ image.save(byte_arr, format='JPEG')
130
+ byte_arr.seek(0)
131
+ return byte_arr.getvalue()
132
+ except:
133
+ raise Exception("An error occurred while downloading and processing the video file.")
134
+ else:
135
+ raise ValueError("Invalid input. Please provide a valid local file path or a download link.")
136
+
137
+ from PIL import Image
138
+ import io
139
+
140
+ def image_to_bytes(image_path):
141
+ with Image.open(image_path) as img:
142
+ buffer = io.BytesIO()
143
+ img.save(buffer, format="JPEG")
144
+ byte_data = buffer.getvalue()
145
+ return byte_data
146
+
147
+ class req:
148
+
149
+ def __init__(self,auth:str):
150
+ self.auth = auth
151
+ self.enc = cryption(auth)
152
+
153
+ def send_request(self,data:dict,method:str,type_method:str="rubino"):
154
+
155
+ if type_method == "rubino":
156
+
157
+ data_json = {
158
+ "api_version": "0",
159
+ "auth": self.auth,
160
+ "client":confing.android,
161
+ "data": data,
162
+ "method": method
163
+ }
164
+
165
+ elif type_method == "messenger":
166
+
167
+ data_json = {
168
+ "api_version": "5",
169
+ "auth": self.auth,
170
+ "data_enc": self.enc.encrypt(
171
+ dumps({
172
+ "method": method,
173
+ "input": data,
174
+ "client": confing.android
175
+ })
176
+ )
177
+ }
178
+
179
+ while True:
180
+ try:
181
+ response = Session.post(
182
+ url=confing.server[type_method],
183
+ headers=confing.headers,
184
+ json=data_json
185
+ )
186
+ except HTTPError as err:
187
+ raise HTTPError(f"HTTP Error {err.args[0]}")
188
+ except ReadTimeout:
189
+ raise ReadTimeout('Time out')
190
+ except ConnectionError:
191
+ raise ConnectionError('Check your internet connection')
192
+ except:
193
+ continue
194
+ else:
195
+ if 'data_enc' in response.json():
196
+ return loads(self.enc.decrypt(response.json()['data_enc']))
197
+ return response.json()
198
+
199
+ def requestUploadFile(self,file_name:str,size:str,file_type:str,profile_id:str=None):
200
+ return self.send_request({
201
+ "file_name": file_name,
202
+ "file_size": str(size),
203
+ "file_type": file_type,
204
+ "profile_id": profile_id
205
+ },"requestUploadFile")
206
+
207
+ def upload(self, post_file, post_type: str, profile_id: str = None):
208
+ file_byte_code = post_file if isinstance(post_file, bytes) else open(post_file, "rb").read()
209
+ upload_res = self.requestUploadFile("video.mp4" if post_type == "Video" else "picture.jpg", len(file_byte_code), post_type, profile_id)
210
+ if upload_res is not None and upload_res["status"] == "OK":
211
+ upload_res = upload_res["data"]
212
+ total_part = len(file_byte_code) // 131072
213
+ upload_data = 0
214
+ for part in range(1, total_part + 2):
215
+ byte_part = file_byte_code[131072 * (part - 1): 131072 * part]
216
+ header = {
217
+ "part-number": str(part),
218
+ "total-part": str(total_part + 1),
219
+ "auth": self.auth,
220
+ "hash-file-request": upload_res["hash_file_request"],
221
+ "file-id": str(upload_res["file_id"]),
222
+ "content-type": "application/octet-stream",
223
+ "content-length": str(len(byte_part)),
224
+ "Host": upload_res["server_url"].replace("https://", "").replace("/UploadFile.ashx", ""),
225
+ "Connection": "Keep-Alive",
226
+ "accept-encoding": "gzip",
227
+ "user-agent": "okhttp/3.12.1",
228
+ }
229
+ while True:
230
+ try:
231
+ response = Session.post(data=byte_part, url=upload_res["server_url"], headers=header)
232
+ if response.status_code == 200:
233
+ upload_data += len(byte_part)
234
+ RED = "\033[31m"
235
+ GREEN = "\033[32m"
236
+ YELLOW = "\033[33m"
237
+ CYAN = "\033[36m"
238
+ BOLD = "\033[1m"
239
+ RESET = "\033[0m"
240
+ progress = upload_data / len(file_byte_code)
241
+ progress_bar_length = 100
242
+ filled_length = int(progress_bar_length * progress)
243
+ progress_bar = f"[{'=' * filled_length}{'.' * (progress_bar_length - filled_length)}]"
244
+ print(f"\r{RESET}{YELLOW}{BOLD}Post File --{CYAN}{BOLD}| Upload {RESET} {GREEN}{upload_data / (1024 * 1024):.2f} MB {CYAN}{BOLD} total {RESET} {progress_bar} {progress * 100:.2f}%{RESET} in {RESET} {YELLOW}{len(file_byte_code) / (1024 * 1024):.2f} MB {CYAN}{BOLD}", end="\r")
245
+ break
246
+ except ConnectionError:raise ConnectionError('Check your internet connection')
247
+ print()
248
+ return [upload_res, response.json()["data"]["hash_file_receive"]]
249
+ return upload_res
250
+
251
+
252
+ class DateInfo:
253
+ def __init__(self, data: Dict[str, Any]):
254
+ self.jalali = data.get('jalali')
255
+ self.miladi = data.get('miladi')
256
+ self.ghamari = data.get('ghamari')
257
+ def getVideoData(bytes:bytes):
258
+ try:
259
+ from moviepy.editor import VideoFileClip
260
+ with NamedTemporaryFile(delete=False, dir=".") as temp_video:
261
+ temp_video.write(bytes)
262
+ temp_path = temp_video.name
263
+ chmod(temp_path, 0o777)
264
+ try:
265
+ from PIL import Image
266
+ except ImportError:
267
+ system("pip install pillow")
268
+ from PIL import Image
269
+ with VideoFileClip(temp_path) as clip:
270
+ duration = clip.duration
271
+ resolution = clip.size
272
+ thumbnail = clip.get_frame(0)
273
+ thumbnail_image = Image.fromarray(thumbnail)
274
+ thumbnail_buffer = BytesIO()
275
+ print(thumbnail_buffer)
276
+ thumbnail_image.save(thumbnail_buffer, format="JPEG")
277
+ thumbnail_b64 = thumbnail_buffer.getvalue()
278
+ clip.close()
279
+ remove(temp_path)
280
+ return thumbnail_b64
281
+ except ImportError:
282
+ print("pip install moviepy")
283
+ return confing.th
284
+ except Exception as e:print(e)
285
+ class SeasonInfo:
286
+ def __init__(self, data: Dict[str, Any]):
287
+ self.number = data.get('number')
288
+ self.name = data.get('name')
289
+
290
+ class TimeInfo:
291
+ def __init__(self, data: Dict[str, Any]):
292
+ self.hour = data.get('hour')
293
+ self.minute = data.get('minute')
294
+ self.second = data.get('second')
295
+
296
+ class DayInfo:
297
+ def __init__(self, data: Dict[str, Any]):
298
+ self.number = data.get('number')
299
+ self.name_week = data.get('name_week')
300
+ self.name_month = data.get('name_month')
301
+
302
+ class MonthInfo:
303
+ def __init__(self, data: Dict[str, Any]):
304
+ self.number = data.get('number')
305
+ self.name_past = data.get('name_past')
306
+ self.name = data.get('name')
307
+
308
+ class YearInfo:
309
+ def __init__(self, data: Dict[str, Any]):
310
+ self.number = data.get('number')
311
+ self.name = data.get('name')
312
+ self.name_past = data.get('name_past')
313
+ self.remaining = data.get('remaining')
314
+ self.leap = data.get('leap')
315
+
316
+ class OccasionInfo:
317
+ def __init__(self, data: Dict[str, Any]):
318
+ self.miladi = data.get('miladi')
319
+ self.jalali = data.get('jalali')
320
+ self.ghamari = data.get('ghamari')
321
+
322
+ class TimeData:
323
+ def __init__(self, data: Dict[str, Any]):
324
+ self.timestamp = data.get('timestamp')
325
+ self.date = DateInfo(data.get('date', {}))
326
+ self.season = SeasonInfo(data.get('season', {}))
327
+ self.time = TimeInfo(data.get('time', {}))
328
+ self.day = DayInfo(data.get('day', {}))
329
+ self.month = MonthInfo(data.get('month', {}))
330
+ self.year = YearInfo(data.get('year', {}))
331
+ self.occasion = OccasionInfo(data.get('occasion', {}))
332
+
333
+ def __repr__(self) -> str:
334
+ return json.dumps(self.__dict__, ensure_ascii=False, indent=4, default=lambda o: o.__dict__)
335
+
336
+ class IPInfo:
337
+ def __init__(self, data: Dict[str, Any]):
338
+ self.ip = data.get('IP')
339
+ self.country = data.get('Country')
340
+ self.city = data.get('City')
341
+ self.isp = data.get('ISP')
342
+ self.timezone = data.get('timzone')
343
+ self.org = data.get('org')
344
+ self.country_code = data.get('countryCode')
345
+
346
+ def __repr__(self) -> str:
347
+ return json.dumps(self.__dict__, ensure_ascii=False, indent=4)
348
+
349
+ def __request_url():
350
+ import random
351
+ return f"https://rubino{random.randint(1,59)}.iranlms.ir/"
352
+ from typing import Union, Optional
353
+ from pathlib import Path
354
+
355
+ _useragent_list = [
356
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
357
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
358
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
359
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
360
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
361
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.62',
362
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0'
363
+ ]
364
+ def get_useragent():
365
+ import random
366
+ return random.choice(_useragent_list)
367
+ class api:
368
+ def download_post_rubika(
369
+ share_url:str,
370
+ #return_choice:None = False
371
+ ):
372
+ body = {'url': share_url}
373
+ request = urllib3.PoolManager()
374
+ response = request.request(
375
+ 'POST',
376
+ 'https://api-free.ir/api/rubino-dl.php',
377
+ fields=body)
378
+ if response.status == 200:
379
+ response_data = json.loads(response.data.decode('utf-8'))
380
+ if 'result' in response_data:
381
+ return response_data['result']
382
+
383
+ def download_story_rubika(
384
+ username:str
385
+ ):
386
+ body = {'id': username}
387
+ request = urllib3.PoolManager()
388
+ response = request.request(
389
+ 'POST',
390
+ 'https://api-free.ir/api2/story_rubino.php',
391
+ fields=body)
392
+ if response.status == 200:
393
+ response_data = json.loads(response.data.decode('utf-8'))
394
+ if 'result' in response_data:
395
+ return response_data['result']
396
+ def search_page_rubino(
397
+ text:str
398
+ ):
399
+ body = {'user': text}
400
+ request = urllib3.PoolManager()
401
+ response = request.request(
402
+ 'GET',
403
+ 'https://api-free.ir/api/rubino-search.php',
404
+ fields=body)
405
+ if response.status == 200:
406
+ response_data = json.loads(response.data.decode('utf-8'))
407
+ if 'result' in response_data:
408
+ return response_data['result']
409
+ def _req(term, results, lang, start, proxies, timeout):
410
+ resp = get(
411
+ url="https://www.google.com/search",
412
+ headers={
413
+ "User-Agent": get_useragent()
414
+ },
415
+ params={
416
+ "q": term,
417
+ "num": results + 2, # Prevents multiple requests
418
+ "hl": lang,
419
+ "start": start,
420
+ },
421
+ proxies=proxies,
422
+ timeout=timeout,
423
+ )
424
+ resp.raise_for_status()
425
+ return resp
426
+ import random
427
+
428
+ class Bot():
429
+ """rubino class"""
430
+ def __init__(self,auth,platform="m.rubika.ir",lang_code="fa") -> None:
431
+ self.auth=auth
432
+ self.platform=platform
433
+ self.lang_code=lang_code
434
+ #{"app_name": "Main","app_version": "3.0.2"dd,"lang_code": "fa","package": "app.rbmain.a","platform": "Android"}
435
+ def _request_url(self):
436
+ import random
437
+ return f"https://rubino{random.randint(1,59)}.iranlms.ir/"
438
+ def get_link(self):
439
+ return self._request_url()
440
+ def _reuests_post(self,methode:str,data:dict):
441
+ request = urllib3.PoolManager()
442
+
443
+ if self.platform == "m.rubika.ir" or self.platform == "web" or self.platform == "PWA":
444
+ body = {
445
+ "auth":self.auth,
446
+ "api_version":"0",
447
+ "client":{
448
+ "app_name":"Main",
449
+ "app_version":"2.2.4",
450
+ "package":"m.rubika.ir",
451
+ "platform":"PWA"
452
+ },
453
+ "data":data,
454
+ "method":methode
455
+ }
456
+ elif self.platform == "android" or self.platform == "Android" or self.platform == "rubix":
457
+ body = {
458
+ "auth":self.auth,
459
+ "api_version":"0",
460
+ "client":{
461
+ "app_name": "Main",
462
+ "app_version": "3.0.2",
463
+ "lang_code": self.lang_code,
464
+ "package": "app.rbmain.a",
465
+ "platform": "Android"
466
+ },
467
+ "data":data,
468
+ "method":methode
469
+ }
470
+ response = request.request(
471
+ 'POST',
472
+ self.get_link(),json=body)
473
+ if response.status == 200:
474
+ response_data = json.loads(response.data.decode('utf-8'))
475
+ if 'data' in response_data:
476
+ return response_data['data']
477
+ else:
478
+ return response_data['status_det']
479
+ else :
480
+ raise Exception("Request Error Server")
481
+ def edit_info_page(
482
+ self,
483
+ username_me:str,
484
+ name=str,
485
+ bio=None,
486
+ phone=None,
487
+ email=None,
488
+ website=None
489
+ ):
490
+ """
491
+ - username_me : در این مقدر باید آیدی پیجی که میخاین ادیت شه وارد کنید
492
+ """
493
+ profile_id=requests.post(f"https://api-free.ir/api/rubino-search.php?user={username_me}").json()['result']['data']['profiles'][0]['id']
494
+ data = {
495
+ "profile_id":profile_id,
496
+ "username":username_me,
497
+ "name":name,
498
+ "bio":bio,
499
+ "phone":phone,
500
+ "email":email,
501
+ "website":website
502
+ }
503
+ methode = "updateProfile"
504
+ req_get = self._reuests_post(methode=methode,data=data)
505
+ return req_get
506
+ def create_page(
507
+ self,
508
+ username:str,
509
+ name:str = "codern",
510
+ bio:str = None,
511
+ phone=None,
512
+ email=None,
513
+ website=None
514
+ ):
515
+ data = {
516
+ "username":username,
517
+ "name":name,
518
+ "bio":bio,
519
+ "phone":phone,
520
+ "email":email,
521
+ "website":website
522
+ }
523
+ methode = "createPage"
524
+
525
+ request = self._reuests_post(methode=methode,data=data)
526
+ return request
527
+ def Download_story(self,username):
528
+ return api.download_story_rubika(username)
529
+ def get_comments(self,post_id,post_profile_id,profile_id=None):
530
+ data = {
531
+ "equal": False,
532
+ "limit": 100,
533
+ "sort": "FromMax",
534
+ "post_id": post_id,
535
+ "profile_id": profile_id,
536
+ "post_profile_id": post_profile_id
537
+ }
538
+ methode = "getComments"
539
+ request = self._reuests_post(methode=methode,data=data)
540
+ return request
541
+ def get_all_profile(self):
542
+ data = {"equal":False,"limit":10,"sort":"FromMax"}
543
+ methode = 'getProfileList'
544
+ request = self._reuests_post(methode=methode,data=data)
545
+ return request
546
+ def get_me_info(self,profile_id):
547
+ """- دریافت اطلاعات پیج"""
548
+ data = {"profile_id":profile_id}
549
+ methode = 'getMyProfileInfo'
550
+ request = self._reuests_post(methode=methode,data=data)
551
+ return request
552
+ def Like(self,post_id,target_post_id):
553
+ data ={"action_type":"Like","post_id":post_id,"post_profile_id":target_post_id,"profile_id":[]}
554
+ methode = 'likePostAction'
555
+ request = self._reuests_post(methode=methode,data=data)
556
+ return request
557
+
558
+ #--------------------------------------------
559
+
560
+ def comment(self,text,post_id,post_target_id,profile_id=None):
561
+ import random
562
+ data = {
563
+ "content": text,
564
+ "post_id": post_id,
565
+ "post_profile_id": post_target_id,
566
+ "rnd":f"{random.randint(100000,999999999)}" ,
567
+ "profile_id":profile_id
568
+ }
569
+ methode = 'addComment'
570
+ while True:
571
+ try:return self._reuests_post(methode=methode,data=data)
572
+ except:return "error"
573
+
574
+ def get_link_share(self,post_id,post_profile,prof=None):
575
+ data = {
576
+ "post_id":post_id,
577
+ "post_profile_id":post_profile,
578
+ "profile_id":prof
579
+ }
580
+ methode = 'getShareLink'
581
+ return self._reuests_post(methode=methode,data=data)
582
+
583
+
584
+ def is_Exist_Username(self,username):
585
+ if username.startswith("@"):
586
+ username = username.split("@")[1]
587
+ data = {"username": username}
588
+ else:data = {"username": username}
589
+ methode = "isExistUsername"
590
+ return self._reuests_post(methode=methode,data=data)
591
+
592
+ def add_View_Story(self,target_story_id,ids:list,profile_id=None):
593
+ data = {
594
+ "profile_id":profile_id,
595
+ "story_ids":ids,
596
+ "story_profile_id":target_story_id
597
+ }
598
+ methode = 'addViewStory'
599
+ return self._reuests_post(methode=methode,data=data)
600
+
601
+
602
+ def save_post(self,post_id,post_profile_id,prof=None):
603
+ data = {
604
+ "action_type":"Bookmark",
605
+ "post_id":post_id,
606
+ "post_profile_id":post_profile_id,
607
+ "profile_id":prof
608
+ }
609
+ methode ='postBookmarkAction'
610
+ return self._reuests_post(methode=methode,data=data)
611
+
612
+
613
+ def un_like(self,post_id,post_profile_id):
614
+ data = {
615
+ "action_type":"Unlike",
616
+ "post_id":post_id,
617
+ "post_profile_id":post_profile_id,
618
+ "profile_id":[]
619
+ }
620
+ methode ='likePostAction'
621
+ return self._reuests_post(methode=methode,data=data)
622
+ def get_Suggested(self,profile_id=None):
623
+ data = {
624
+ "profile_id":profile_id,
625
+ "limit": 20,
626
+ "sort": "FromMax"
627
+ }
628
+ methode = 'getSuggested'
629
+ return self._reuests_post(methode=methode,data=data)
630
+ def image_to_bytes(self, image_path):
631
+ with Image.open(image_path) as img:
632
+ buffer = io.BytesIO()
633
+ img.save(buffer, format="JPEG")
634
+ byte_data = buffer.getvalue()
635
+ return byte_data
636
+
637
+ def check_url_content_type(self, url):
638
+ response = requests.head(url)
639
+ content_type = response.headers.get('Content-Type', '').lower()
640
+ print(f"post type {content_type}")
641
+ if 'image' in content_type:
642
+ return 'image'
643
+ elif 'video' in content_type:
644
+ return 'video'
645
+ return None
646
+
647
+ def upload_file(self, file, file_type, profile_id):
648
+ return req(self.auth).upload(file, file_type, profile_id)
649
+
650
+ def get_video_resolution(self,download_link):
651
+ try:
652
+ from moviepy.editor import VideoFileClip
653
+ clip = VideoFileClip(download_link)
654
+ width = clip.w
655
+ height = clip.h
656
+ clip.close()
657
+ return [width, height]
658
+ except ModuleNotFoundError:
659
+ print("pip install moviepy")
660
+ return [668,789]
661
+ except Exception as e:
662
+ return [668,789]
663
+ def add_Post(self,post_file: str, caption: str = None, time: int = 1, size: Any = [668, 798], thumbnail_file: str = None, profile_id: str = None):
664
+ from concurrent.futures import ThreadPoolExecutor
665
+ if size == "Auto" or size =="auto":
666
+ try:
667
+ size=self.get_video_resolution(post_file)
668
+ print(size)
669
+ except Exception as e:
670
+ print(f"error data resolution auto [668,789]")
671
+ http = urllib3.PoolManager(num_pools=10, headers={'Connection': 'keep-alive'})
672
+ def get_file_content(file):
673
+ if file.startswith("https://"):
674
+ content_type = self.check_url_content_type(file)
675
+ if content_type not in ['image', 'video']:
676
+ return None, None
677
+ response = http.request('GET', file)
678
+ print("GET <<< Data byte.")
679
+ return response.data, "Picture" if content_type == 'image' else "Video"
680
+ else:
681
+ post_extension = file.split(".")[-1].lower()
682
+ if post_extension in ["mp4", "mov", "mkv"]:
683
+ return open(file, 'rb').read(), "Video"
684
+ elif post_extension in ["jpg", "jpeg", "png"]:
685
+ return open(file, 'rb').read(), "Picture"
686
+ else:
687
+ return None, None
688
+
689
+ post_file_content, post_type = get_file_content(post_file)
690
+ if post_file_content is None:
691
+ return "Invalid file or URL"
692
+
693
+ def get_thumbnail_content(thumbnail, post_file_content):
694
+ if thumbnail and thumbnail.startswith("https://"):
695
+ response = http.request('GET', thumbnail)
696
+ content_type = response.headers.get('content-type', '').lower()
697
+ if 'image' in content_type:
698
+ return response.data
699
+ else:
700
+ return confing.th
701
+ elif thumbnail:
702
+ return image_to_bytes(thumbnail)
703
+ else:
704
+ try:
705
+ print("GET <<< thumbnail Byte.")
706
+ return getVideoData(post_file_content)
707
+ except ModuleNotFoundError:
708
+ return confing.th
709
+ thumbnail_content = get_thumbnail_content(thumbnail_file, post_file_content)
710
+ def upload_file_concurrently(file_content, file_type, profile_id):
711
+ return self.upload_file(file_content, file_type, profile_id)
712
+
713
+ with ThreadPoolExecutor(max_workers=2) as executor:
714
+ post_res = executor.submit(upload_file_concurrently, post_file_content, post_type, profile_id).result()
715
+ tumb_res = executor.submit(upload_file_concurrently, thumbnail_content, "Picture", profile_id).result()
716
+
717
+ data = {
718
+ "caption": caption,
719
+ "file_id": post_res[0]["file_id"],
720
+ "hash_file_receive": post_res[1],
721
+ "height": str(min(size[1], 862)),
722
+ "width": str(min(size[0], 848)),
723
+ "is_multi_file": False,
724
+ "post_type": post_type,
725
+ "rnd": random.randint(100000, 999999999),
726
+ "tagged_profiles": [],
727
+ "thumbnail_file_id": tumb_res[0]["file_id"],
728
+ "thumbnail_hash_file_receive": tumb_res[1],
729
+ "profile_id": profile_id
730
+ }
731
+
732
+ if post_type == "Video":
733
+ data.update({
734
+ "duration": str(time),
735
+ "snapshot_file_id": tumb_res[0]["file_id"],
736
+ "snapshot_hash_file_receive": tumb_res[1]
737
+ })
738
+
739
+ return req(self.auth).send_request(data, "addPost")
740
+
741
+ def get_Post_Likes(self,post_profile_id:str,post_id:str,max_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
742
+ data = {
743
+ "equal": equal,
744
+ "limit": limit,
745
+ "max_id": max_id,
746
+ "post_id": post_id,
747
+ "post_profile_id": post_profile_id,
748
+ "sort": sort,
749
+ "profile_id": profile_id
750
+ }
751
+ return self._reuests_post(methode='getPostLikes',data=data)
752
+
753
+ def get_Story(self,story_profile_id:str,story_ids:list,profile_id:str=None):
754
+ return self._reuests_post(data={
755
+ "profile_id": profile_id,
756
+ "story_ids": story_ids,
757
+ "story_profile_id": story_profile_id
758
+ },methode="getStory")
759
+
760
+ def get_Story_Viewers(self,story_id:str,limit:int=50,profile_id:str=None):
761
+ return self._reuests_post(data={
762
+ "limit": limit,
763
+ "profile_id": profile_id,
764
+ "story_id": story_id
765
+ },methode="getStoryViewers")
766
+
767
+ def get_My_Archive_Stories(self,sort:str="FromMax",limit:int=10,equal:bool=False,profile_id:str=None):
768
+ return self._reuests_post(data={
769
+ "equal": equal,
770
+ "limit": limit,
771
+ "sort": sort,
772
+ "profile_id": profile_id
773
+ },methode="getMyArchiveStories")
774
+
775
+ def get_Page_Highlights(self,target_profile_id:str,sort:str="FromMax",limit:int=10,equal:bool=False,profile_id:str=None):
776
+ return self._reuests_post(data={
777
+ "equal": equal,
778
+ "limit": limit,
779
+ "sort": sort,
780
+ "target_profile_id": target_profile_id,
781
+ "profile_id": profile_id
782
+ },methode="getProfileHighlights")
783
+
784
+ def create_Highlight(self,highlight_name:str,story_ids:list,highlight_cover_picture:str,profile_id:str=None):
785
+ highlight_cover_res = self.req.upload(highlight_cover_picture,"Picture",profile_id)
786
+ return self._reuests_post(data={
787
+ "highlight_cover": {
788
+ "highlight_file_id": highlight_cover_res[0]["file_id"],
789
+ "highlight_hash_file_receive": highlight_cover_res[1],
790
+ "type": "File"
791
+ },
792
+ "highlight_name": highlight_name,
793
+ "story_ids": story_ids,
794
+ "profile_id": profile_id
795
+ },methode="addHighlight")
796
+
797
+ def highlight_Story(self,highlight_id:str,story_id:str,profile_id:str=None):
798
+ return self._reuests_post(data={
799
+ "highlight_id": highlight_id,
800
+ "story_id": story_id,
801
+ "profile_id": profile_id
802
+ },methode="highlightStory")
803
+
804
+ def remove_Story_From_Highlight(self,highlight_id:str,remove_story_ids:list,profile_id:str=None):
805
+ return self._reuests_post(data={
806
+ "highlight_id": highlight_id,
807
+ "remove_story_ids": remove_story_ids,
808
+ "updated_parameters":["remove_story_ids"],
809
+ "profile_id": profile_id
810
+ },methode="editHighlight")
811
+
812
+ def get_Hash_Tag_Trend(self,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
813
+ return self._reuests_post(data={
814
+ "equal": equal,
815
+ "limit": limit,
816
+ "sort": sort,
817
+ "profile_id": profile_id
818
+ },methode="getHashTagTrend")
819
+
820
+ def get_Explore_Posts(self,sort:str="FromMax",limit:int=51,equal:bool=False,profile_id:str=None):
821
+ return self._reuests_post(data={
822
+ "equal": equal,
823
+ "limit": limit,
824
+ "sort": sort,
825
+ "profile_id": profile_id
826
+ },methode="getExplorePosts")
827
+
828
+ def get_Tagged_Posts(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
829
+ return self._reuests_post(data={
830
+ "equal": equal,
831
+ "limit": limit,
832
+ "sort": sort,
833
+ "target_profile_id": target_profile_id,
834
+ "profile_id": profile_id
835
+ },methode="getTaggedPosts")
836
+
837
+ def delete_Comment(self,post_id:str,comment_id:str,text:str,profile_id:str=None):
838
+ return self._reuests_post(data={
839
+ "model": "Comment",
840
+ "post_id": post_id,
841
+ "record_id": comment_id,
842
+ "profile_id": profile_id
843
+ },methode="removeRecord")
844
+
845
+ def like_Comment(self,comment_id:str,post_id:str,profile_id:str=None):
846
+ return self._reuests_post(data={
847
+ "action_type": "Like",
848
+ "comment_id": comment_id,
849
+ "post_id": post_id,
850
+ "profile_id": profile_id
851
+ },methode="likeCommentAction")
852
+
853
+ def un_like_Comment(self,comment_id:str,post_id:str,profile_id:str=None):
854
+ return self._reuests_post(data={
855
+ "action_type": "Unlike",
856
+ "comment_id": comment_id,
857
+ "post_id": post_id,
858
+ "profile_id": profile_id
859
+ },methode="likeCommentAction")
860
+
861
+ def get_Comments(self,post_profile_id:str,post_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
862
+ return self._reuests_post(data={
863
+ "equal": equal,
864
+ "limit": limit,
865
+ "post_id": post_id,
866
+ "post_profile_id": post_profile_id,
867
+ "sort": sort,
868
+ "profile_id": profile_id
869
+ },methode="getComments")
870
+
871
+ def request_Follow(self,followee_id:str,profile_id:str=None):
872
+ return self._reuests_post(data={
873
+ "f_type": "Follow",
874
+ "followee_id": followee_id,
875
+ "profile_id": profile_id
876
+ },methode="requestFollow")
877
+
878
+ def un_Follow(self,followee_id:str,profile_id:str=None):
879
+ return self._reuests_post(data={
880
+ "f_type": "Unfollow",
881
+ "followee_id": followee_id,
882
+ "profile_id": profile_id
883
+ },methode="requestFollow")
884
+
885
+ def get_Page_Follower(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
886
+ return self._reuests_post(data={
887
+ "equal": equal,
888
+ "f_type": "Follower",
889
+ "limit": limit,
890
+ "sort": sort,
891
+ "target_profile_id": target_profile_id,
892
+ "profile_id": profile_id
893
+ },methode="getProfileFollowers")
894
+
895
+ def get_Page_Following(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
896
+ return self._reuests_post(data={
897
+ "equal": equal,
898
+ "f_type": "Following",
899
+ "limit": limit,
900
+ "sort": sort,
901
+ "target_profile_id": target_profile_id,
902
+ "profile_id": profile_id
903
+ },methode="getProfileFollowers")
904
+
905
+ def search_Follower(self,target_profile_id:str,username:str,max_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
906
+ return self._reuests_post(data={
907
+ "equal": equal,
908
+ "limit": limit,
909
+ "max_id": max_id,
910
+ "search_type": "Follower",
911
+ "sort": sort,
912
+ "target_profile_id": target_profile_id,
913
+ "username": username,
914
+ "profile_id": profile_id
915
+ },methode="getProfileFollowers")
916
+
917
+ def search_Following(self,target_profile_id:str,username:str,max_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
918
+ return self._reuests_post(data={
919
+ "equal": equal,
920
+ "limit": limit,
921
+ "max_id": max_id,
922
+ "search_type": "Following",
923
+ "sort": sort,
924
+ "target_profile_id": target_profile_id,
925
+ "username": username,
926
+ "profile_id": profile_id
927
+ },methode="getProfileFollowers")
928
+
929
+ def get_NewFollow_Requests(self,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
930
+ return self._reuests_post(data={
931
+ "equal": equal,
932
+ "limit": limit,
933
+ "sort": sort,
934
+ "profile_id": profile_id
935
+ },methode="getNewFollowRequests")
936
+
937
+ def accept_Request_Follow(self,request_id:str,profile_id:str=None):
938
+ return self._reuests_post(data={
939
+ "action": "Accept",
940
+ "request_id": request_id,
941
+ "profile_id": profile_id
942
+ },methode="actionOnRequest")
943
+
944
+ def decline_Request_Follow(self,request_id:str,profile_id:str=None):
945
+ return self._reuests_post(data={
946
+ "action": "Decline",
947
+ "request_id": request_id,
948
+ "profile_id": profile_id
949
+ },methode="actionOnRequest")
950
+ def un_save_Post(self,post_profile_id:str,post_id:str,profile_id:str=None):
951
+ return self._reuests_post(data={
952
+ "action_type": "Unbookmark",
953
+ "post_id": post_id,
954
+ "post_profile_id": post_profile_id,
955
+ "track_id": "Related",
956
+ "profile_id": profile_id
957
+ },methode="postBookmarkAction")
958
+
959
+ def get_Saved_Posts(self,sort:str="FromMax",limit:int=51,equal:bool=False,profile_id:str=None):
960
+ return self._reuests_post(data={
961
+ "equal": equal,
962
+ "limit": limit,
963
+ "sort": sort,
964
+ "profile_id": profile_id
965
+ },methode="getBookmarkedPosts")
966
+
967
+ def search_Page(self,username:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
968
+ return self._reuests_post(data={
969
+ "equal": equal,
970
+ "limit": limit,
971
+ "sort": sort,
972
+ "username": username,
973
+ "profile_id": profile_id
974
+ },methode="searchProfile")
975
+
976
+ def block_Page(self,target_profile_id:str,profile_id:str=None):
977
+ return self._reuests_post(data={
978
+ "action": "Block",
979
+ "blocked_id": target_profile_id,
980
+ "profile_id": profile_id
981
+ },methode="setBlockProfile")
982
+
983
+ def un_block_Page(self,target_profile_id:str,profile_id:str=None):
984
+ return self._reuests_post(data={
985
+ "action": "Unblock",
986
+ "blocked_id": target_profile_id,
987
+ "profile_id": profile_id
988
+ },methode="setBlockProfile")
989
+
990
+ def report_Page(self,post_id:str,reason:int=2,profile_id:str=None):
991
+ return self._reuests_post(data={
992
+ "model": "Profile",
993
+ "reason": reason,
994
+ "record_id": post_id,
995
+ "profile_id": profile_id
996
+ },methode="setReportRecord")
997
+
998
+ def delete_Post(self,post_id:str,profile_id:str=None):
999
+ return self._reuests_post(data={
1000
+ "model": "Post",
1001
+ "record_id": post_id,
1002
+ "profile_id": profile_id
1003
+ },methode="removeRecord")
1004
+
1005
+ def delete_Story(self,story_id:list,profile_id:str=None):
1006
+ return self._reuests_post(data={
1007
+ "profile_id": profile_id,
1008
+ "story_id": story_id,
1009
+ },methode="deleteStory")
1010
+
1011
+ def set_Page_Status(self,profile_status:str="Private",profile_id:str=None):
1012
+ return self._reuests_post(data={
1013
+ "profile_status": profile_status,
1014
+ "profile_id": profile_id
1015
+ },methode="updateProfile")
1016
+
1017
+ def allow_Send_MessagePv(self,is_message_allowed:bool=False,profile_id:str=None):
1018
+ return self._reuests_post(data={
1019
+ "is_message_allowed": is_message_allowed,
1020
+ "profile_id": profile_id
1021
+ },methode="updateProfile")
1022
+
1023
+ def edit_Notification(self,is_mute:bool=False,profile_id:str=None):
1024
+ return self._reuests_post(data={
1025
+ "is_mute": is_mute,
1026
+ "profile_id": profile_id
1027
+ },methode="updateProfile")
1028
+
1029
+ def upload_avatar(self,prof_file:str,profile_id:str=None):
1030
+ prof_res = req(self.auth).upload(prof_file,"Picture",profile_id)
1031
+ return self._reuests_post(data={
1032
+ "file_id": prof_res[0]["file_id"],
1033
+ "hash_file_receive": prof_res[1],
1034
+ "thumbnail_file_id": prof_res[0]["file_id"],
1035
+ "thumbnail_hash_file_receive": prof_res[1],
1036
+ "profile_id": profile_id
1037
+ },methode="updateProfilePhoto")
1038
+ def add_Story(self,post_file:str,duration:int=27,size:list=[668,798],thumbnail_file:str=None,profile_id:str=None):
1039
+
1040
+ if post_file.split(".")[-1] == "mp4" or post_file.split(".")[-1] == "mov" or post_file.split(".")[-1] == "mkv" or "https://":
1041
+ try:
1042
+ if "https://" in post_file:
1043
+ tumb_res , post_res = req(self.auth).upload(image_to_bytes(thumbnail_file) if type(thumbnail_file) is str else confing.th,"Picture",profile_id) , req(self.auth).upload(requests.get(post_file).content,"Video",profile_id)
1044
+ else :
1045
+ tumb_res , post_res = req(self.auth).upload(image_to_bytes(thumbnail_file) if type(thumbnail_file) is str else confing.th,"Picture",profile_id) , req(self.auth).upload(post_file,"Video",profile_id)
1046
+ except ModuleNotFoundError:
1047
+ print("pip install moviepy")
1048
+ tumb_res , post_res = req(self.auth).upload(confing.th,"Picture",profile_id) , req(self.auth).upload(post_file,"Video",profile_id)
1049
+ data = {
1050
+ "duration": str(duration),
1051
+ "file_id": post_res[0]["file_id"],
1052
+ "hash_file_receive": post_res[1],
1053
+ "height": 1280 if size[1] > 1280 else size[1],
1054
+ "story_type": "Video",
1055
+ "rnd": random.randint(100000, 999999999),
1056
+ "snapshot_file_id": tumb_res[0]["file_id"],
1057
+ "snapshot_hash_file_receive": tumb_res[1],
1058
+ "thumbnail_file_id": tumb_res[0]["file_id"],
1059
+ "thumbnail_hash_file_receive": tumb_res[1],
1060
+ "width": 720 if size[0] > 720 else size[0],
1061
+ "profile_id": profile_id
1062
+ }
1063
+
1064
+ elif post_file.split(".")[-1] == "jpg" or post_file.split(".")[-1] == "png":
1065
+ post_res = req(self.auth).upload(post_file,"Picture",profile_id)
1066
+
1067
+ data = {
1068
+ "file_id": post_res[0]["file_id"],
1069
+ "hash_file_receive": post_res[1],
1070
+ "height": 1280 if size[1] > 1280 else size[1],
1071
+ "story_type": "Picture",
1072
+ "rnd": random.randint(100000, 999999999),
1073
+ "thumbnail_file_id": post_res[0]["file_id"],
1074
+ "thumbnail_hash_file_receive": post_res[1],
1075
+ "width": 720 if size[0] > 720 else size[0],
1076
+ "profile_id": profile_id
1077
+ }
1078
+ else:
1079
+ return "file address eror"
1080
+ return req(self.auth).send_request(data,"addStory")['data']
1081
+ def delete_Page(self,page_profile_id:str):
1082
+ return self._reuests_post(data={
1083
+ "model": "Profile",
1084
+ "record_id": page_profile_id,
1085
+ "profile_id": None
1086
+ },methode="removeRecord")
1087
+
1088
+ def add_Post_View_Count(self,post_profile_id:str,post_id:str):
1089
+ return self._reuests_post(data={
1090
+ "post_id": post_id,
1091
+ "post_profile_id": post_profile_id
1092
+ },methode="addPostViewCount")
1093
+
1094
+ def add_Post_View_Time(self,post_profile_id:str,post_id:str,duration:int,profile_id:str=None):
1095
+ return self._reuests_post(data={
1096
+ "duration": duration,
1097
+ "post_id": post_id,
1098
+ "post_profile_id": post_profile_id,
1099
+ "profile_id": profile_id
1100
+ },methode="addPostViewTime")['data']