Rubka 7.2.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. rubka/__init__.py +79 -0
  2. rubka/adaptorrubka/__init__.py +4 -0
  3. rubka/adaptorrubka/client/__init__.py +1 -0
  4. rubka/adaptorrubka/client/client.py +60 -0
  5. rubka/adaptorrubka/crypto/__init__.py +1 -0
  6. rubka/adaptorrubka/crypto/crypto.py +82 -0
  7. rubka/adaptorrubka/enums.py +36 -0
  8. rubka/adaptorrubka/exceptions.py +22 -0
  9. rubka/adaptorrubka/methods/__init__.py +1 -0
  10. rubka/adaptorrubka/methods/methods.py +90 -0
  11. rubka/adaptorrubka/network/__init__.py +3 -0
  12. rubka/adaptorrubka/network/helper.py +22 -0
  13. rubka/adaptorrubka/network/network.py +221 -0
  14. rubka/adaptorrubka/network/socket.py +31 -0
  15. rubka/adaptorrubka/sessions/__init__.py +1 -0
  16. rubka/adaptorrubka/sessions/sessions.py +72 -0
  17. rubka/adaptorrubka/types/__init__.py +1 -0
  18. rubka/adaptorrubka/types/socket/__init__.py +1 -0
  19. rubka/adaptorrubka/types/socket/message.py +187 -0
  20. rubka/adaptorrubka/utils/__init__.py +2 -0
  21. rubka/adaptorrubka/utils/configs.py +18 -0
  22. rubka/adaptorrubka/utils/utils.py +251 -0
  23. rubka/api.py +1723 -0
  24. rubka/asynco.py +2541 -0
  25. rubka/button.py +404 -0
  26. rubka/config.py +3 -0
  27. rubka/context.py +1077 -0
  28. rubka/decorators.py +30 -0
  29. rubka/exceptions.py +37 -0
  30. rubka/filters.py +330 -0
  31. rubka/helpers.py +1461 -0
  32. rubka/jobs.py +15 -0
  33. rubka/keyboards.py +16 -0
  34. rubka/keypad.py +298 -0
  35. rubka/logger.py +12 -0
  36. rubka/metadata.py +114 -0
  37. rubka/rubino.py +1271 -0
  38. rubka/tv.py +145 -0
  39. rubka/update.py +1038 -0
  40. rubka/utils.py +3 -0
  41. rubka-7.2.8.dist-info/METADATA +1047 -0
  42. rubka-7.2.8.dist-info/RECORD +45 -0
  43. rubka-7.2.8.dist-info/WHEEL +5 -0
  44. rubka-7.2.8.dist-info/entry_points.txt +2 -0
  45. rubka-7.2.8.dist-info/top_level.txt +1 -0
rubka/rubino.py ADDED
@@ -0,0 +1,1271 @@
1
+ import urllib3
2
+ import json,random
3
+ from typing import Any, Dict,List
4
+ from tempfile import NamedTemporaryFile
5
+ from os import system, chmod, remove
6
+ from base64 import b64encode
7
+ from io import BytesIO
8
+ class InvalidInputError(Exception):
9
+ def __init__(self, message="Invalid input provided"):
10
+ self.message = message
11
+ super().__init__(self.message)
12
+ class confing():
13
+ headers= {
14
+ "User-Agent": "okhttp/3.12.1",
15
+ "Connection": "Keep-Alive",
16
+ "Accept-Encoding": "gzip",
17
+ "Content-Type": "application/json; charset=UTF-8"
18
+ }
19
+ server = {
20
+ "rubino": "https://rubino17.iranlms.ir",
21
+ "messenger": "https://messengerg2c137.iranlms.ir"
22
+ }
23
+ android = {
24
+ "app_name": "Main",
25
+ "app_version": "3.7.3",
26
+ "lang_code": "fa",
27
+ "package": "app.rbmain.a",
28
+ "platform": "Android",
29
+ "store": "Myket",
30
+ "temp_code": "34"
31
+ }
32
+ 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'
33
+
34
+
35
+ try:
36
+ from base64 import b64encode, urlsafe_b64decode
37
+ from Crypto.Util.Padding import pad, unpad
38
+ from Crypto.Cipher import AES
39
+ except:os.system('pip install pycryptodome')
40
+ class cryption:
41
+
42
+ def __init__(self, auth:str):
43
+ self.key = bytearray(self.secret(auth), 'UTF-8')
44
+ self.iv = bytearray.fromhex('0' * 32)
45
+
46
+ def replaceCharAt(self, e, t, i):
47
+ return e[0:t] + i + e[t + len(i):]
48
+
49
+ def secret(self, e):
50
+ t = e[0:8]
51
+ i = e[8:16]
52
+ n = e[16:24] + t + e[24:32] + i
53
+ s = 0
54
+ while s < len(n):
55
+ e = n[s]
56
+ if e >= '0' and e <= '9':
57
+ t = chr((ord(e[0]) - ord('0') + 5) % 10 + ord('0'))
58
+ n = self.replaceCharAt(n, s, t)
59
+ else:
60
+ t = chr((ord(e[0]) - ord('a') + 9) % 26 + ord('a'))
61
+ n = self.replaceCharAt(n, s, t)
62
+ s += 1
63
+ return n
64
+
65
+ def encrypt(self, text):
66
+ return b64encode(
67
+ AES.new(self.key, AES.MODE_CBC, self.iv)
68
+ .encrypt(pad(text.encode('UTF-8'),AES.block_size))
69
+ ).decode('UTF-8')
70
+
71
+
72
+ def decrypt(self, text):
73
+ return unpad(
74
+ AES.new(self.key, AES.MODE_CBC, self.iv)
75
+ .decrypt(urlsafe_b64decode(text.encode('UTF-8')))
76
+ ,AES.block_size
77
+ ).decode('UTF-8')
78
+
79
+
80
+ def changeAuthType(self, auth_enc):
81
+ lowercase = 'abcdefghijklmnopqrstuvwxyz'
82
+ uppercase = 'abcdefghijklmnopqrstuvwxyz'.upper()
83
+ digits = '0123456789'
84
+ n = ''
85
+ for s in auth_enc:
86
+ if s in lowercase:
87
+ n += chr(((32 - (ord(s) - 97)) % 26) + 97)
88
+ elif s in uppercase:
89
+ n += chr(((29- (ord(s) - 65)) % 26) + 65)
90
+ elif s in digits:
91
+ n += chr(((13 - (ord(s)- 48)) % 10) + 48)
92
+ else:
93
+ n += s
94
+ return n
95
+
96
+ from requests.exceptions import HTTPError , ReadTimeout , ConnectionError
97
+ from requests.sessions import Session ; Session = Session()
98
+ from json import dumps,loads
99
+ from requests.exceptions import HTTPError , ReadTimeout , ConnectionError
100
+ from requests.sessions import Session ; Session = Session()
101
+ from json import dumps,loads
102
+ import requests
103
+ from requests import get
104
+
105
+ import os
106
+ import re
107
+
108
+ import io
109
+ import urllib
110
+
111
+ def get_video_thumbnail_bytes(video_path):
112
+ if os.path.exists(video_path):
113
+ try:
114
+ from moviepy.editor import VideoFileClip
115
+ from PIL import Image
116
+ video = VideoFileClip(video_path)
117
+ frame = video.get_frame(0)
118
+ image = Image.fromarray(frame)
119
+ byte_arr = io.BytesIO()
120
+ image.save(byte_arr, format='JPEG')
121
+ byte_arr.seek(0)
122
+ return byte_arr.getvalue()
123
+ except:
124
+ raise Exception("An error occurred while processing the video file.")
125
+ 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
126
+ try:
127
+ response = urllib.request.urlopen(video_path)
128
+ video_bytes = response.read()
129
+ video = VideoFileClip(io.BytesIO(video_bytes))
130
+ frame = video.get_frame(0)
131
+ image = Image.fromarray(frame)
132
+ byte_arr = io.BytesIO()
133
+ image.save(byte_arr, format='JPEG')
134
+ byte_arr.seek(0)
135
+ return byte_arr.getvalue()
136
+ except:
137
+ raise Exception("An error occurred while downloading and processing the video file.")
138
+ else:
139
+ raise ValueError("Invalid input. Please provide a valid local file path or a download link.")
140
+
141
+ from PIL import Image
142
+ import io
143
+
144
+ def image_to_bytes(image_path):
145
+ with Image.open(image_path) as img:
146
+ buffer = io.BytesIO()
147
+ img.save(buffer, format="JPEG")
148
+ byte_data = buffer.getvalue()
149
+ return byte_data
150
+
151
+ class req:
152
+
153
+ def __init__(self,auth:str):
154
+ self.auth = auth
155
+ self.enc = cryption(auth)
156
+
157
+ def send_request(self,data:dict,method:str,type_method:str="rubino"):
158
+
159
+ if type_method == "rubino":
160
+
161
+ data_json = {
162
+ "api_version": "0",
163
+ "auth": self.auth,
164
+ "client":confing.android,
165
+ "data": data,
166
+ "method": method
167
+ }
168
+
169
+ elif type_method == "messenger":
170
+
171
+ data_json = {
172
+ "api_version": "5",
173
+ "auth": self.auth,
174
+ "data_enc": self.enc.encrypt(
175
+ dumps({
176
+ "method": method,
177
+ "input": data,
178
+ "client": confing.android
179
+ })
180
+ )
181
+ }
182
+
183
+ while True:
184
+ try:
185
+ response = Session.post(
186
+ url=confing.server[type_method],
187
+ headers=confing.headers,
188
+ json=data_json
189
+ )
190
+ except HTTPError as err:
191
+ raise HTTPError(f"HTTP Error {err.args[0]}")
192
+ except ReadTimeout:
193
+ raise ReadTimeout('Time out')
194
+ except ConnectionError:
195
+ raise ConnectionError('Check your internet connection')
196
+ except:
197
+ continue
198
+ else:
199
+
200
+ response_data = response.json()
201
+
202
+ if 'data_enc' in response_data:
203
+ return loads(self.enc.decrypt(response_data['data_enc']))
204
+ if response_data.get('status') != "OK":
205
+ raise InvalidInputError(f"Error : {response_data.get('status_det', 'Unknown error')}")
206
+ return response_data
207
+
208
+
209
+ def requestUploadFile(self,file_name:str,size:str,file_type:str,profile_id:str=None):
210
+ return self.send_request({
211
+ "file_name": file_name,
212
+ "file_size": str(size),
213
+ "file_type": file_type,
214
+ "profile_id": profile_id
215
+ },"requestUploadFile")
216
+
217
+
218
+ def upload(self, post_file, post_type: str, profile_id: str = None):
219
+ file_byte_code = post_file if isinstance(post_file, bytes) else open(post_file, "rb").read()
220
+ upload_res = self.requestUploadFile("video.mp4" if post_type == "Video" else "picture.jpg", len(file_byte_code), post_type, profile_id)
221
+ if upload_res is not None and upload_res["status"] == "OK":
222
+ upload_res = upload_res["data"]
223
+ total_part = len(file_byte_code) // 131072
224
+ upload_data = 0
225
+ for part in range(1, total_part + 2):
226
+ byte_part = file_byte_code[131072 * (part - 1): 131072 * part]
227
+ header = {
228
+ "part-number": str(part),
229
+ "total-part": str(total_part + 1),
230
+ "auth": self.auth,
231
+ "hash-file-request": upload_res["hash_file_request"],
232
+ "file-id": str(upload_res["file_id"]),
233
+ "content-type": "application/octet-stream",
234
+ "content-length": str(len(byte_part)),
235
+ "Host": upload_res["server_url"].replace("https://", "").replace("/UploadFile.ashx", ""),
236
+ "Connection": "Keep-Alive",
237
+ "accept-encoding": "gzip",
238
+ "user-agent": "okhttp/3.12.1",
239
+ }
240
+ while True:
241
+ try:
242
+ response = Session.post(data=byte_part, url=upload_res["server_url"], headers=header)
243
+ if response.status_code == 200:
244
+ upload_data += len(byte_part)
245
+ RED = "\033[31m"
246
+ GREEN = "\033[32m"
247
+ YELLOW = "\033[33m"
248
+ CYAN = "\033[36m"
249
+ BOLD = "\033[1m"
250
+ RESET = "\033[0m"
251
+ progress = upload_data / len(file_byte_code)
252
+ progress_bar_length = 100
253
+ filled_length = int(progress_bar_length * progress)
254
+ progress_bar = f"[{'=' * filled_length}{'.' * (progress_bar_length - filled_length)}]"
255
+ 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")
256
+ break
257
+ except ConnectionError:raise ConnectionError('Check your internet connection')
258
+ print()
259
+ return [upload_res, response.json()["data"]["hash_file_receive"]]
260
+ return upload_res
261
+
262
+
263
+ class DateInfo:
264
+ def __init__(self, data: Dict[str, Any]):
265
+ self.jalali = data.get('jalali')
266
+ self.miladi = data.get('miladi')
267
+ self.ghamari = data.get('ghamari')
268
+ def getVideoData(bytes:bytes):
269
+ try:
270
+ from moviepy.editor import VideoFileClip
271
+ with NamedTemporaryFile(delete=False, dir=".") as temp_video:
272
+ temp_video.write(bytes)
273
+ temp_path = temp_video.name
274
+ chmod(temp_path, 0o777)
275
+ try:
276
+ from PIL import Image
277
+ except ImportError:
278
+ system("pip install pillow")
279
+ from PIL import Image
280
+ with VideoFileClip(temp_path) as clip:
281
+ duration = clip.duration
282
+ resolution = clip.size
283
+ thumbnail = clip.get_frame(0)
284
+ thumbnail_image = Image.fromarray(thumbnail)
285
+ thumbnail_buffer = BytesIO()
286
+ print(thumbnail_buffer)
287
+ thumbnail_image.save(thumbnail_buffer, format="JPEG")
288
+ thumbnail_b64 = thumbnail_buffer.getvalue()
289
+ clip.close()
290
+ remove(temp_path)
291
+ return thumbnail_b64
292
+ except ImportError:
293
+ print("pip install moviepy")
294
+ return confing.th
295
+ except Exception as e:print(e)
296
+ class SeasonInfo:
297
+ def __init__(self, data: Dict[str, Any]):
298
+ self.number = data.get('number')
299
+ self.name = data.get('name')
300
+
301
+ class TimeInfo:
302
+ def __init__(self, data: Dict[str, Any]):
303
+ self.hour = data.get('hour')
304
+ self.minute = data.get('minute')
305
+ self.second = data.get('second')
306
+
307
+ class DayInfo:
308
+ def __init__(self, data: Dict[str, Any]):
309
+ self.number = data.get('number')
310
+ self.name_week = data.get('name_week')
311
+ self.name_month = data.get('name_month')
312
+
313
+ class MonthInfo:
314
+ def __init__(self, data: Dict[str, Any]):
315
+ self.number = data.get('number')
316
+ self.name_past = data.get('name_past')
317
+ self.name = data.get('name')
318
+
319
+ class YearInfo:
320
+ def __init__(self, data: Dict[str, Any]):
321
+ self.number = data.get('number')
322
+ self.name = data.get('name')
323
+ self.name_past = data.get('name_past')
324
+ self.remaining = data.get('remaining')
325
+ self.leap = data.get('leap')
326
+
327
+ class OccasionInfo:
328
+ def __init__(self, data: Dict[str, Any]):
329
+ self.miladi = data.get('miladi')
330
+ self.jalali = data.get('jalali')
331
+ self.ghamari = data.get('ghamari')
332
+
333
+ class TimeData:
334
+ def __init__(self, data: Dict[str, Any]):
335
+ self.timestamp = data.get('timestamp')
336
+ self.date = DateInfo(data.get('date', {}))
337
+ self.season = SeasonInfo(data.get('season', {}))
338
+ self.time = TimeInfo(data.get('time', {}))
339
+ self.day = DayInfo(data.get('day', {}))
340
+ self.month = MonthInfo(data.get('month', {}))
341
+ self.year = YearInfo(data.get('year', {}))
342
+ self.occasion = OccasionInfo(data.get('occasion', {}))
343
+
344
+ def __repr__(self) -> str:
345
+ return json.dumps(self.__dict__, ensure_ascii=False, indent=4, default=lambda o: o.__dict__)
346
+
347
+ class IPInfo:
348
+ def __init__(self, data: Dict[str, Any]):
349
+ self.ip = data.get('IP')
350
+ self.country = data.get('Country')
351
+ self.city = data.get('City')
352
+ self.isp = data.get('ISP')
353
+ self.timezone = data.get('timzone')
354
+ self.org = data.get('org')
355
+ self.country_code = data.get('countryCode')
356
+
357
+ def __repr__(self) -> str:
358
+ return json.dumps(self.__dict__, ensure_ascii=False, indent=4)
359
+
360
+ def __request_url():
361
+ import random
362
+ return f"https://rubino{random.randint(1,59)}.iranlms.ir/"
363
+ from typing import Union, Optional
364
+ from pathlib import Path
365
+
366
+ _useragent_list = [
367
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0',
368
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
369
+ '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',
370
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
371
+ 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
372
+ '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',
373
+ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0'
374
+ ]
375
+ def get_useragent():
376
+ import random
377
+ return random.choice(_useragent_list)
378
+ class api:
379
+ def download_post_rubika(
380
+ share_url:str,
381
+ #return_choice:None = False
382
+ ):
383
+ body = {'url': share_url}
384
+ request = urllib3.PoolManager()
385
+ response = request.request(
386
+ 'POST',
387
+ 'https://api-free.ir/api/rubino-dl.php',
388
+ fields=body)
389
+ if response.status == 200:
390
+ response_data = json.loads(response.data.decode('utf-8'))
391
+ if 'result' in response_data:
392
+ return response_data['result']
393
+
394
+ def download_story_rubika(
395
+ username:str
396
+ ):
397
+ body = {'id': username}
398
+ request = urllib3.PoolManager()
399
+ response = request.request(
400
+ 'POST',
401
+ 'https://api-free.ir/api2/story_rubino.php',
402
+ fields=body)
403
+ if response.status == 200:
404
+ response_data = json.loads(response.data.decode('utf-8'))
405
+ if 'result' in response_data:
406
+ return response_data['result']
407
+ def search_page_rubino(
408
+ text:str
409
+ ):
410
+ body = {'user': text}
411
+ request = urllib3.PoolManager()
412
+ response = request.request(
413
+ 'GET',
414
+ 'https://api-free.ir/api/rubino-search.php',
415
+ fields=body)
416
+ if response.status == 200:
417
+ response_data = json.loads(response.data.decode('utf-8'))
418
+ if 'result' in response_data:
419
+ return response_data['result']
420
+
421
+
422
+ class Bot():
423
+ """rubino class Regester m.rubika.ir"""
424
+ def __init__(self,auth,platform="m.rubika.ir",lang_code="fa") -> None:
425
+ """
426
+ regester m.rubika.ir
427
+ """
428
+ self.auth=auth
429
+ self.platform=platform
430
+ self.lang_code=lang_code
431
+ #{"app_name": "Main","app_version": "3.0.2"dd,"lang_code": "fa","package": "app.rbmain.a","platform": "Android"}
432
+ def _request_url(self):
433
+ import random
434
+ return f"https://rubino{random.randint(1,59)}.iranlms.ir/"
435
+ def get_link(self):
436
+ return self._request_url()
437
+ def _reuests_post(self,methode:str,data:dict):
438
+ request = urllib3.PoolManager()
439
+
440
+ if self.platform == "m.rubika.ir" or self.platform == "web" or self.platform == "PWA":
441
+ body = {
442
+ "auth":self.auth,
443
+ "api_version":"0",
444
+ "client":{
445
+ "app_name":"Main",
446
+ "app_version":"2.4.7",
447
+ "package":"m.rubika.ir",
448
+ "platform":"PWA"
449
+ },
450
+ "data":data,
451
+ "method":methode
452
+ }
453
+ elif self.platform == "android" or self.platform == "Android" or self.platform == "rubix":
454
+ body = {
455
+ "auth":self.auth,
456
+ "api_version":"0",
457
+ "client":{
458
+ "app_name": "Main",
459
+ "app_version": "3.0.2",
460
+ "lang_code": self.lang_code,
461
+ "package": "app.rbmain.a",
462
+ "platform": "Android"
463
+ },
464
+ "data":data,
465
+ "method":methode
466
+ }
467
+ response = request.request(
468
+ 'POST',
469
+ self.get_link(),json=body)
470
+ if response.status == 200:
471
+ response_data = json.loads(response.data.decode('utf-8'))
472
+ if 'data' in response_data:
473
+ return response_data['data']
474
+ else:
475
+ raise Exception(f"Error: {response_data.get('status_det', 'Unknown error')}")
476
+ else:
477
+ raise Exception(f"Request Error Server - Status Code: {response.status}")
478
+
479
+ def edit_info_page(
480
+ self,
481
+ username_me:str,
482
+ name=str,
483
+ bio=None,
484
+ phone=None,
485
+ email=None,
486
+ website=None
487
+ ):
488
+ """
489
+ - username_me : در این مقدر باید آیدی پیجی که میخاین ادیت شه وارد کنید
490
+ """
491
+ profile_id=requests.post(f"https://api-free.ir/api/rubino-search.php?user={username_me}").json()['result']['data']['profiles'][0]['id']
492
+ data = {
493
+ "profile_id":profile_id,
494
+ "username":username_me,
495
+ "name":name,
496
+ "bio":bio,
497
+ "phone":phone,
498
+ "email":email,
499
+ "website":website
500
+ }
501
+ methode = "updateProfile"
502
+ req_get = self._reuests_post(methode=methode,data=data)
503
+ return req_get
504
+ def create_page(
505
+ self,
506
+ username:str,
507
+ name:str = "codern",
508
+ bio:str = None,
509
+ phone=None,
510
+ email=None,
511
+ website=None
512
+ ):
513
+ data = {
514
+ "username":username,
515
+ "name":name,
516
+ "bio":bio,
517
+ "phone":phone,
518
+ "email":email,
519
+ "website":website
520
+ }
521
+ methode = "createPage"
522
+
523
+ request = self._reuests_post(methode=methode,data=data)
524
+ return request
525
+ def Download_story(self,username):
526
+ return api.download_story_rubika(username)
527
+ def get_comments(self,post_id,post_profile_id,profile_id=None):
528
+ data = {
529
+ "equal": False,
530
+ "limit": 100,
531
+ "sort": "FromMax",
532
+ "post_id": post_id,
533
+ "profile_id": profile_id,
534
+ "post_profile_id": post_profile_id
535
+ }
536
+ methode = "getComments"
537
+ request = self._reuests_post(methode=methode,data=data)
538
+ return request
539
+ def get_all_profile(self):
540
+ data = {"equal":False,"limit":10,"sort":"FromMax"}
541
+ methode = 'getProfileList'
542
+ request = self._reuests_post(methode=methode,data=data)
543
+ return request
544
+ def get_me_info(self,profile_id):
545
+ """- دریافت اطلاعات پیج"""
546
+ data = {"profile_id":profile_id}
547
+ methode = 'getMyProfileInfo'
548
+ request = self._reuests_post(methode=methode,data=data)
549
+ return request
550
+ def Like(self,post_id,target_post_id):
551
+ data ={"action_type":"Like","post_id":post_id,"post_profile_id":target_post_id,"profile_id":[]}
552
+ methode = 'likePostAction'
553
+ request = self._reuests_post(methode=methode,data=data)
554
+ return request
555
+
556
+ #--------------------------------------------
557
+
558
+ def comment(self,text,post_id,post_target_id,profile_id=None):
559
+ import random
560
+ data = {
561
+ "content": text,
562
+ "post_id": post_id,
563
+ "post_profile_id": post_target_id,
564
+ "rnd":f"{random.randint(100000,999999999)}" ,
565
+ "profile_id":profile_id
566
+ }
567
+ methode = 'addComment'
568
+ while True:
569
+ try:return self._reuests_post(methode=methode,data=data)
570
+ except:return "error"
571
+
572
+ def get_link_share(self,post_id,post_profile,prof=None):
573
+ data = {
574
+ "post_id":post_id,
575
+ "post_profile_id":post_profile,
576
+ "profile_id":prof
577
+ }
578
+ methode = 'getShareLink'
579
+ return self._reuests_post(methode=methode,data=data)
580
+
581
+
582
+ def is_Exist_Username(self,username):
583
+ if username.startswith("@"):
584
+ username = username.split("@")[1]
585
+ data = {"username": username}
586
+ else:data = {"username": username}
587
+ methode = "isExistUsername"
588
+ return self._reuests_post(methode=methode,data=data)
589
+
590
+ def add_View_Story(self,target_story_id,ids:list,profile_id=None):
591
+ data = {
592
+ "profile_id":profile_id,
593
+ "story_ids":ids,
594
+ "story_profile_id":target_story_id
595
+ }
596
+ methode = 'addViewStory'
597
+ return self._reuests_post(methode=methode,data=data)
598
+
599
+
600
+ def save_post(self,post_id,post_profile_id,prof=None):
601
+ data = {
602
+ "action_type":"Bookmark",
603
+ "post_id":post_id,
604
+ "post_profile_id":post_profile_id,
605
+ "profile_id":prof
606
+ }
607
+ methode ='postBookmarkAction'
608
+ return self._reuests_post(methode=methode,data=data)
609
+
610
+
611
+ def un_like(self,post_id,post_profile_id):
612
+ data = {
613
+ "action_type":"Unlike",
614
+ "post_id":post_id,
615
+ "post_profile_id":post_profile_id,
616
+ "profile_id":[]
617
+ }
618
+ methode ='likePostAction'
619
+ return self._reuests_post(methode=methode,data=data)
620
+ def get_Suggested(self,profile_id=None):
621
+ data = {
622
+ "profile_id":profile_id,
623
+ "limit": 20,
624
+ "sort": "FromMax"
625
+ }
626
+ methode = 'getSuggested'
627
+ return self._reuests_post(methode=methode,data=data)
628
+ def image_to_bytes(self, image_path):
629
+ with Image.open(image_path) as img:
630
+ buffer = io.BytesIO()
631
+ img.save(buffer, format="JPEG")
632
+ byte_data = buffer.getvalue()
633
+ return byte_data
634
+
635
+ def check_url_content_type(self, url):
636
+ response = requests.head(url)
637
+ content_type = response.headers.get('Content-Type', '').lower()
638
+ print(f"post type {content_type}")
639
+ if 'image' in content_type:
640
+ return 'image'
641
+ elif 'video' in content_type:
642
+ return 'video'
643
+ return None
644
+
645
+ def upload_file(self, file, file_type, profile_id):
646
+ return req(self.auth).upload(file, file_type, profile_id)
647
+
648
+ def get_video_resolution(self,download_link):
649
+ try:
650
+ from moviepy.editor import VideoFileClip
651
+ clip = VideoFileClip(download_link)
652
+ width = clip.w
653
+ height = clip.h
654
+ clip.close()
655
+ return [width, height]
656
+ except ModuleNotFoundError:
657
+ print("pip install moviepy")
658
+ return [668,789]
659
+ except Exception as e:
660
+ return [668,789]
661
+ def add_Story(self,post_file:str,duration:int=27,size:list=[668,798],thumbnail_file:str=None,profile_id:str=None):
662
+
663
+ if post_file.split(".")[-1] == "mp4" or post_file.split(".")[-1] == "mov" or post_file.split(".")[-1] == "mkv" or "https://":
664
+ try:
665
+ if "https://" in post_file:
666
+ 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)
667
+ else :
668
+ 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)
669
+ except ModuleNotFoundError:
670
+ print("pip install moviepy")
671
+ tumb_res , post_res = req(self.auth).upload(confing.th,"Picture",profile_id) , req(self.auth).upload(post_file,"Video",profile_id)
672
+ data = {
673
+ "duration": str(duration),
674
+ "file_id": post_res[0]["file_id"],
675
+ "hash_file_receive": post_res[1],
676
+ "height": 1280 if size[1] > 1280 else size[1],
677
+ "story_type": "Video",
678
+ "rnd": random.randint(100000, 999999999),
679
+ "snapshot_file_id": tumb_res[0]["file_id"],
680
+ "snapshot_hash_file_receive": tumb_res[1],
681
+ "thumbnail_file_id": tumb_res[0]["file_id"],
682
+ "thumbnail_hash_file_receive": tumb_res[1],
683
+ "width": 720 if size[0] > 720 else size[0],
684
+ "profile_id": profile_id
685
+ }
686
+
687
+ elif post_file.split(".")[-1] == "jpg" or post_file.split(".")[-1] == "png":
688
+ post_res = req(self.auth).upload(post_file,"Picture",profile_id)
689
+
690
+ data = {
691
+ "file_id": post_res[0]["file_id"],
692
+ "hash_file_receive": post_res[1],
693
+ "height": 1280 if size[1] > 1280 else size[1],
694
+ "story_type": "Picture",
695
+ "rnd": random.randint(100000, 999999999),
696
+ "thumbnail_file_id": post_res[0]["file_id"],
697
+ "thumbnail_hash_file_receive": post_res[1],
698
+ "width": 720 if size[0] > 720 else size[0],
699
+ "profile_id": profile_id
700
+ }
701
+ else:
702
+ return "file address eror"
703
+ return req(self.auth).send_request(data,"addStory")['data']
704
+ 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):
705
+ from concurrent.futures import ThreadPoolExecutor
706
+ if size == "Auto" or size =="auto":
707
+ try:
708
+ size=self.get_video_resolution(post_file)
709
+ print(size)
710
+ except Exception as e:
711
+ print(f"error data resolution auto [668,789]")
712
+ http = urllib3.PoolManager(num_pools=10, headers={'Connection': 'keep-alive'})
713
+ def get_file_content(file):
714
+ if file.startswith("https://"):
715
+ content_type = self.check_url_content_type(file)
716
+ if content_type not in ['image', 'video']:
717
+ return None, None
718
+ response = http.request('GET', file)
719
+ print("GET <<< Data byte.")
720
+ return response.data, "Picture" if content_type == 'image' else "Video"
721
+ else:
722
+ post_extension = file.split(".")[-1].lower()
723
+ if post_extension in ["mp4", "mov", "mkv"]:
724
+ return open(file, 'rb').read(), "Video"
725
+ elif post_extension in ["jpg", "jpeg", "png"]:
726
+ return open(file, 'rb').read(), "Picture"
727
+ else:
728
+ return None, None
729
+
730
+ post_file_content, post_type = get_file_content(post_file)
731
+ if post_file_content is None:
732
+ return "Invalid file or URL"
733
+
734
+ def get_thumbnail_content(thumbnail, post_file_content):
735
+ if thumbnail and thumbnail.startswith("https://"):
736
+ response = http.request('GET', thumbnail)
737
+ content_type = response.headers.get('content-type', '').lower()
738
+ if 'image' in content_type:
739
+ return response.data
740
+ else:
741
+ return confing.th
742
+ elif thumbnail:
743
+ return image_to_bytes(thumbnail)
744
+ else:
745
+ try:
746
+ print("GET <<< thumbnail Byte.")
747
+ return getVideoData(post_file_content)
748
+ except ModuleNotFoundError:
749
+ return confing.th
750
+ thumbnail_content = get_thumbnail_content(thumbnail_file, post_file_content)
751
+ def upload_file_concurrently(file_content, file_type, profile_id):
752
+ return self.upload_file(file_content, file_type, profile_id)
753
+
754
+ with ThreadPoolExecutor(max_workers=2) as executor:
755
+ post_res = executor.submit(upload_file_concurrently, post_file_content, post_type, profile_id).result()
756
+ tumb_res = executor.submit(upload_file_concurrently, thumbnail_content, "Picture", profile_id).result()
757
+
758
+ data = {
759
+ "caption": caption,
760
+ "file_id": post_res[0]["file_id"],
761
+ "hash_file_receive": post_res[1],
762
+ "height": str(min(size[1], 862)),
763
+ "width": str(min(size[0], 848)),
764
+ "is_multi_file": False,
765
+ "post_type": post_type,
766
+ "rnd": random.randint(100000, 999999999),
767
+ "tagged_profiles": [],
768
+ "thumbnail_file_id": tumb_res[0]["file_id"],
769
+ "thumbnail_hash_file_receive": tumb_res[1],
770
+ "profile_id": profile_id
771
+ }
772
+
773
+ if post_type == "Video":
774
+ data.update({
775
+ "duration": str(time),
776
+ "snapshot_file_id": tumb_res[0]["file_id"],
777
+ "snapshot_hash_file_receive": tumb_res[1]
778
+ })
779
+
780
+ return req(self.auth).send_request(data, "addPost")
781
+
782
+ 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):
783
+ data = {
784
+ "equal": equal,
785
+ "limit": limit,
786
+ "max_id": max_id,
787
+ "post_id": post_id,
788
+ "post_profile_id": post_profile_id,
789
+ "sort": sort,
790
+ "profile_id": profile_id
791
+ }
792
+ return self._reuests_post(methode='getPostLikes',data=data)
793
+
794
+ def get_Story(self,story_profile_id:str,story_ids:list,profile_id:str=None):
795
+ return self._reuests_post(data={
796
+ "profile_id": profile_id,
797
+ "story_ids": story_ids,
798
+ "story_profile_id": story_profile_id
799
+ },methode="getStory")
800
+
801
+ def get_Story_Viewers(self,story_id:str,limit:int=50,profile_id:str=None):
802
+ return self._reuests_post(data={
803
+ "limit": limit,
804
+ "profile_id": profile_id,
805
+ "story_id": story_id
806
+ },methode="getStoryViewers")
807
+
808
+ def get_My_Archive_Stories(self,sort:str="FromMax",limit:int=10,equal:bool=False,profile_id:str=None):
809
+ return self._reuests_post(data={
810
+ "equal": equal,
811
+ "limit": limit,
812
+ "sort": sort,
813
+ "profile_id": profile_id
814
+ },methode="getMyArchiveStories")
815
+
816
+ def get_Page_Highlights(self,target_profile_id:str,sort:str="FromMax",limit:int=10,equal:bool=False,profile_id:str=None):
817
+ return self._reuests_post(data={
818
+ "equal": equal,
819
+ "limit": limit,
820
+ "sort": sort,
821
+ "target_profile_id": target_profile_id,
822
+ "profile_id": profile_id
823
+ },methode="getProfileHighlights")
824
+
825
+ def create_Highlight(self,highlight_name:str,story_ids:list,highlight_cover_picture:str,profile_id:str=None):
826
+ highlight_cover_res = self.req.upload(highlight_cover_picture,"Picture",profile_id)
827
+ return self._reuests_post(data={
828
+ "highlight_cover": {
829
+ "highlight_file_id": highlight_cover_res[0]["file_id"],
830
+ "highlight_hash_file_receive": highlight_cover_res[1],
831
+ "type": "File"
832
+ },
833
+ "highlight_name": highlight_name,
834
+ "story_ids": story_ids,
835
+ "profile_id": profile_id
836
+ },methode="addHighlight")
837
+
838
+ def highlight_Story(self,highlight_id:str,story_id:str,profile_id:str=None):
839
+ return self._reuests_post(data={
840
+ "highlight_id": highlight_id,
841
+ "story_id": story_id,
842
+ "profile_id": profile_id
843
+ },methode="highlightStory")
844
+
845
+ def remove_Story_From_Highlight(self,highlight_id:str,remove_story_ids:list,profile_id:str=None):
846
+ return self._reuests_post(data={
847
+ "highlight_id": highlight_id,
848
+ "remove_story_ids": remove_story_ids,
849
+ "updated_parameters":["remove_story_ids"],
850
+ "profile_id": profile_id
851
+ },methode="editHighlight")
852
+
853
+ def get_Hash_Tag_Trend(self,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
854
+ return self._reuests_post(data={
855
+ "equal": equal,
856
+ "limit": limit,
857
+ "sort": sort,
858
+ "profile_id": profile_id
859
+ },methode="getHashTagTrend")
860
+
861
+ def get_Explore_Posts(self,sort:str="FromMax",limit:int=51,equal:bool=False,profile_id:str=None):
862
+ return self._reuests_post(data={
863
+ "equal": equal,
864
+ "limit": limit,
865
+ "sort": sort,
866
+ "profile_id": profile_id
867
+ },methode="getExplorePosts")
868
+
869
+ def get_Tagged_Posts(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
870
+ return self._reuests_post(data={
871
+ "equal": equal,
872
+ "limit": limit,
873
+ "sort": sort,
874
+ "target_profile_id": target_profile_id,
875
+ "profile_id": profile_id
876
+ },methode="getTaggedPosts")
877
+
878
+ def delete_Comment(self,post_id:str,comment_id:str,text:str,profile_id:str=None):
879
+ return self._reuests_post(data={
880
+ "model": "Comment",
881
+ "post_id": post_id,
882
+ "record_id": comment_id,
883
+ "profile_id": profile_id
884
+ },methode="removeRecord")
885
+
886
+ def like_Comment(self,comment_id:str,post_id:str,profile_id:str=None):
887
+ return self._reuests_post(data={
888
+ "action_type": "Like",
889
+ "comment_id": comment_id,
890
+ "post_id": post_id,
891
+ "profile_id": profile_id
892
+ },methode="likeCommentAction")
893
+
894
+ def un_like_Comment(self,comment_id:str,post_id:str,profile_id:str=None):
895
+ return self._reuests_post(data={
896
+ "action_type": "Unlike",
897
+ "comment_id": comment_id,
898
+ "post_id": post_id,
899
+ "profile_id": profile_id
900
+ },methode="likeCommentAction")
901
+
902
+ def get_Comments(self,post_profile_id:str,post_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
903
+ return self._reuests_post(data={
904
+ "equal": equal,
905
+ "limit": limit,
906
+ "post_id": post_id,
907
+ "post_profile_id": post_profile_id,
908
+ "sort": sort,
909
+ "profile_id": profile_id
910
+ },methode="getComments")
911
+
912
+ def request_Follow(self,followee_id:str,profile_id:str=None):
913
+ return self._reuests_post(data={
914
+ "f_type": "Follow",
915
+ "followee_id": followee_id,
916
+ "profile_id": profile_id
917
+ },methode="requestFollow")
918
+
919
+ def un_Follow(self,followee_id:str,profile_id:str=None):
920
+ return self._reuests_post(data={
921
+ "f_type": "Unfollow",
922
+ "followee_id": followee_id,
923
+ "profile_id": profile_id
924
+ },methode="requestFollow")
925
+
926
+ def get_Page_Follower(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
927
+ return self._reuests_post(data={
928
+ "equal": equal,
929
+ "f_type": "Follower",
930
+ "limit": limit,
931
+ "sort": sort,
932
+ "target_profile_id": target_profile_id,
933
+ "profile_id": profile_id
934
+ },methode="getProfileFollowers")
935
+ def search_Follower(self,username,profile_id,target_profile_id,limit=10,search_type="Follower"):
936
+ return self._reuests_post(data={
937
+ "limit": limit,
938
+ "profile_id": profile_id,
939
+ "search_type": limit,
940
+ "target_profile_id": target_profile_id,
941
+ "username": username
942
+ },methode="searchFollower")
943
+ def search_Following(self,username,profile_id,target_profile_id,limit=10,search_type="Following"):
944
+ return self._reuests_post(data={
945
+ "limit": limit,
946
+ "profile_id": profile_id,
947
+ "search_type": limit,
948
+ "target_profile_id": target_profile_id,
949
+ "username": username
950
+ },methode="searchFollower")
951
+
952
+ def get_Page_Following(self,target_profile_id:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
953
+ return self._reuests_post(data={
954
+ "equal": equal,
955
+ "f_type": "Following",
956
+ "limit": limit,
957
+ "sort": sort,
958
+ "target_profile_id": target_profile_id,
959
+ "profile_id": profile_id
960
+ },methode="getProfileFollowers")
961
+
962
+ 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):
963
+ return self._reuests_post(data={
964
+ "equal": equal,
965
+ "limit": limit,
966
+ "max_id": max_id,
967
+ "search_type": "Follower",
968
+ "sort": sort,
969
+ "target_profile_id": target_profile_id,
970
+ "username": username,
971
+ "profile_id": profile_id
972
+ },methode="getProfileFollowers")
973
+
974
+ 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):
975
+ return self._reuests_post(data={
976
+ "equal": equal,
977
+ "limit": limit,
978
+ "max_id": max_id,
979
+ "search_type": "Following",
980
+ "sort": sort,
981
+ "target_profile_id": target_profile_id,
982
+ "username": username,
983
+ "profile_id": profile_id
984
+ },methode="getProfileFollowers")
985
+ def get_Related_Explore_Post(self,post_id:str,track_id,post_profile_id:str,limit:int=50,start_id:bool=False,profile_id:str=None,target_profile_id=None,):
986
+ return self._reuests_post(data={
987
+ "limit": limit,
988
+ "post_id": post_id,
989
+ "post_profile_id": post_profile_id,
990
+ "start_id": start_id,
991
+ "target_profile_id": target_profile_id,
992
+ "track_id": track_id,
993
+ "profile_id": profile_id
994
+ },methode="getRelatedExplorePost")
995
+
996
+ def get_Highlight_StoryIds(self,highlight_id:str,profile_id:str,target_profile_id:str):
997
+ return self._reuests_post(data={
998
+ "highlight_id": highlight_id,
999
+ "profile_id": profile_id,
1000
+ "target_profile_id": target_profile_id
1001
+ },methode="getHighlightStoryIds")
1002
+ def get_Highlight_Stories(self,highlight_id:str,profile_id:str,target_profile_id:str,story_ids:list):
1003
+ return self._reuests_post(data={
1004
+ "highlight_id": highlight_id,
1005
+ "profile_id": profile_id,
1006
+ "target_profile_id": target_profile_id,
1007
+ "story_ids":story_ids
1008
+ },methode="getHighlightStories")
1009
+ def un_save_Post(self,post_profile_id:str,post_id:str,profile_id:str=None):
1010
+ return self._reuests_post(data={
1011
+ "action_type": "Unbookmark",
1012
+ "post_id": post_id,
1013
+ "post_profile_id": post_profile_id,
1014
+ "track_id": "Related",
1015
+ "profile_id": profile_id
1016
+ },methode="postBookmarkAction")
1017
+ def get_saved_posts(
1018
+ self,
1019
+ max_id: str,
1020
+ limit: int = 20,
1021
+ profile_id: Optional[str] = None,
1022
+ sort: str = "FromMax") -> Dict[str, Any]:
1023
+ payload = {
1024
+ "limit": limit,
1025
+ "max_id": max_id,
1026
+ "sort": sort
1027
+ }
1028
+ if profile_id is not None:
1029
+ payload["profile_id"] = profile_id
1030
+
1031
+ return self._reuests_post(
1032
+ data=payload,
1033
+ methode="getBookmarkedPosts"
1034
+ )
1035
+
1036
+ def search_Page(self,username:str,sort:str="FromMax",limit:int=50,equal:bool=False,profile_id:str=None):
1037
+ return self._reuests_post(data={
1038
+ "equal": equal,
1039
+ "limit": limit,
1040
+ "sort": sort,
1041
+ "username": username,
1042
+ "profile_id": profile_id
1043
+ },methode="searchProfile")
1044
+
1045
+ def block_Page(self,target_profile_id:str,profile_id:str=None):
1046
+ return self._reuests_post(data={
1047
+ "action": "Block",
1048
+ "blocked_id": target_profile_id,
1049
+ "profile_id": profile_id
1050
+ },methode="setBlockProfile")
1051
+
1052
+ def un_block_Page(self,target_profile_id:str,profile_id:str=None):
1053
+ return self._reuests_post(data={
1054
+ "action": "Unblock",
1055
+ "blocked_id": target_profile_id,
1056
+ "profile_id": profile_id
1057
+ },methode="setBlockProfile")
1058
+
1059
+ def report_Page(self,post_id:str,reason:int=2,profile_id:str=None):
1060
+ return self._reuests_post(data={
1061
+ "model": "Profile",
1062
+ "reason": reason,
1063
+ "record_id": post_id,
1064
+ "profile_id": profile_id
1065
+ },methode="setReportRecord")
1066
+ def report_Post(self,post_profile_id,post_id:str,reason:int=2,profile_id:str=None):
1067
+ return self._reuests_post(data={
1068
+ "model": "Post",
1069
+ "reason": reason,
1070
+ "post_profile_id":post_profile_id,
1071
+ "record_id": post_id,
1072
+ "profile_id": profile_id
1073
+ },methode="setReportRecord")
1074
+
1075
+ def delete_Post(self,post_id:str,profile_id:str=None):
1076
+ return self._reuests_post(data={
1077
+ "model": "Post",
1078
+ "record_id": post_id,
1079
+ "profile_id": profile_id
1080
+ },methode="removeRecord")
1081
+
1082
+ def delete_Story(self,story_id:list,profile_id:str=None):
1083
+ return self._reuests_post(data={
1084
+ "profile_id": profile_id,
1085
+ "story_id": story_id,
1086
+ },methode="deleteStory")
1087
+
1088
+ def set_Page_Status(self,profile_status:str="Private",profile_id:str=None):
1089
+ return self._reuests_post(data={
1090
+ "profile_status": profile_status,
1091
+ "profile_id": profile_id
1092
+ },methode="updateProfile")
1093
+ def get_New_Events(self,limit:int=20,sort:str="FromMax",profile_id:str=None):
1094
+ return self._reuests_post(data={
1095
+ "limit": limit,
1096
+ "profile_id": profile_id,
1097
+ "sort":sort
1098
+ },methode="updateProfile")
1099
+
1100
+ def allow_Send_MessagePv(self,is_message_allowed:bool=False,profile_id:str=None):
1101
+ return self._reuests_post(data={
1102
+ "is_message_allowed": is_message_allowed,
1103
+ "profile_id": profile_id
1104
+ },methode="updateProfile")
1105
+
1106
+ def edit_Notification(self,is_mute:bool=False,profile_id:str=None):
1107
+ return self._reuests_post(data={
1108
+ "is_mute": is_mute,
1109
+ "profile_id": profile_id
1110
+ },methode="updateProfile")
1111
+
1112
+ def upload_avatar(self,prof_file:str,profile_id:str=None):
1113
+ prof_res = req(self.auth).upload(prof_file,"Picture",profile_id)
1114
+ return self._reuests_post(data={
1115
+ "file_id": prof_res[0]["file_id"],
1116
+ "hash_file_receive": prof_res[1],
1117
+ "thumbnail_file_id": prof_res[0]["file_id"],
1118
+ "thumbnail_hash_file_receive": prof_res[1],
1119
+ "profile_id": profile_id
1120
+ },methode="updateProfilePhoto")
1121
+
1122
+ def delete_Page(self,page_profile_id:str):
1123
+ return self._reuests_post(data={
1124
+ "model": "Profile",
1125
+ "record_id": page_profile_id,
1126
+ "profile_id": None
1127
+ },methode="removeRecord")
1128
+
1129
+ def add_Post_View_Count(self,post_profile_id:str,post_id:str):
1130
+ return self._reuests_post(data={
1131
+ "post_id": post_id,
1132
+ "post_profile_id": post_profile_id
1133
+ },methode="addPostViewCount")
1134
+
1135
+ def add_Post_View_Time(self,post_profile_id:str,post_id:str,duration:int,profile_id:str=None):
1136
+ return self._reuests_post(data={
1137
+ "duration": duration,
1138
+ "post_id": post_id,
1139
+ "post_profile_id": post_profile_id,
1140
+ "profile_id": profile_id
1141
+ },methode="addPostViewTime")['data']
1142
+ def get_Profile_Posts(self,target_profile_id:str,max_id:str,sort:str="FromMax",limit:str=10):
1143
+ return self._reuests_post(data={
1144
+ "limit": limit,
1145
+ "max_id": max_id,
1146
+ "sort":sort,
1147
+ "target_profile_id": target_profile_id,
1148
+ },methode="getProfilePosts")['data']
1149
+ def get_info_Post(self,url_post:str,profile_id:str=None):
1150
+ return self._reuests_post(data={
1151
+ "share_string": url_post,
1152
+ "profile_id": profile_id,
1153
+ },methode="getPostByShareLink")['data']
1154
+ def search_HashTag(
1155
+ self,
1156
+ content: str,
1157
+ profile_id:str,
1158
+ limit: int = 20,
1159
+ ) -> Dict[str, Any]:
1160
+
1161
+ payload = {
1162
+ "profile_id": profile_id,
1163
+ "content": content,
1164
+ "limit": limit
1165
+ }
1166
+ return self._reuests_post("reportProfile", data=payload)
1167
+ def accept_Follow_Request(
1168
+ self,
1169
+ request_id: str,
1170
+ profile_id: Optional[str] = None
1171
+ ) -> Dict[str, Any]:
1172
+ """
1173
+ Accept a follow request from a user.
1174
+
1175
+ Args:
1176
+ request_id (str): The ID of the follow request.
1177
+ profile_id (Optional[str]): The profile ID of the current user (if available).
1178
+
1179
+ Returns:
1180
+ Dict[str, Any]: The server's response, including action status.
1181
+ """
1182
+ payload = {
1183
+ "action": "Accept",
1184
+ "request_id": request_id,
1185
+ "profile_id": profile_id
1186
+ }
1187
+ return self._reuests_post("actionOnRequest", data=payload)
1188
+ def decline_Follow_Request(
1189
+ self,
1190
+ request_id: str,
1191
+ profile_id: Optional[str] = None
1192
+ ) -> Dict[str, Any]:
1193
+ """
1194
+ Decline a follow request from a user.
1195
+
1196
+ Args:
1197
+ request_id (str): The ID of the follow request.
1198
+ profile_id (Optional[str]): The profile ID of the current user (if available).
1199
+
1200
+ Returns:
1201
+ Dict[str, Any]: The server's response, including action status.
1202
+ """
1203
+ payload = {
1204
+ "action": "Decline",
1205
+ "request_id": request_id,
1206
+ "profile_id": profile_id
1207
+ }
1208
+ return self._reuests_post("actionOnRequest", data=payload)
1209
+ def get_New_Follow_Requests(
1210
+ self,
1211
+ profile_id: Optional[str] = None ,
1212
+ limit: int = 20,
1213
+ sort: str = "FromMax"
1214
+ ) -> Dict[str, Any]:
1215
+ """
1216
+ Retrieve new follow requests for a given profile.
1217
+
1218
+ Args:
1219
+ profile_id (str): The profile ID of the current user.
1220
+ limit (int): The number of requests to fetch. Default is 20.
1221
+ sort (str): The sorting order for the requests. Default is "FromMax".
1222
+
1223
+ Returns:
1224
+ Dict[str, Any]: The server's response containing new follow requests.
1225
+ """
1226
+ payload = {
1227
+ "profile_id": profile_id,
1228
+ "limit": limit,
1229
+ "sort": sort
1230
+ }
1231
+ return self._reuests_post("getNewFollowRequests", data=payload)
1232
+ def get_myprofile_posts(
1233
+ self,
1234
+ profile_id: Optional[str] = None ,
1235
+ limit: int = 20,
1236
+ sort: str = "FromMax"
1237
+ ) -> Dict[str, Any]:
1238
+ payload = {
1239
+ "profile_id": profile_id,
1240
+ "limit": limit,
1241
+ "sort": sort
1242
+ }
1243
+ return self._reuests_post("getMyProfilePosts", data=payload)
1244
+ def get_recent_following_posts(
1245
+ self,
1246
+ profile_id: Optional[str] = None ,
1247
+ limit: int = 20,
1248
+ sort: str = "FromMax"
1249
+ ) -> Dict[str, Any]:
1250
+ payload = {
1251
+ "profile_id": profile_id,
1252
+ "limit": limit,
1253
+ "sort": sort
1254
+ }
1255
+ return self._reuests_post("getRecentFollowingPosts", data=payload)
1256
+ def get_explore_post_topics(
1257
+ self,
1258
+ profile_id: Optional[str] = None ,
1259
+ ) -> Dict[str, Any]:
1260
+ payload = {
1261
+ "profile_id": profile_id,
1262
+ }
1263
+ return self._reuests_post("getExplorePostTopics", data=payload)
1264
+ def get_profiles_stories(
1265
+ self,
1266
+ profile_id: Optional[str] = None ,
1267
+ ) -> Dict[str, Any]:
1268
+ payload = {
1269
+ "profile_id": profile_id,
1270
+ }
1271
+ return self._reuests_post("getProfilesStories", data=payload)