├── .deepsource.toml ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── custom.md │ └── feature_request.md └── README.md ├── .gitignore ├── Aptfile ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── Exon ├── __init__.py ├── __main__.py ├── antispam.py ├── conf.py ├── elevated_users.json ├── events.py ├── langs │ ├── __init__.py │ ├── en.yaml │ ├── hi.yaml │ └── language.py ├── modules │ ├── ABISHNOI COPYRIGHT © │ ├── Callback.py │ ├── __init__.py │ ├── admin.py │ ├── afk.py │ ├── antichannel.py │ ├── antiflood.py │ ├── antiraid.py │ ├── approval.py │ ├── backups.py │ ├── bans.py │ ├── blacklist.py │ ├── blacklist_stickers.py │ ├── blacklistusers.py │ ├── cleaner.py │ ├── connection.py │ ├── cron_jobs.py │ ├── cust_filters.py │ ├── dbcleanup.py │ ├── debug.py │ ├── dev.py │ ├── disable.py │ ├── disable_help.py │ ├── disasters.py │ ├── error_handling.py │ ├── eval.py │ ├── feds.py │ ├── feedback.py │ ├── fonts.py │ ├── forcesub.py │ ├── global_bans.py │ ├── gtranslator.py │ ├── helper_funcs │ │ ├── ABISHNOI COPYRIGHT © │ │ ├── __init__.py │ │ ├── alternate.py │ │ ├── anonymous.py │ │ ├── chat_status.py │ │ ├── decorators.py │ │ ├── extraction.py │ │ ├── filters.py │ │ ├── formatter.py │ │ ├── git_api.py │ │ ├── handlers.py │ │ ├── misc.py │ │ ├── msg_types.py │ │ ├── readable_time.py │ │ ├── regex_helper.py │ │ ├── string_handling.py │ │ └── telethn │ │ │ ├── ABISHNOI © │ │ │ ├── __init__.py │ │ │ └── chatstatus.py │ ├── info.py │ ├── invitelinks.py │ ├── karmas.py │ ├── language.py │ ├── locks.py │ ├── log_channel.py │ ├── misc.py │ ├── modules.py │ ├── muting.py │ ├── nightmode.py │ ├── no_sql │ │ ├── ABISHNOI COPYRIGHT © │ │ ├── __init__.py │ │ ├── afk_db.py │ │ ├── blacklist_db.py │ │ ├── disable_db.py │ │ ├── fsub_db.py │ │ ├── global_bans_db.py │ │ ├── karma_db.py │ │ ├── log_channel_db.py │ │ └── users_db.py │ ├── notes.py │ ├── pin.py │ ├── ping.py │ ├── purge.py │ ├── quote.py │ ├── remote_cmds.py │ ├── repo.py │ ├── reporting.py │ ├── resources │ │ ├── asu.ttf │ │ └── fonts.py │ ├── rules.py │ ├── shell.py │ ├── sql │ │ ├── ABISHNOI COPYRIGHT © │ │ ├── __init__.py │ │ ├── acm_sql.py │ │ ├── antiflood_sql.py │ │ ├── antilinkedchannel_sql.py │ │ ├── approve_sql.py │ │ ├── blacklist_sql.py │ │ ├── blacklistusers_sql.py │ │ ├── blsticker_sql.py │ │ ├── cleaner_sql.py │ │ ├── clear_cmd_sql.py │ │ ├── connection_sql.py │ │ ├── cust_filters_sql.py │ │ ├── disable_sql.py │ │ ├── feds_sql.py │ │ ├── fsub_sql.py │ │ ├── language_sql.py │ │ ├── locks_sql.py │ │ ├── log_channel_sql.py │ │ ├── logger_sql.py │ │ ├── night_mode_sql.py │ │ ├── notes_sql.py │ │ ├── reporting_sql.py │ │ ├── rules_sql.py │ │ ├── userinfo_sql.py │ │ ├── warns_sql.py │ │ └── welcome_sql.py │ ├── stats.py │ ├── stickers.py │ ├── tags.py │ ├── tools.py │ ├── truth_and_dare.py │ ├── uall.py │ ├── ubot.py │ ├── userinfo.py │ ├── users.py │ ├── wallpaper.py │ ├── warns.py │ ├── watcher.py │ ├── weather.py │ ├── webss.py │ ├── welcome.py │ └── zombies.py └── utils │ ├── ABISHNOI © │ ├── __init__.py │ ├── adminpermissions.py │ ├── aiodownloader.py │ ├── dbfunctions.py │ ├── errors.py │ ├── exceptions.py │ ├── fetch.py │ ├── formatter.py │ ├── functions.py │ ├── http.py │ ├── keyboard.py │ ├── pastebin.py │ ├── permissions.py │ ├── pluginhelp.py │ ├── pluginhelpers.py │ ├── progress.py │ └── sections.py ├── LICENSE ├── Procfile ├── SECURITY.md ├── app.json ├── config.py ├── docker-compose.yml ├── heroku.yml ├── okteto-pipeline.yml ├── requirements.txt ├── restart.bat ├── runtime.txt ├── sample.env ├── start ├── start.bat └── start_service.bat /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "python" 5 | 6 | [analyzers.meta] 7 | runtime_version = "3.x.x" 8 | 9 | [[transformers]] 10 | name = "black" 11 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @AshokShau 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.session 3 | *.session-journal 4 | *.config.py 5 | .vscode/ 6 | postgres-data/ 7 | *.env 8 | !sample.env 9 | logs/ 10 | .idea/ 11 | 12 | Exon/config.py 13 | Exon/*.session 14 | Exon/*.session-journal 15 | Exon/config.ini 16 | log.txt 17 | *.pyc 18 | .idea/ 19 | .project 20 | .pydevproject 21 | .directory 22 | .vscode 23 | Exon/modules/helper_funcs/temp.txt 24 | Exon/elevated_users.json 25 | start-3.9.bat 26 | *.session 27 | kangsticker.png 28 | venv 29 | env 30 | Exon.session-journal 31 | updates.txt 32 | *.exe 33 | 34 | 35 | # Byte-compiled / optimized / DLL files 36 | __pycache__/ 37 | *.py[cod] 38 | *$py.class 39 | 40 | # C extensions 41 | *.so 42 | 43 | # Distribution / packaging 44 | .Python 45 | build/ 46 | develop-eggs/ 47 | dist/ 48 | downloads/ 49 | eggs/ 50 | .eggs/ 51 | lib/ 52 | lib64/ 53 | parts/ 54 | sdist/ 55 | var/ 56 | wheels/ 57 | pip-wheel-metadata/ 58 | share/python-wheels/ 59 | *.egg-info/ 60 | .installed.cfg 61 | *.egg 62 | MANIFEST 63 | 64 | # PyInstaller 65 | # Usually these files are written by a python script from a template 66 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 67 | *.manifest 68 | *.spec 69 | 70 | # Installer logs 71 | pip-log.txt 72 | pip-delete-this-directory.txt 73 | 74 | # Unit test / coverage reports 75 | htmlcov/ 76 | .tox/ 77 | .nox/ 78 | .coverage 79 | .coverage.* 80 | .cache 81 | nosetests.xml 82 | coverage.xml 83 | *.cover 84 | *.py,cover 85 | .hypothesis/ 86 | .pytest_cache/ 87 | 88 | # Translations 89 | *.mo 90 | *.pot 91 | 92 | # Django stuff: 93 | *.log 94 | local_settings.py 95 | db.sqlite3 96 | db.sqlite3-journal 97 | 98 | # Flask stuff: 99 | instance/ 100 | .webassets-cache 101 | 102 | # Scrapy stuff: 103 | .scrapy 104 | 105 | # Sphinx documentation 106 | docs/_build/ 107 | 108 | # PyBuilder 109 | target/ 110 | 111 | # Jupyter Notebook 112 | .ipynb_checkpoints 113 | 114 | # IPython 115 | profile_default/ 116 | ipython_config.py 117 | 118 | # pyenv 119 | .python-version 120 | 121 | # pipenv 122 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 123 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 124 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 125 | # install all needed dependencies. 126 | #Pipfile.lock 127 | 128 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 129 | __pypackages__/ 130 | 131 | # Celery stuff 132 | celerybeat-schedule 133 | celerybeat.pid 134 | 135 | # SageMath parsed files 136 | *.sage.py 137 | 138 | # Environments 139 | .env 140 | .venv 141 | env/ 142 | venv/ 143 | ENV/ 144 | env.bak/ 145 | venv.bak/ 146 | 147 | # Spyder project settings 148 | .spyderproject 149 | .spyproject 150 | 151 | # Rope project settings 152 | .ropeproject 153 | 154 | # mkdocs documentation 155 | /site 156 | 157 | # mypy 158 | .mypy_cache/ 159 | .dmypy.json 160 | dmypy.json 161 | 162 | # Pyre type checker 163 | .pyre/ 164 | -------------------------------------------------------------------------------- /Aptfile: -------------------------------------------------------------------------------- 1 | libgl1 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10.11 2 | 3 | WORKDIR /root/Exon 4 | 5 | COPY . . 6 | 7 | RUN pip3 install --upgrade pip setuptools 8 | 9 | RUN pip install -U -r requirements.txt 10 | 11 | CMD bash start 12 | -------------------------------------------------------------------------------- /Exon/conf.py: -------------------------------------------------------------------------------- 1 | from envparse import env 2 | 3 | from Exon import LOGGER 4 | 5 | DEFAULTS = { 6 | "LOAD_MODULES": True, 7 | } 8 | 9 | 10 | def get_str_key(name, required=False): 11 | default = DEFAULTS.get(name) 12 | if not (data := env.str(name, default=default)) and not required: 13 | LOGGER.warn(f"No str key: {name}") 14 | return None 15 | if data: 16 | return data 17 | LOGGER.critical(f"No str key: {name}") 18 | sys.exit(2) 19 | 20 | 21 | def get_int_key(name, required=False): 22 | default = DEFAULTS.get(name) 23 | if not (data := env.int(name, default=default)) and not required: 24 | LOGGER.warn(f"No int key: {name}") 25 | return None 26 | if data: 27 | return data 28 | LOGGER.critical(f"No int key: {name}") 29 | sys.exit(2) 30 | -------------------------------------------------------------------------------- /Exon/elevated_users.json: -------------------------------------------------------------------------------- 1 | { 2 | "devs": [ 3 | 5938660179 4 | ], 5 | "supports": [ 6 | 5938660179 7 | ], 8 | "whitelists": [ 9 | 5938660179 10 | ], 11 | "spammers": [ 12 | 5938660179 13 | ], 14 | "dragons": [ 15 | 5938660179 16 | ], 17 | "demons": [ 18 | 5938660179 19 | ], 20 | "wolfes": [ 21 | 5938660179 22 | ], 23 | "heroes": [ 24 | 5938660179 25 | ], 26 | "tigers": [ 27 | 5938660179 28 | ], 29 | "sudos": [ 30 | 5938660179 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /Exon/events.py: -------------------------------------------------------------------------------- 1 | from telethon import events 2 | 3 | from Exon import telethn 4 | 5 | 6 | def register(**args): 7 | """ʀᴇɢɪsᴛᴇʀs ᴀ ɴᴇᴡ ᴍᴇssᴀɢᴇ.""" 8 | pattern = args.get("pattern") 9 | 10 | r_pattern = r"^[/!]" 11 | 12 | if pattern is not None and not pattern.startswith("(?i)"): 13 | args["pattern"] = f"(?i){pattern}" 14 | 15 | args["pattern"] = pattern.replace("^/", r_pattern, 1) 16 | 17 | def decorator(func): 18 | telethn.add_event_handler(func, events.NewMessage(**args)) 19 | return func 20 | 21 | return decorator 22 | 23 | 24 | def Asuinline(**args): 25 | def decorator(func): 26 | telethn.add_event_handler(func, events.CallbackQuery(**args)) 27 | return func 28 | 29 | return decorator 30 | -------------------------------------------------------------------------------- /Exon/langs/__init__.py: -------------------------------------------------------------------------------- 1 | from Exon.langs.language import langs 2 | 3 | get_string = langs.get_string 4 | reload_strings = langs.reload_strings 5 | get_languages = langs.get_languages 6 | get_language = langs.get_language 7 | -------------------------------------------------------------------------------- /Exon/langs/language.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import Dict 3 | 4 | import yaml 5 | 6 | 7 | class Language: 8 | def __init__(self) -> None: 9 | self.languages: Dict = {} 10 | self.reload_strings() 11 | 12 | def get_string(self, lang: str, string: str) -> str: 13 | try: 14 | return self.languages[lang][string] 15 | except KeyError as e: 16 | # a keyerror happened, the english file must have it 17 | en_string = self.languages["en"].get(string) 18 | if en_string is None: 19 | raise StringNotFound(f"String: ({string}) not found.") from e 20 | return en_string 21 | 22 | def reload_strings(self) -> None: 23 | for filename in os.listdir(r"./Exon/langs"): 24 | if filename.endswith(".yaml"): 25 | language_name = filename[:-5] 26 | self.languages[language_name] = yaml.safe_load( 27 | open(f"./Exon/langs/{filename}", encoding="utf8") 28 | ) 29 | 30 | def get_languages(self) -> Dict: 31 | to_return: Dict = { 32 | language: self.languages[language]["language"] 33 | for language in self.languages 34 | } 35 | return to_return 36 | 37 | def get_language(self, language: str) -> str: 38 | return self.languages[language]["language"] 39 | 40 | 41 | class StringNotFound(Exception): 42 | """ 43 | Raised when language string not found for the 44 | given key inside english locale. 45 | """ 46 | 47 | 48 | langs = Language() 49 | -------------------------------------------------------------------------------- /Exon/modules/ABISHNOI COPYRIGHT ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # MY ALL BOTS :- Abishnoi_bots 28 | # GITHUB :- KingAbishnoi "" -------------------------------------------------------------------------------- /Exon/modules/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import sys 31 | 32 | from Exon import LOAD, LOGGER, NO_LOAD 33 | 34 | 35 | def __list_all_modules(): 36 | import glob 37 | from os.path import basename, dirname, isfile 38 | 39 | # This generates a list of modules in this folder for the * in __main__ to work. 40 | mod_paths = glob.glob(f"{dirname(__file__)}/*.py") 41 | all_modules = [ 42 | basename(f)[:-3] 43 | for f in mod_paths 44 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") 45 | ] 46 | 47 | if LOAD or NO_LOAD: 48 | to_load = LOAD 49 | if to_load: 50 | if not all( 51 | any(mod == module_name for module_name in all_modules) 52 | for mod in to_load 53 | ): 54 | LOGGER.error("ɪɴᴠᴀʟɪᴅ ʟᴏᴀᴅᴏʀᴅᴇʀ ɴᴀᴍᴇs. ǫᴜɪᴛᴛɪɴɢ.") 55 | sys.exit(1) 56 | 57 | all_modules = sorted(set(all_modules) - set(to_load)) 58 | to_load = list(all_modules) + to_load 59 | 60 | else: 61 | to_load = all_modules 62 | 63 | if NO_LOAD: 64 | LOGGER.info(f"Not loading: {NO_LOAD}") 65 | return [item for item in to_load if item not in NO_LOAD] 66 | 67 | return to_load 68 | 69 | return all_modules 70 | 71 | 72 | ALL_MODULES = __list_all_modules() 73 | 74 | __all__ = ALL_MODULES + ["ALL_MODULES"] 75 | -------------------------------------------------------------------------------- /Exon/modules/cron_jobs.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | 31 | import datetime 32 | import os 33 | import shutil 34 | import subprocess 35 | from time import sleep 36 | 37 | from telegram.ext.callbackcontext import CallbackContext 38 | from telegram.ext.filters import Filters 39 | from telegram.update import Update 40 | 41 | from Exon import BACKUP_PASS, DB_URL, DEV_USERS, LOGGER, OWNER_ID, dispatcher 42 | from Exon.modules.helper_funcs.decorators import Exoncmd 43 | 44 | 45 | @Exoncmd(command="backupdb", filters=Filters.user(DEV_USERS) | Filters.user(OWNER_ID)) 46 | def backup_now(_: Update, ctx: CallbackContext): 47 | cronjob.run(dispatcher=dispatcher) 48 | 49 | 50 | @Exoncmd(command="stopjobs", filters=Filters.user(DEV_USERS) | Filters.user(OWNER_ID)) 51 | def stop_jobs(update: Update, _: CallbackContext): 52 | print(j.stop()) 53 | update.effective_message.reply_text("Scheduler has been shut down") 54 | 55 | 56 | @Exoncmd(command="startjobs", filters=Filters.user(DEV_USERS) | Filters.user(OWNER_ID)) 57 | def start_jobs(update: Update, _: CallbackContext): 58 | print(j.start()) 59 | update.effective_message.reply_text("Scheduler started") 60 | 61 | 62 | zip_pass = BACKUP_PASS 63 | 64 | 65 | def backup_db(_: CallbackContext): 66 | bot = dispatcher.bot 67 | tmpmsg = "Performing backup, Please wait..." 68 | tmp = bot.send_message(OWNER_ID, tmpmsg) 69 | datenow = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") 70 | dbbkpname = f"db_{bot.username}_{datenow}.tar" 71 | bkplocation = f"backups/{datenow}" 72 | bkpcmd = f"pg_dump {DB_URL} --format=tar > {bkplocation}/{dbbkpname}" 73 | 74 | if not os.path.exists(bkplocation): 75 | os.makedirs(bkplocation) 76 | LOGGER.info("Performing db backup") 77 | loginfo = "db backup" 78 | term(bkpcmd, loginfo) 79 | if not os.path.exists(f"{bkplocation}/{dbbkpname}"): 80 | bot.send_message(OWNER_ID, "An error occurred during the db backup") 81 | tmp.edit_text("Backup Failed!") 82 | sleep(8) 83 | tmp.delete() 84 | return 85 | else: 86 | LOGGER.info("Copying config, and logs to backup location") 87 | if os.path.exists("logs.txt"): 88 | print("Logs copied") 89 | shutil.copyfile("logs.txt", f"{bkplocation}/logs.txt") 90 | if os.path.exists("config.ini"): 91 | print("Config copied") 92 | shutil.copyfile("config.ini", f"{bkplocation}/config.ini") 93 | LOGGER.info("Zipping the backup") 94 | zipcmd = f"zip --password '{zip_pass}' {bkplocation} {bkplocation}/*" 95 | zipinfo = "zipping db backup" 96 | LOGGER.info("Zip initiated") 97 | term(zipcmd, zipinfo) 98 | LOGGER.info("Zip done") 99 | sleep(1) 100 | with open(f"backups/{datenow}.zip", "rb") as bkp: 101 | nm = f"{bot.username} backup \n{datenow}" 102 | bot.send_document(OWNER_ID, document=bkp, caption=nm, timeout=20) 103 | LOGGER.info("Removing zipped files") 104 | shutil.rmtree(f"backups/{datenow}") 105 | LOGGER.info("Backup done") 106 | tmp.edit_text("Backup complete!") 107 | sleep(5) 108 | tmp.delete() 109 | 110 | 111 | @Exoncmd( 112 | command="purgebackups", filters=Filters.user(DEV_USERS) | Filters.user(OWNER_ID) 113 | ) 114 | def del_bkp_fldr(update: Update, _: CallbackContext): 115 | shutil.rmtree("backups") 116 | update.effective_message.reply_text("'Backups' directory has been purged!") 117 | 118 | 119 | def term(cmd, info): 120 | process = subprocess.Popen( 121 | cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True 122 | ) 123 | stdout, stderr = process.communicate() 124 | stderr = stderr.decode() 125 | if stdout := stdout.decode(): 126 | LOGGER.info(f"{info} successful!") 127 | LOGGER.info(f"{stdout}") 128 | if stderr: 129 | LOGGER.error(f"error while running {info}") 130 | LOGGER.info(f"{stderr}") 131 | 132 | 133 | from Exon import updater as u 134 | 135 | # run the backup daily at 1:00 136 | twhen = datetime.datetime.strptime("01:00", "%H:%M").time() 137 | j = u.job_queue 138 | cronjob = j.run_daily(callback=backup_db, name="database backups", time=twhen) 139 | -------------------------------------------------------------------------------- /Exon/modules/debug.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | import datetime 30 | import os 31 | 32 | from telegram import Update 33 | from telegram.ext import CallbackContext, CommandHandler 34 | from telethon import events 35 | 36 | from Exon import dispatcher, telethn 37 | from Exon.modules.helper_funcs.chat_status import dev_plus 38 | 39 | DEBUG_MODE = False 40 | 41 | 42 | @dev_plus 43 | def debug(update: Update, context: CallbackContext): 44 | global DEBUG_MODE 45 | args = update.effective_message.text.split(None, 1) 46 | message = update.effective_message 47 | print(DEBUG_MODE) 48 | if len(args) > 1: 49 | if args[1] in ("yes", "on"): 50 | DEBUG_MODE = True 51 | message.reply_text("Debug mode is now on.") 52 | elif args[1] in ("no", "off"): 53 | DEBUG_MODE = False 54 | message.reply_text("Debug mode is now off.") 55 | elif DEBUG_MODE: 56 | message.reply_text("Debug mode is currently on.") 57 | else: 58 | message.reply_text("Debug mode is currently off.") 59 | 60 | 61 | @telethn.on(events.NewMessage(pattern="[/!].*")) 62 | async def i_do_nothing_yes(event): 63 | if DEBUG_MODE: 64 | print(f"-{event.from_id} ({event.chat_id}) : {event.text}") 65 | if os.path.exists("updates.txt"): 66 | with open("updates.txt", "r") as f: 67 | text = f.read() 68 | with open("updates.txt", "w+") as f: 69 | f.write(f"{text}\n-{event.from_id} ({event.chat_id}) : {event.text}") 70 | else: 71 | with open("updates.txt", "w+") as f: 72 | f.write( 73 | f"- {event.from_id} ({event.chat_id}) : {event.text} | {datetime.datetime.now()}", 74 | ) 75 | 76 | 77 | support_chat = os.getenv("SUPPORT_CHAT") 78 | 79 | 80 | @dev_plus 81 | def logs(update: Update, context: CallbackContext): 82 | user = update.effective_user 83 | with open("log.txt", "rb") as f: 84 | context.bot.send_document(document=f, filename=f.name, chat_id=user.id) 85 | 86 | 87 | LOG_HANDLER = CommandHandler("logs", logs, run_async=True) 88 | DEBUG_HANDLER = CommandHandler("debug", debug, run_async=True) 89 | 90 | dispatcher.add_handler(LOG_HANDLER) 91 | dispatcher.add_handler(DEBUG_HANDLER) 92 | 93 | __mod_name__ = "𝐃ᴇʙᴜɢ" 94 | 95 | __command_list__ = ["debug"] 96 | 97 | __handlers__ = [DEBUG_HANDLER] 98 | 99 | # ғᴏʀ ʜᴇʟᴘ ᴍᴇɴᴜ 100 | 101 | 102 | # """ 103 | from Exon.modules.language import gs 104 | 105 | 106 | def get_help(chat): 107 | return gs(chat, "debug_help") 108 | 109 | # """ 110 | -------------------------------------------------------------------------------- /Exon/modules/disable_help.py: -------------------------------------------------------------------------------- 1 | from Exon.modules.language import gs 2 | 3 | 4 | def get_help(chat): 5 | return gs(chat, "disable_help") 6 | 7 | 8 | __mod_name__ = "𝐃ɪsᴀʙʟᴇ" 9 | -------------------------------------------------------------------------------- /Exon/modules/feedback.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | import random 31 | 32 | from telegram import ParseMode 33 | from telethon import Button 34 | 35 | from Exon import OWNER_ID, SUPPORT_CHAT 36 | from Exon import telethn as tbot 37 | from ..events import register 38 | 39 | 40 | @register(pattern="/feedback ?(.*)") 41 | async def feedback(e): 42 | quew = e.pattern_match.group(1) 43 | user_id = e.sender.id 44 | user_name = e.sender.first_name 45 | mention = f"[{user_name}](tg://user?id={str(user_id)})" 46 | Exon = ( 47 | "https://telegra.ph/file/753bfe51f0e0314f1f3ff.jpg", 48 | "https://telegra.ph/file/20bab4a499d6dccd823f1.jpg", 49 | "https://telegra.ph/file/2ef1c255ac51d9febb3f4.jpg", 50 | "https://telegra.ph/file/bc3a10df7c66e6333bba6.jpg", 51 | "https://telegra.ph/file/bf283996f928a6ab5b625.jpg", 52 | "https://telegra.ph/file/bf283996f928a6ab5b625.jpg", 53 | "https://telegra.ph/file/43b4f5a5645ab1cd1dd7c.jpg", 54 | "https://telegra.ph/file/0f5240ad4d50d5dac57fe.jpg", 55 | "https://telegra.ph/file/f6128a7a197cf088ba5e0.jpg", 56 | "https://telegra.ph/file/53d0320dcaa0d21da19c0.jpg", 57 | "https://telegra.ph/file/fc988e9441acfb5fe71a7.jpg", 58 | "https://telegra.ph/file/731387573fd96e3cfc2f5.jpg", 59 | "https://telegra.ph/file/6c9951e14cece66f2fc3a.jpg", 60 | ) 61 | NATFEED = ("https://telegra.ph/file/2dd04f407b16bc2cfdf76.jpg",) 62 | BUTTON = [[Button.url("Go To Support Group", f"https://t.me/{SUPPORT_CHAT}")]] 63 | TEXT = "ᴛʜᴀɴᴋꜱ ꜰᴏʀ ʏᴏᴜʀ ꜰᴇᴇᴅʙᴀᴄᴋ, ɪ ʜᴏᴘᴇ ʏᴏᴜ ʜᴀᴘᴘʏ ᴡɪᴛʜ ᴏᴜʀ ꜱᴇʀᴠɪᴄᴇ." 64 | logger_text = f""" 65 | **ɴᴇᴡ ꜰᴇᴇᴅʙᴀᴄᴋ** 66 | 67 | **ꜰʀᴏᴍ ᴜꜱᴇʀ:** {mention} 68 | **ᴜꜱᴇʀɴᴀᴍᴇ:** @{e.sender.username} 69 | **ᴜꜱᴇʀ ɪᴅ:** `{e.sender.id}` 70 | **ꜰᴇᴇᴅʙᴀᴄᴋ:** `{e.text}` 71 | """ 72 | if e.sender_id != OWNER_ID and not quew: 73 | GIVE = "ɢɪᴠᴇ ꜱᴏᴍᴇ ᴛᴇxᴛ ꜰᴏʀ ꜰᴇᴇᴅʙᴄᴋ ✨" 74 | await e.reply( 75 | GIVE, 76 | parse_mode=ParseMode.MARKDOWN, 77 | buttons=BUTTON, 78 | file=random.choice(NATFEED), 79 | ), 80 | return 81 | 82 | await tbot.send_message( 83 | SUPPORT_CHAT, 84 | f"{logger_text}", 85 | file=random.choice(Exon), 86 | link_preview=False, 87 | ) 88 | await e.reply(TEXT, file=random.choice(Exon), buttons=BUTTON) 89 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/ABISHNOI COPYRIGHT ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # MY ALL BOTS :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/__init__.py: -------------------------------------------------------------------------------- 1 | """ @Abishnoi1M""" 2 | """ 3 | MIT License 4 | 5 | Copyright (c) 2022 ABISHNOI69 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | """ 25 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/alternate.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from functools import wraps 26 | 27 | from telegram import ChatAction 28 | from telegram.error import BadRequest 29 | 30 | 31 | def send_message(message, text, *args, **kwargs): 32 | try: 33 | return message.reply_text(text, *args, **kwargs) 34 | except BadRequest as err: 35 | if str(err) == "Reply message not found": 36 | return message.reply_text(text, quote=False, *args, **kwargs) 37 | 38 | 39 | def typing_action(func): 40 | """Sends typing action while processing func command.""" 41 | 42 | @wraps(func) 43 | def command_func(update, context, *args, **kwargs): 44 | context.bot.send_chat_action( 45 | chat_id=update.effective_chat.id, 46 | action=ChatAction.TYPING, 47 | ) 48 | return func(update, context, *args, **kwargs) 49 | 50 | return command_func 51 | 52 | 53 | def send_action(action): 54 | """Sends `action` while processing func command.""" 55 | 56 | def decorator(func): 57 | @wraps(func) 58 | def command_func(update, context, *args, **kwargs): 59 | context.bot.send_chat_action( 60 | chat_id=update.effective_chat.id, action=action 61 | ) 62 | return func(update, context, *args, **kwargs) 63 | 64 | return command_func 65 | 66 | return decorator 67 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/filters.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from emoji import UNICODE_EMOJI 26 | from telegram import Message 27 | from telegram.ext import MessageFilter 28 | 29 | from Exon import DEMONS, DEV_USERS 30 | 31 | 32 | class CustomFilters: 33 | class _Supporters(MessageFilter): 34 | def filter(self, message: Message): 35 | return bool(message.from_user and message.from_user.id in DEMONS) 36 | 37 | support_filter = _Supporters() 38 | 39 | class _Sudoers(MessageFilter): 40 | def filter(self, message: Message): 41 | return bool(message.from_user and message.from_user.id in DEV_USERS) 42 | 43 | dev_filter = _Sudoers() 44 | 45 | class _MimeType(MessageFilter): 46 | def __init__(self, mimetype): 47 | self.mime_type = mimetype 48 | self.name = f"CustomFilters.mime_type({self.mime_type})" 49 | 50 | def filter(self, message: Message): 51 | return bool( 52 | message.document and message.document.mime_type == self.mime_type 53 | ) 54 | 55 | mime_type = _MimeType 56 | 57 | class _HasText(MessageFilter): 58 | def filter(self, message: Message): 59 | return bool( 60 | message.text 61 | or message.sticker 62 | or message.photo 63 | or message.document 64 | or message.video 65 | ) 66 | 67 | has_text = _HasText() 68 | 69 | class _HasEmoji(MessageFilter): 70 | def filter(self, message: Message): 71 | text = message.text or "" 72 | for emoji in UNICODE_EMOJI: 73 | for letter in text: 74 | if letter == emoji: 75 | return True 76 | return False 77 | 78 | has_emoji = _HasEmoji() 79 | 80 | class _IsEmoji(MessageFilter): 81 | def filter(self, message: Message): 82 | if message.text and len(message.text) == 1: 83 | for emoji in UNICODE_EMOJI: 84 | for letter in message.text: 85 | if letter == emoji: 86 | return True 87 | return False 88 | 89 | is_emoji = _IsEmoji() 90 | 91 | class _IsAnonChannel(MessageFilter): 92 | def filter(self, message: Message): 93 | return bool(message.from_user and message.from_user.id == 136817688) 94 | 95 | is_anon_channel = _IsAnonChannel() 96 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/formatter.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | 26 | def get_readable_time(seconds: int) -> str: 27 | count = 0 28 | ping_time = "" 29 | time_list = [] 30 | time_suffix_list = ["s", "m", "h", "days"] 31 | while count < 4: 32 | count += 1 33 | remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) 34 | if seconds == 0 and remainder == 0: 35 | break 36 | time_list.append(int(result)) 37 | seconds = int(remainder) 38 | for i in range(len(time_list)): 39 | time_list[i] = str(time_list[i]) + time_suffix_list[i] 40 | if len(time_list) == 4: 41 | ping_time += f"{time_list.pop()}, " 42 | time_list.reverse() 43 | ping_time += ":".join(time_list) 44 | return ping_time 45 | 46 | 47 | # Convert seconds to mm:ss 48 | async def convert_seconds_to_minutes(seconds: int): 49 | seconds = seconds 50 | seconds %= 24 * 3600 51 | seconds %= 3600 52 | minutes = seconds // 60 53 | seconds %= 60 54 | return "%02d:%02d" % (minutes, seconds) 55 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/git_api.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import json 26 | import urllib.request as url 27 | 28 | VERSION = "1.1.0" 29 | APIURL = "http://api.github.com/repos/" 30 | 31 | 32 | def vercheck() -> str: 33 | return str(VERSION) 34 | 35 | 36 | # Repo-wise stuff 37 | 38 | 39 | def getData(repoURL): 40 | try: 41 | with url.urlopen(APIURL + repoURL + "/releases") as data_raw: 42 | return json.loads(data_raw.read().decode()) 43 | except Exception: 44 | return None 45 | 46 | 47 | def getReleaseData(repoData, index): 48 | return repoData[index] if index < len(repoData) else None 49 | 50 | 51 | # Release-wise stuff 52 | 53 | 54 | def getAuthor(releaseData): 55 | return None if releaseData is None else releaseData["author"]["login"] 56 | 57 | 58 | def getAuthorUrl(releaseData): 59 | return None if releaseData is None else releaseData["author"]["html_url"] 60 | 61 | 62 | def getReleaseName(releaseData): 63 | return None if releaseData is None else releaseData["name"] 64 | 65 | 66 | def getReleaseDate(releaseData): 67 | return None if releaseData is None else releaseData["published_at"] 68 | 69 | 70 | def getAssetsSize(releaseData): 71 | return None if releaseData is None else len(releaseData["assets"]) 72 | 73 | 74 | def getAssets(releaseData): 75 | return None if releaseData is None else releaseData["assets"] 76 | 77 | 78 | def getBody(releaseData): # changelog stuff 79 | return None if releaseData is None else releaseData["body"] 80 | 81 | 82 | # Asset-wise stuff 83 | 84 | 85 | def getReleaseFileName(asset): 86 | return asset["name"] 87 | 88 | 89 | def getReleaseFileURL(asset): 90 | return asset["browser_download_url"] 91 | 92 | 93 | def getDownloadCount(asset): 94 | return asset["download_count"] 95 | 96 | 97 | def getSize(asset): 98 | return asset["size"] 99 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/readable_time.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | 26 | def get_readable_time(seconds: int) -> str: 27 | count = 0 28 | readable_time = "" 29 | time_list = [] 30 | time_suffix_list = ["s", "ᴍ", "ʜ", "ᴅᴀʏs"] 31 | 32 | while count < 4: 33 | count += 1 34 | remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) 35 | if seconds == 0 and remainder == 0: 36 | break 37 | time_list.append(int(result)) 38 | seconds = int(remainder) 39 | 40 | for x in range(len(time_list)): 41 | time_list[x] = str(time_list[x]) + time_suffix_list[x] 42 | if len(time_list) == 4: 43 | readable_time += f"{time_list.pop()}, " 44 | 45 | time_list.reverse() 46 | readable_time += ":".join(time_list) 47 | 48 | return readable_time 49 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/regex_helper.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | import regex 25 | 26 | 27 | def regex_searcher(regex_string, string): 28 | try: 29 | search = regex.search(regex_string, string, timeout=6) 30 | except (TimeoutError, Exception): 31 | return False 32 | return search 33 | 34 | 35 | def infinite_loop_check(regex_string): 36 | loop_matches = [ 37 | r"\((.{1,}[\+\*]){1,}\)[\+\*].", 38 | r"[\(\[].{1,}\{\d(,)?\}[\)\]]\{\d(,)?\}", 39 | r"\(.{1,}\)\{.{1,}(,)?\}\(.*\)(\+|\* |\{.*\})", 40 | ] 41 | for match in loop_matches: 42 | if match_1 := regex.search(match, regex_string): 43 | return True 44 | return False 45 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/telethn/ABISHNOI ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # """DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # MY ALL BOTS :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 """ 29 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/telethn/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from Exon import DEMONS, DEV_USERS, DRAGONS, TIGERS, WOLVES 26 | 27 | IMMUNE_USERS = DRAGONS + WOLVES + DEMONS + TIGERS + DEV_USERS 28 | 29 | IMMUNE_USERS = ( 30 | list(DRAGONS) + list(WOLVES) + list(DEMONS) + list(TIGERS) + list(DEV_USERS) 31 | ) 32 | -------------------------------------------------------------------------------- /Exon/modules/helper_funcs/telethn/chatstatus.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from telethon.tl.types import ChannelParticipantsAdmins 26 | 27 | from Exon import DRAGONS 28 | from Exon.modules.helper_funcs.telethn import IMMUNE_USERS, telethn 29 | 30 | 31 | async def user_is_ban_protected(user_id: int, message): 32 | status = False 33 | if message.is_private or user_id in (IMMUNE_USERS): 34 | return True 35 | 36 | async for user in telethn.iter_participants( 37 | message.chat_id, 38 | filter=ChannelParticipantsAdmins, 39 | ): 40 | if user_id == user.id: 41 | status = True 42 | break 43 | return status 44 | 45 | 46 | async def user_is_admin(user_id: int, message): 47 | status = False 48 | if message.is_private: 49 | return True 50 | 51 | async for user in telethn.iter_participants( 52 | message.chat_id, 53 | filter=ChannelParticipantsAdmins, 54 | ): 55 | if user_id == user.id or user_id in DRAGONS: 56 | status = True 57 | break 58 | return status 59 | 60 | 61 | async def is_user_admin(user_id: int, chat_id): 62 | status = False 63 | async for user in telethn.iter_participants( 64 | chat_id, 65 | filter=ChannelParticipantsAdmins, 66 | ): 67 | if user_id == user.id or user_id in DRAGONS: 68 | status = True 69 | break 70 | return status 71 | 72 | 73 | async def natsunagi_is_admin(chat_id: int): 74 | status = False 75 | natsunagi = await telethn.get_me() 76 | async for user in telethn.iter_participants( 77 | chat_id, 78 | filter=ChannelParticipantsAdmins, 79 | ): 80 | if natsunagi.id == user.id: 81 | status = True 82 | break 83 | return status 84 | 85 | 86 | async def is_user_in_chat(chat_id: int, user_id: int): 87 | status = False 88 | async for user in telethn.iter_participants(chat_id): 89 | if user_id == user.id: 90 | status = True 91 | break 92 | return status 93 | 94 | 95 | async def can_change_info(message): 96 | return message.chat.admin_rights.change_info if message.chat.admin_rights else False 97 | 98 | 99 | async def can_ban_users(message): 100 | return message.chat.admin_rights.ban_users if message.chat.admin_rights else False 101 | 102 | 103 | async def can_pin_messages(message): 104 | return ( 105 | message.chat.admin_rights.pin_messages if message.chat.admin_rights else False 106 | ) 107 | 108 | 109 | async def can_invite_users(message): 110 | return ( 111 | message.chat.admin_rights.invite_users if message.chat.admin_rights else False 112 | ) 113 | 114 | 115 | async def can_add_admins(message): 116 | return message.chat.admin_rights.add_admins if message.chat.admin_rights else False 117 | 118 | 119 | async def can_delete_messages(message): 120 | if message.is_private: 121 | return True 122 | if message.chat.admin_rights: 123 | return message.chat.admin_rights.delete_messages 124 | return False 125 | -------------------------------------------------------------------------------- /Exon/modules/info.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | from pyrogram import filters 31 | from pyrogram.types import Message 32 | 33 | from Exon import Abishnoi as app 34 | from Exon import DEV_USERS 35 | from Exon.utils.sections import section 36 | 37 | 38 | async def get_user_info(user, already=False): 39 | if not already: 40 | user = await app.get_users(user) 41 | if not user.first_name: 42 | return ["Deleted account", None] 43 | user_id = user.id 44 | username = user.username 45 | first_name = user.first_name 46 | mention = user.mention("Link") 47 | dc_id = user.dc_id 48 | photo_id = user.photo.big_file_id if user.photo else None 49 | is_sudo = user_id in DEV_USERS 50 | body = { 51 | "ID": user_id, 52 | "DC": dc_id, 53 | "Name": [first_name], 54 | "Username": [f"@{username}" if username else None], 55 | "Mention": [mention], 56 | "Sudo": is_sudo, 57 | } 58 | caption = section("User info", body) 59 | return [caption, photo_id] 60 | 61 | 62 | async def get_chat_info(chat, already=False): 63 | if not already: 64 | chat = await app.get_chat(chat) 65 | chat_id = chat.id 66 | username = chat.username 67 | title = chat.title 68 | type_ = chat.type 69 | is_scam = chat.is_scam 70 | description = chat.description 71 | members = chat.members_count 72 | is_restricted = chat.is_restricted 73 | link = f"[Link](t.me/{username})" if username else None 74 | dc_id = chat.dc_id 75 | photo_id = chat.photo.big_file_id if chat.photo else None 76 | body = { 77 | "ID": chat_id, 78 | "DC": dc_id, 79 | "Type": type_, 80 | "Name": [title], 81 | "Username": [f"@{username}" if username else None], 82 | "Mention": [link], 83 | "Members": members, 84 | "Scam": is_scam, 85 | "Restricted": is_restricted, 86 | "Description": [description], 87 | } 88 | caption = section("Chat info", body) 89 | return [caption, photo_id] 90 | 91 | 92 | @app.on_message(filters.command("uinfo")) 93 | async def info_func(_, message: Message): 94 | if message.reply_to_message: 95 | user = message.reply_to_message.from_user.id 96 | elif len(message.command) == 1: 97 | user = message.from_user.id 98 | else: 99 | user = message.text.split(None, 1)[1] 100 | 101 | m = await message.reply_text("Processing...") 102 | 103 | try: 104 | info_caption, photo_id = await get_user_info(user) 105 | except Exception as e: 106 | return await m.edit(str(e)) 107 | 108 | if not photo_id: 109 | return await m.edit(info_caption, disable_web_page_preview=True) 110 | photo = await app.download_media(photo_id) 111 | 112 | await message.reply_photo(photo, caption=info_caption, quote=False) 113 | await m.delete() 114 | os.remove(photo) 115 | 116 | 117 | @app.on_message(filters.command("cinfo")) 118 | async def chat_info_func(_, message: Message): 119 | try: 120 | if len(message.command) > 2: 121 | return await message.reply_text("**Usage:**cinfo ") 122 | 123 | if len(message.command) == 1: 124 | chat = message.chat.id 125 | elif len(message.command) == 2: 126 | chat = message.text.split(None, 1)[1] 127 | 128 | m = await message.reply_text("Processing...") 129 | 130 | info_caption, photo_id = await get_chat_info(chat) 131 | if not photo_id: 132 | return await m.edit(info_caption, disable_web_page_preview=True) 133 | 134 | photo = await app.download_media(photo_id) 135 | await message.reply_photo(photo, caption=info_caption, quote=False) 136 | 137 | await m.delete() 138 | os.remove(photo) 139 | except Exception as e: 140 | await m.edit(e) 141 | 142 | 143 | __mod_name__ = "𝐂ɪɴғᴏ" 144 | 145 | # ғᴏʀ ʜᴇʟᴘ ᴍᴇɴᴜ 146 | 147 | 148 | # """ 149 | from Exon.modules.language import gs 150 | 151 | 152 | def get_help(chat): 153 | return gs(chat, "cinfo_help") 154 | 155 | # """ 156 | -------------------------------------------------------------------------------- /Exon/modules/invitelinks.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | import html 31 | import re 32 | 33 | from telegram import ParseMode 34 | from telegram.ext import ChatJoinRequestHandler 35 | from telegram.ext.callbackcontext import CallbackContext 36 | from telegram.inline.inlinekeyboardbutton import InlineKeyboardButton 37 | from telegram.inline.inlinekeyboardmarkup import InlineKeyboardMarkup 38 | from telegram.update import Update 39 | from telegram.utils.helpers import mention_html 40 | 41 | from Exon import dispatcher 42 | from Exon.modules.helper_funcs.chat_status import bot_admin, user_can_restrict_no_reply 43 | from Exon.modules.helper_funcs.decorators import Exoncallback 44 | from Exon.modules.log_channel import loggable 45 | 46 | 47 | def chat_join_req(upd: Update, ctx: CallbackContext): 48 | bot = ctx.bot 49 | user = upd.chat_join_request.from_user 50 | chat = upd.chat_join_request.chat 51 | keyboard = InlineKeyboardMarkup( 52 | [ 53 | [ 54 | InlineKeyboardButton( 55 | "ᴀᴘᴘʀᴏᴠᴇ", callback_data=f"cb_approve={user.id}" 56 | ), 57 | InlineKeyboardButton( 58 | "ᴅᴇᴄʟɪɴᴇ", callback_data=f"cb_decline={user.id}" 59 | ), 60 | ] 61 | ] 62 | ) 63 | bot.send_message( 64 | chat.id, 65 | f'{mention_html(user.id, user.first_name)} ᴡᴀɴᴛs ᴛᴏ ᴊᴏɪɴ {chat.title or "this chat"}', 66 | reply_markup=keyboard, 67 | parse_mode=ParseMode.HTML, 68 | ) 69 | 70 | 71 | @Exoncallback(pattern=r"cb_approve=") 72 | @user_can_restrict_no_reply 73 | @bot_admin 74 | @loggable 75 | def approve_joinreq(update: Update, context: CallbackContext) -> str: 76 | bot = context.bot 77 | query = update.callback_query 78 | user = update.effective_user 79 | chat = update.effective_chat 80 | match = re.match(r"cb_approve=(.+)", query.data) 81 | 82 | user_id = match[1] 83 | try: 84 | bot.approve_chat_join_request(chat.id, user_id) 85 | update.effective_message.edit_text( 86 | f"ᴊᴏɪɴ ʀᴇǫᴜᴇsᴛ ᴀᴘᴘʀᴏᴠᴇᴅ ʙʏ {mention_html(user.id, user.first_name)}.", 87 | parse_mode="HTML", 88 | ) 89 | return f"{html.escape(chat.title)}:\n#𝐉𝐎𝐈𝐍_𝐑𝐄𝐐𝐔𝐄𝐒𝐓\nᴀᴘᴘʀᴏᴠᴇᴅ\nᴀᴅᴍɪɴ: {mention_html(user.id, html.escape(user.first_name))}\nᴜsᴇʀ: {mention_html(user_id, html.escape(user.first_name))}\n" 90 | except Exception as e: 91 | update.effective_message.edit_text(str(e)) 92 | 93 | 94 | @Exoncallback(pattern=r"cb_decline=") 95 | @user_can_restrict_no_reply 96 | @bot_admin 97 | @loggable 98 | def decline_joinreq(update: Update, context: CallbackContext) -> str: 99 | bot = context.bot 100 | query = update.callback_query 101 | user = update.effective_user 102 | chat = update.effective_chat 103 | match = re.match(r"cb_decline=(.+)", query.data) 104 | 105 | user_id = match[1] 106 | try: 107 | bot.decline_chat_join_request(chat.id, user_id) 108 | update.effective_message.edit_text( 109 | f"ᴊᴏɪɴ ʀᴇǫᴜᴇsᴛ ᴅᴇᴄʟɪɴᴇᴅ ʙʏ {mention_html(user.id, user.first_name)}.", 110 | parse_mode="HTML", 111 | ) 112 | return f"{html.escape(chat.title)}:\n#𝐉𝐎𝐈𝐍_𝐑𝐄𝐐𝐔𝐄𝐒𝐓\nᴅᴇᴄʟɪɴᴇᴅ\nᴀᴅᴍɪɴ: {mention_html(user.id, html.escape(user.first_name))}\nᴜsᴇʀ: {mention_html(user_id, html.escape(user.first_name))}\n" 113 | except Exception as e: 114 | update.effective_message.edit_text(str(e)) 115 | 116 | 117 | dispatcher.add_handler(ChatJoinRequestHandler(callback=chat_join_req, run_async=True)) 118 | -------------------------------------------------------------------------------- /Exon/modules/language.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import itertools 30 | from collections.abc import Iterable 31 | from typing import Generator, List, Union 32 | 33 | from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update 34 | 35 | import Exon.modules.sql.language_sql as sql 36 | from Exon.langs import get_language, get_languages, get_string 37 | from Exon.modules.helper_funcs.chat_status import user_admin, user_admin_no_reply 38 | from Exon.modules.helper_funcs.decorators import Exoncallback, Exoncmd 39 | 40 | 41 | def paginate(iterable: Iterable, page_size: int) -> Generator[List, None, None]: 42 | while True: 43 | i1, i2 = itertools.tee(iterable) 44 | iterable, page = ( 45 | itertools.islice(i1, page_size, None), 46 | list(itertools.islice(i2, page_size)), 47 | ) 48 | if not page: 49 | break 50 | yield page 51 | 52 | 53 | def gs(chat_id: Union[int, str], string: str) -> str: 54 | try: 55 | lang = sql.get_chat_lang(chat_id) 56 | return get_string(lang, string) 57 | except Exception: 58 | return "ᴍᴇ ɴᴏᴡ ʙᴜsʏ ᴡʜᴇɴ ғʀᴇᴇ ᴀᴅᴅ ᴛʜɪs " 59 | 60 | 61 | @Exoncmd(command="language") 62 | @user_admin 63 | def set_lang(update: Update, _) -> None: 64 | chat = update.effective_chat 65 | msg = update.effective_message 66 | 67 | msg_text = gs(chat.id, "curr_chat_lang").format( 68 | get_language(sql.get_chat_lang(chat.id))[:-3] 69 | ) 70 | 71 | keyb = [ 72 | InlineKeyboardButton( 73 | text=name, 74 | callback_data=f"setLang_{code}", 75 | ) 76 | for code, name in get_languages().items() 77 | ] 78 | keyb = list(paginate(keyb, 2)) 79 | keyb.append( 80 | [ 81 | InlineKeyboardButton( 82 | text="ʜᴇʟᴘ ᴜs ɪɴ ᴛʀᴀɴsʟᴀᴛɪᴏɴs", 83 | url="https://github.com/Abishnoi69/ExonRobot", # plz. Don't edit and change 84 | ) 85 | ] 86 | ) 87 | msg.reply_text(msg_text, reply_markup=InlineKeyboardMarkup(keyb)) 88 | 89 | 90 | @Exoncallback(pattern=r"setLang_") 91 | @user_admin_no_reply 92 | def lang_button(update: Update, _) -> None: 93 | query = update.callback_query 94 | chat = update.effective_chat 95 | 96 | query.answer() 97 | lang = query.data.split("_")[1] 98 | sql.set_lang(chat.id, lang) 99 | 100 | query.message.edit_text( 101 | gs(chat.id, "set_chat_lang").format(get_language(lang)[:-3]) 102 | ) 103 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/ABISHNOI COPYRIGHT ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" -------------------------------------------------------------------------------- /Exon/modules/no_sql/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | 31 | from motor.motor_asyncio import AsyncIOMotorClient as MongoCli 32 | from pymongo import MongoClient, collection 33 | 34 | from Exon import DB_NAME 35 | from Exon import MONGO_URI as MONGO_DB_URI 36 | 37 | mongo = MongoCli(MONGO_DB_URI) 38 | Asudb = mongo.ExonRobot_ 39 | 40 | try: 41 | client = MongoClient(MONGO_DB_URI) 42 | except PyMongoError: 43 | exiter(1) 44 | main_db = client[DB_NAME] 45 | 46 | AsuXdb = main_db 47 | 48 | 49 | def get_collection(name: str) -> collection: 50 | """ɢᴇᴛ ᴛʜᴇ ᴄᴏʟʟᴇᴄᴛɪᴏɴ ғʀᴏᴍ ᴅᴀᴛᴀʙᴀsᴇ.""" 51 | return AsuXdb[name] 52 | 53 | 54 | class MongoDB: 55 | """Class for interacting with Bot database.""" 56 | 57 | def __init__(self, collection) -> None: 58 | self.collection = AsuXdb[collection] 59 | 60 | # Insert one entry into collection 61 | def insert_one(self, document): 62 | result = self.collection.insert_one(document) 63 | return repr(result.inserted_id) 64 | 65 | # Find one entry from collection 66 | def find_one(self, query): 67 | return result if (result := self.collection.find_one(query)) else False 68 | 69 | # Find entries from collection 70 | def find_all(self, query=None): 71 | if query is None: 72 | query = {} 73 | return list(self.collection.find(query)) 74 | 75 | # Count entries from collection 76 | def count(self, query=None): 77 | if query is None: 78 | query = {} 79 | return self.collection.count_documents(query) 80 | 81 | # Delete entry/entries from collection 82 | def delete_one(self, query): 83 | self.collection.delete_many(query) 84 | return self.collection.count_documents({}) 85 | 86 | # Replace one entry in collection 87 | def replace(self, query, new_data): 88 | old = self.collection.find_one(query) 89 | _id = old["_id"] 90 | self.collection.replace_one({"_id": _id}, new_data) 91 | new = self.collection.find_one({"_id": _id}) 92 | return old, new 93 | 94 | # Update one entry from collection 95 | def update(self, query, update): 96 | result = self.collection.update_one(query, {"$set": update}) 97 | new_document = self.collection.find_one(query) 98 | return result.modified_count, new_document 99 | 100 | @staticmethod 101 | def close(): 102 | return client.close() 103 | 104 | 105 | def __connect_first(): 106 | _ = MongoDB("test") 107 | 108 | 109 | __connect_first() 110 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/afk_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | from Exon.modules.no_sql import Asudb 31 | 32 | afkdb = Asudb.afk 33 | 34 | 35 | async def is_afk(user_id: int) -> bool: 36 | user = await afkdb.find_one({"user_id": user_id}) 37 | return (True, user["reason"]) if user else (False, {}) 38 | 39 | 40 | async def add_afk(user_id: int, mode): 41 | await afkdb.update_one( 42 | {"user_id": user_id}, {"$set": {"reason": mode}}, upsert=True 43 | ) 44 | 45 | 46 | async def remove_afk(user_id: int): 47 | user = await afkdb.find_one({"user_id": user_id}) 48 | if user: 49 | return await afkdb.delete_one({"user_id": user_id}) 50 | 51 | 52 | async def get_afk_users() -> list: 53 | users = afkdb.find({"user_id": {"$gt": 0}}) 54 | return list(await users.to_list(length=1000000000)) if users else [] 55 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/blacklist_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | from Exon.modules.no_sql import get_collection 31 | 32 | BL = get_collection("BLACKLIST") 33 | BL_SETTING = get_collection("BLACKLIST_SETTINGS") 34 | 35 | CHAT_BLACKLISTS = {} 36 | CHAT_SETTINGS_BLACKLISTS = {} 37 | 38 | 39 | def add_to_blacklist(chat_id, trigger): 40 | BL.find_one_and_update( 41 | {"chat_id": chat_id, "trigger": trigger}, 42 | {"$set": {"chat_id": chat_id, "trigger": trigger}}, 43 | upsert=True, 44 | ) 45 | if CHAT_BLACKLISTS.get(str(chat_id), set()) == set(): 46 | CHAT_BLACKLISTS[str(chat_id)] = {trigger} 47 | else: 48 | CHAT_BLACKLISTS.get(str(chat_id), set()).add(trigger) 49 | 50 | 51 | def rm_from_blacklist(chat_id, trigger) -> bool: 52 | if data := BL.find_one_and_delete( 53 | {"chat_id": chat_id, "trigger": trigger} 54 | ): 55 | if trigger in CHAT_BLACKLISTS.get(str(chat_id), set()): 56 | CHAT_BLACKLISTS.get(str(chat_id), set()).remove(trigger) 57 | return True 58 | return False 59 | 60 | 61 | def get_chat_blacklist(chat_id) -> set: 62 | return CHAT_BLACKLISTS.get(str(chat_id), set()) 63 | 64 | 65 | def num_blacklist_filters() -> int: 66 | return BL.count_documents({}) 67 | 68 | 69 | def num_blacklist_chat_filters(chat_id) -> int: 70 | return BL.count_documents({"chat_id": chat_id}) 71 | 72 | 73 | def num_blacklist_filter_chats() -> int: 74 | data = BL.distinct("chat_id") 75 | return len(data) 76 | 77 | 78 | def set_blacklist_strength(chat_id, blacklist_type, value): 79 | """For blacklist type settings 80 | `blacklist_type` (int): 81 | - 0 = nothing 82 | - 1 = delete 83 | - 2 = warn 84 | - 3 = mute 85 | - 4 = kick 86 | - 5 = ban 87 | - 6 = tban 88 | - 7 = tmute. 89 | """ 90 | BL_SETTING.update_one( 91 | {"chat_id": chat_id}, 92 | {"$set": {"blacklist_type": int(blacklist_type), "value": str(value)}}, 93 | upsert=True, 94 | ) 95 | CHAT_SETTINGS_BLACKLISTS[str(chat_id)] = { 96 | "blacklist_type": int(blacklist_type), 97 | "value": value, 98 | } 99 | 100 | 101 | def get_blacklist_setting(chat_id) -> [int, str]: 102 | if setting := CHAT_SETTINGS_BLACKLISTS.get(str(chat_id)): 103 | return setting["blacklist_type"], setting["value"] 104 | return 1, "0" 105 | 106 | 107 | def __load_chat_blacklists(): 108 | for chat in BL.find(): 109 | CHAT_BLACKLISTS[chat["chat_id"]] = [] 110 | 111 | for x in BL.find(): 112 | CHAT_BLACKLISTS[x["chat_id"]] += [x["trigger"]] 113 | 114 | CHAT_BLACKLISTS = {str(x): set(y) for x, y in CHAT_BLACKLISTS.items()} 115 | 116 | 117 | def __load_chat_settings_blacklists(): 118 | for x in BL_SETTING.find(): 119 | CHAT_SETTINGS_BLACKLISTS[x["chat_id"]] = { 120 | "blacklist_type": x["blacklist_type"], 121 | "value": x["value"], 122 | } 123 | 124 | 125 | def migrate_chat(old_chat_id, new_chat_id): 126 | BL.update_many({"chat_id": old_chat_id}, {"$set": {"chat_id": new_chat_id}}) 127 | __load_chat_blacklists() 128 | __load_chat_settings_blacklists() 129 | 130 | 131 | __load_chat_blacklists() 132 | __load_chat_settings_blacklists() 133 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/disable_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | 31 | from Exon.modules.no_sql import get_collection 32 | 33 | DISABLED_COMMANDS = get_collection("DISABLED_COMMANDS") 34 | 35 | DISABLED = {} 36 | 37 | 38 | def disable_command(chat_id, disable) -> bool: 39 | data = DISABLED_COMMANDS.find_one({"chat_id": chat_id, "command": disable}) 40 | if not data: 41 | DISABLED.setdefault(str(chat_id), set()).add(disable) 42 | 43 | DISABLED_COMMANDS.insert_one({"chat_id": chat_id, "command": disable}) 44 | return True 45 | return False 46 | 47 | 48 | def enable_command(chat_id, enable) -> bool: 49 | if data := DISABLED_COMMANDS.find_one( 50 | {"chat_id": chat_id, "command": enable} 51 | ): 52 | if enable in DISABLED.get(str(chat_id)): # sanity check 53 | DISABLED.setdefault(str(chat_id), set()).remove(enable) 54 | 55 | DISABLED_COMMANDS.delete_one({"chat_id": chat_id, "command": enable}) 56 | return True 57 | return False 58 | 59 | 60 | def is_command_disabled(chat_id, cmd) -> bool: 61 | return cmd in DISABLED.get(str(chat_id), set()) 62 | 63 | 64 | def get_all_disabled(chat_id) -> dict: 65 | return DISABLED.get(str(chat_id), set()) 66 | 67 | 68 | def num_chats() -> int: 69 | chats = DISABLED_COMMANDS.distinct("chat_id") 70 | return len(chats) 71 | 72 | 73 | def num_disabled() -> int: 74 | return DISABLED_COMMANDS.count_documents({}) 75 | 76 | 77 | def migrate_chat(old_chat_id, new_chat_id) -> None: 78 | DISABLED_COMMANDS.update_many( 79 | {"chat_id": old_chat_id}, {"$set": {"chat_id": new_chat_id}} 80 | ) 81 | 82 | if str(old_chat_id) in DISABLED: 83 | DISABLED[str(old_chat_id)] = DISABLED.get(str(old_chat_id), set()) 84 | 85 | 86 | def __load_disabled_commands() -> None: 87 | all_chats = DISABLED_COMMANDS.find() 88 | for chat in all_chats: 89 | DISABLED.setdefault(chat["chat_id"], set()).add(chat["command"]) 90 | 91 | 92 | __load_disabled_commands() 93 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/fsub_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | from . import AsuXdb as db 31 | 32 | fsub = db.force_sub 33 | 34 | 35 | def fs_settings(chat_id: int): 36 | return _x if (_x := fsub.find_one({"chat_id": chat_id})) else None 37 | 38 | 39 | def add_channel(chat_id: int, channel): 40 | fsub.update_one({"chat_id": chat_id}, {"$set": {"channel": channel}}, upsert=True) 41 | 42 | 43 | def disapprove(chat_id: int): 44 | fsub.delete_one({"chat_id": chat_id}) 45 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/global_bans_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | """ɢʟᴏʙᴀʟ ʙᴀɴs ᴅᴀᴛᴀʙᴀsᴇ""" 31 | 32 | from Exon.modules.no_sql import get_collection 33 | 34 | GBAN_USER = get_collection("GBANS") 35 | GBAN_SETTINGS = get_collection("GBAN_SETTINGS") 36 | GBANNED_LIST = set() 37 | GBANSTAT_LIST = set() 38 | 39 | 40 | def gban_user(user_id, name, reason=None) -> None: 41 | GBAN_USER.insert_one( 42 | { 43 | "_id": user_id, 44 | "name": name, 45 | "reason": reason, 46 | } 47 | ) 48 | __load_gbanned_userid_list() 49 | 50 | 51 | def update_gban_reason(user_id, name, reason) -> str: 52 | data = GBAN_USER.find_one_and_update( 53 | {"_id": user_id}, {"$set": {"name": name, "reason": reason}}, upsert=False 54 | ) 55 | return data["reason"] 56 | 57 | 58 | def ungban_user(user_id) -> None: 59 | GBAN_USER.delete_one({"_id": user_id}) 60 | __load_gbanned_userid_list() 61 | 62 | 63 | def is_user_gbanned(user_id): 64 | return user_id in GBANNED_LIST 65 | 66 | 67 | def get_gbanned_user(user_id): 68 | return GBAN_USER.find_one({"_id": user_id}) 69 | 70 | 71 | def get_gban_list() -> dict: 72 | return list(GBAN_USER.find()) 73 | 74 | 75 | def enable_gbans(chat_id) -> None: 76 | __gban_setting(chat_id, True) 77 | if str(chat_id) in GBANSTAT_LIST: 78 | GBANSTAT_LIST.remove(str(chat_id)) 79 | 80 | 81 | def disable_gbans(chat_id) -> None: 82 | __gban_setting(chat_id, False) 83 | GBANSTAT_LIST.add(str(chat_id)) 84 | 85 | 86 | def __gban_setting(chat_id, setting: bool = True) -> None: 87 | if GBAN_SETTINGS.find_one({"_id": chat_id}): 88 | GBAN_SETTINGS.update_one({"_id": chat_id}, {"$set": {"setting": setting}}) 89 | else: 90 | GBAN_SETTINGS.insert_one({"_id": chat_id, "setting": setting}) 91 | 92 | 93 | def does_chat_gban(chat_id) -> bool: 94 | return str(chat_id) not in GBANSTAT_LIST 95 | 96 | 97 | def num_gbanned_users() -> int: 98 | return len(GBANNED_LIST) 99 | 100 | 101 | def __load_gbanned_userid_list() -> None: 102 | global GBANNED_LIST 103 | GBANNED_LIST = {i["_id"] for i in GBAN_USER.find()} 104 | 105 | 106 | def __load_gban_stat_list() -> None: 107 | global GBANSTAT_LIST 108 | GBANSTAT_LIST = {str(i["_id"]) for i in GBAN_SETTINGS.find() if not i["setting"]} 109 | 110 | 111 | def migrate_chat(old_chat_id, new_chat_id) -> None: 112 | if old := GBAN_SETTINGS.find_one_and_delete({"_id": old_chat_id}): 113 | setting = old["setting"] 114 | else: 115 | setting = True 116 | GBAN_SETTINGS.update_one( 117 | {"_id": new_chat_id}, 118 | {"$set": {"setting": setting}}, 119 | upsert=True, 120 | ) 121 | 122 | 123 | # Create in memory userid to avoid disk access 124 | __load_gbanned_userid_list() 125 | __load_gban_stat_list() 126 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/karma_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | 31 | from typing import Dict, Union 32 | 33 | from . import AsuXdb as db 34 | 35 | couplesdb = db.couple 36 | karmadb = db.karma 37 | 38 | 39 | async def _get_lovers(chat_id: int): 40 | lovers = couplesdb.find_one({"chat_id": chat_id}) 41 | lovers = lovers["couple"] if lovers else {} 42 | return lovers 43 | 44 | 45 | async def get_couple(chat_id: int, date: str): 46 | lovers = await _get_lovers(chat_id) 47 | return lovers[date] if date in lovers else False 48 | 49 | 50 | async def save_couple(chat_id: int, date: str, couple: dict): 51 | lovers = await _get_lovers(chat_id) 52 | lovers[date] = couple 53 | couplesdb.update_one( 54 | {"chat_id": chat_id}, {"$set": {"couple": lovers}}, upsert=True 55 | ) 56 | 57 | 58 | async def get_karmas_count() -> dict: 59 | chats = karmadb.find({"chat_id": {"$lt": 0}}) 60 | if not chats: 61 | return {} 62 | chats_count = 0 63 | karmas_count = 0 64 | for chat in await chats.to_list(length=1000000): 65 | for i in chat["karma"]: 66 | karma_ = chat["karma"][i]["karma"] 67 | if karma_ > 0: 68 | karmas_count += karma_ 69 | chats_count += 1 70 | return {"chats_count": chats_count, "karmas_count": karmas_count} 71 | 72 | 73 | async def user_global_karma(user_id) -> int: 74 | chats = karmadb.find({"chat_id": {"$lt": 0}}) 75 | if not chats: 76 | return 0 77 | total_karma = 0 78 | for chat in await chats.to_list(length=1000000): 79 | karma = await get_karma(chat["chat_id"], await int_to_alpha(user_id)) 80 | if karma and (int(karma["karma"]) > 0): 81 | total_karma += int(karma["karma"]) 82 | return total_karma 83 | 84 | 85 | async def get_karmas(chat_id: int) -> Dict[str, int]: 86 | karma = karmadb.find_one({"chat_id": chat_id}) 87 | return karma["karma"] if karma else {} 88 | 89 | 90 | async def get_karma(chat_id: int, name: str) -> Union[bool, dict]: 91 | name = name.lower().strip() 92 | karmas = await get_karmas(chat_id) 93 | if name in karmas: 94 | return karmas[name] 95 | 96 | 97 | async def update_karma(chat_id: int, name: str, karma: dict): 98 | name = name.lower().strip() 99 | karmas = await get_karmas(chat_id) 100 | karmas[name] = karma 101 | karmadb.update_one({"chat_id": chat_id}, {"$set": {"karma": karmas}}, upsert=True) 102 | 103 | 104 | async def is_karma_on(chat_id: int) -> bool: 105 | chat = karmadb.find_one({"chat_id_toggle": chat_id}) 106 | return not chat 107 | 108 | 109 | async def karma_on(chat_id: int): 110 | is_karma = await is_karma_on(chat_id) 111 | if is_karma: 112 | return 113 | return karmadb.delete_one({"chat_id_toggle": chat_id}) 114 | 115 | 116 | async def karma_off(chat_id: int): 117 | is_karma = await is_karma_on(chat_id) 118 | if not is_karma: 119 | return 120 | return karmadb.insert_one({"chat_id_toggle": chat_id}) 121 | 122 | 123 | async def int_to_alpha(user_id: int) -> str: 124 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] 125 | user_id = str(user_id) 126 | return "".join(alphabet[int(i)] for i in user_id) 127 | 128 | 129 | async def alpha_to_int(user_id_alphabet: str) -> int: 130 | alphabet = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"] 131 | user_id = "" 132 | for i in user_id_alphabet: 133 | index = alphabet.index(i) 134 | user_id += str(index) 135 | return int(user_id) 136 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/log_channel_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | from Exon.modules.no_sql import get_collection 31 | 32 | LOG_DATA = get_collection("log_channels") 33 | 34 | CHANNELS = {} 35 | 36 | 37 | def set_chat_log_channel(chat_id, log_channel): 38 | LOG_DATA.update_one( 39 | {"chat_id": chat_id}, {"$set": {"log_channel": log_channel}}, upsert=True 40 | ) 41 | CHANNELS[str(chat_id)] = log_channel 42 | 43 | 44 | def get_chat_log_channel(chat_id) -> int: 45 | return CHANNELS.get(str(chat_id)) 46 | 47 | 48 | def stop_chat_logging(chat_id) -> int: 49 | res = LOG_DATA.find_one_and_delete({"chat_id": chat_id}) 50 | if str(chat_id) in CHANNELS: 51 | del CHANNELS[str(chat_id)] 52 | return res["log_channel"] 53 | 54 | 55 | def num_logchannels() -> int: 56 | return LOG_DATA.count_documents({}) 57 | 58 | 59 | def migrate_chat(old_chat_id, new_chat_id): 60 | LOG_DATA.update_one({"chat_id": old_chat_id}, {"$set": {"chat_id": new_chat_id}}) 61 | if str(old_chat_id) in CHANNELS: 62 | CHANNELS[str(new_chat_id)] = CHANNELS.get(str(old_chat_id)) 63 | 64 | 65 | def __load_log_channels(): 66 | global CHANNELS 67 | CHANNELS = { 68 | str(chat["chat_id"]): str(chat["log_channel"]) for chat in LOG_DATA.find() 69 | } 70 | 71 | 72 | __load_log_channels() 73 | -------------------------------------------------------------------------------- /Exon/modules/no_sql/users_db.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # TG :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | """Users Database.""" 31 | 32 | from Exon import dispatcher 33 | from Exon.modules.no_sql import get_collection 34 | 35 | USERS_DB = get_collection("users") 36 | CHATS_DB = get_collection("chats") 37 | CHAT_MEMBERS_DB = get_collection("chat_mamber") 38 | 39 | 40 | def ensure_bot_in_db(): 41 | USERS_DB.update_one( 42 | {"_id": dispatcher.bot.id}, 43 | {"$set": {"username": dispatcher.bot.username}}, 44 | upsert=True, 45 | ) 46 | 47 | 48 | def update_user(user_id, username, chat_id=None, chat_name=None): 49 | USERS_DB.update_one({"_id": user_id}, {"$set": {"username": username}}, upsert=True) 50 | 51 | if not (chat_id or chat_name): 52 | return 53 | 54 | CHATS_DB.update_one( 55 | {"chat_id": chat_id}, {"$set": {"chat_name": chat_name}}, upsert=True 56 | ) 57 | 58 | member = CHAT_MEMBERS_DB.find_one({"chat_id": chat_id, "user_id": user_id}) 59 | if member is None: 60 | CHAT_MEMBERS_DB.insert_one({"chat_id": chat_id, "user_id": user_id}) 61 | 62 | 63 | def get_userid_by_name(username) -> dict: 64 | return list(USERS_DB.find({"username": username})) 65 | 66 | 67 | def get_name_by_userid(user_id) -> dict: 68 | return list(USERS_DB.find_one({"_id": user_id})) 69 | 70 | 71 | def get_chat_members(chat_id) -> list: 72 | return list(CHAT_MEMBERS_DB.find({"chat_id": chat_id})) 73 | 74 | 75 | def get_all_chats() -> list: 76 | return list(CHATS_DB.find()) 77 | 78 | 79 | def get_all_users() -> list: 80 | return list(USERS_DB.find()) 81 | 82 | 83 | def get_user_num_chats(user_id) -> int: 84 | return CHAT_MEMBERS_DB.count_documents({"user_id": user_id}) 85 | 86 | 87 | def get_user_com_chats(user_id) -> int: 88 | return list(CHAT_MEMBERS_DB.find({"user_id": user_id})) 89 | 90 | 91 | def num_chats() -> int: 92 | return CHATS_DB.count_documents({}) 93 | 94 | 95 | def num_chat_users() -> int: 96 | return CHAT_MEMBERS_DB.count_documents({}) 97 | 98 | 99 | def num_users() -> int: 100 | return USERS_DB.count_documents({}) 101 | 102 | 103 | def rem_chat(chat_id) -> None: 104 | CHATS_DB.delete_one({"chat_id": chat_id}) 105 | 106 | 107 | def migrate_chat(old_chat_id, new_chat_id) -> None: 108 | CHATS_DB.update_one({"chat_id": old_chat_id}, {"$set": {"chat_id": new_chat_id}}) 109 | 110 | chat_members = CHAT_MEMBERS_DB.find({"chat_id": old_chat_id}) 111 | for member in chat_members: 112 | CHAT_MEMBERS_DB.update_one( 113 | {"chat_id": member["chat_id"]}, {"$set": {"chat_id": new_chat_id}} 114 | ) 115 | 116 | 117 | ensure_bot_in_db() 118 | -------------------------------------------------------------------------------- /Exon/modules/purge.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | 31 | from pyrogram.enums import ChatType 32 | from pyrogram.errors import MessageDeleteForbidden, RPCError 33 | from pyrogram.types import Message 34 | 35 | from Exon import LOGGER, Abishnoi 36 | 37 | 38 | @Abishnoi.on_cmd("purge") 39 | @Abishnoi.adminsOnly(permissions="can_delete_messages", is_both=True) 40 | async def purge(c: Abishnoi, m: Message): 41 | if m.chat.type != ChatType.SUPERGROUP: 42 | await m.reply_text(text="ᴄᴀɴɴᴏᴛ ᴘᴜʀɢᴇ ᴍᴇssᴀɢᴇs ɪɴ ᴀ ʙᴀsɪᴄ ɢʀᴏᴜᴘ") 43 | return 44 | 45 | if m.reply_to_message: 46 | message_ids = list(range(m.reply_to_message.id, m.id)) 47 | 48 | def divide_chunks(l: list, n: int = 100): 49 | for i in range(0, len(l), n): 50 | yield l[i: i + n] 51 | 52 | # Dielete messages in chunks of 100 messages 53 | m_list = list(divide_chunks(message_ids)) 54 | 55 | try: 56 | for plist in m_list: 57 | await c.delete_messages( 58 | chat_id=m.chat.id, 59 | message_ids=plist, 60 | revoke=True, 61 | ) 62 | await m.delete() 63 | except MessageDeleteForbidden: 64 | await m.reply_text( 65 | text="ᴄᴀɴɴᴏᴛ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ᴍᴇssᴀɢᴇs. ᴛʜᴇ ᴍᴇssᴀɢᴇs ᴍᴀʏ ʙᴇ ᴛᴏᴏ ᴏʟᴅ, I ᴍɪɢʜᴛ ɴᴏᴛ ʜᴀᴠᴇ ᴅᴇʟᴇᴛᴇ ʀɪɢʜᴛs, ᴏʀ ᴛʜɪs ᴍɪɢʜᴛ ɴᴏᴛ ʙᴇ ᴀ sᴜᴘᴇʀɢʀᴏᴜᴘ." 66 | ) 67 | return 68 | except RPCError as ef: 69 | LOGGER.info(f"ERROR on purge {ef}") 70 | 71 | count_del_msg = len(message_ids) 72 | 73 | z = await m.reply_text(text=f"ᴅᴇʟᴇᴛᴇᴅ {count_del_msg} messages") 74 | return 75 | await m.reply_text("ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ sᴛᴀʀᴛ ᴘᴜʀɢᴇ !") 76 | return 77 | 78 | 79 | @Abishnoi.on_cmd("spurge") 80 | @Abishnoi.adminsOnly(permissions="can_delete_messages", is_both=True) 81 | async def spurge(c: Abishnoi, m: Message): 82 | if m.chat.type != ChatType.SUPERGROUP: 83 | await m.reply_text(text="ᴄᴀɴɴᴏᴛ ᴘᴜʀɢᴇ ᴍᴇssᴀɢᴇs ɪɴ ᴀ ʙᴀsɪᴄ ɢʀᴏᴜᴘ") 84 | return 85 | 86 | if m.reply_to_message: 87 | message_ids = list(range(m.reply_to_message.id, m.id)) 88 | 89 | def divide_chunks(l: list, n: int = 100): 90 | for i in range(0, len(l), n): 91 | yield l[i: i + n] 92 | 93 | # Dielete messages in chunks of 100 messages 94 | m_list = list(divide_chunks(message_ids)) 95 | 96 | try: 97 | for plist in m_list: 98 | await c.delete_messages( 99 | chat_id=m.chat.id, 100 | message_ids=plist, 101 | revoke=True, 102 | ) 103 | await m.delete() 104 | except MessageDeleteForbidden: 105 | await m.reply_text( 106 | text="ᴄᴀɴɴᴏᴛ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ᴍᴇssᴀɢᴇs. ᴛʜᴇ ᴍᴇssᴀɢᴇs ᴍᴀʏ ʙᴇ ᴛᴏᴏ ᴏʟᴅ, I ᴍɪɢʜᴛ ɴᴏᴛ ʜᴀᴠᴇ ᴅᴇʟᴇᴛᴇ ʀɪɢʜᴛs, ᴏʀ ᴛʜɪs ᴍɪɢʜᴛ ɴᴏᴛ ʙᴇ ᴀ sᴜᴘᴇʀɢʀᴏᴜᴘ." 107 | ) 108 | return 109 | except RPCError as ef: 110 | LOGGER.info(f"ERROR on purge {ef}") 111 | return 112 | await m.reply_text("ʀᴇᴘʟʏ ᴛᴏ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ sᴛᴀʀᴛ sᴘᴜʀɢᴇ !") 113 | return 114 | 115 | 116 | @Abishnoi.on_cmd("del") 117 | @Abishnoi.adminsOnly(permissions="can_delete_messages", is_both=True) 118 | async def del_msg(c: Abishnoi, m: Message): 119 | if m.reply_to_message: 120 | await m.delete() 121 | await c.delete_messages( 122 | chat_id=m.chat.id, 123 | message_ids=m.reply_to_message.id, 124 | ) 125 | else: 126 | await m.reply_text(text="ᴡʜᴀᴛ ᴅᴏ ʏᴏᴜ ᴡᴀɴɴᴀ ᴅᴇʟᴇᴛᴇ?") 127 | return 128 | 129 | 130 | __PLUGIN__ = "Pᴜʀɢᴇ" 131 | 132 | __alt_name__ = ["purge", "del", "spurge"] 133 | 134 | __HELP__ = """ 135 | • /purge: ᴅᴇʟᴇᴛᴇs ᴍᴇssᴀɢᴇs ᴜᴘᴛᴏ ʀᴇᴘʟɪᴇᴅ ᴍᴇssᴀɢᴇ. 136 | • /spurge: ᴅᴇʟᴇᴛᴇs ᴍᴇssᴀɢᴇs ᴜᴘᴛᴏ ʀᴇᴘʟɪᴇᴅ ᴍᴇssᴀɢᴇ ᴡɪᴛʜᴏᴜᴛ ᴀ sᴜᴄᴄᴇss ᴍᴇssᴀɢᴇ. 137 | • /del: ᴅᴇʟᴇᴛᴇs ᴀ sɪɴɢʟᴇ ᴍᴇssᴀɢᴇ, ᴜsᴇᴅ ᴀs ᴀ ʀᴇᴘʟʏ ᴛᴏ ᴍᴇssᴀɢᴇ. 138 | """ 139 | 140 | __mod_name__ = "𝐏ᴜʀɢᴇ" 141 | 142 | # ғᴏʀ ʜᴇʟᴘ ᴍᴇɴᴜ 143 | 144 | 145 | # """ 146 | from Exon.modules.language import gs 147 | 148 | 149 | def get_help(chat): 150 | return gs(chat, "purge_help") 151 | 152 | # """ 153 | -------------------------------------------------------------------------------- /Exon/modules/repo.py: -------------------------------------------------------------------------------- 1 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 2 | # TG :- @AshokShau 3 | # MY ALL BOTS :- Abishnoi_bots 4 | # GITHUB :- KingAbishnoi "" 5 | 6 | from platform import python_version as y 7 | 8 | from pyrogram import __version__ as z 9 | from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup 10 | from telegram import __version__ as o 11 | from telethon import __version__ as s 12 | 13 | from Exon import Abishnoi as pbot 14 | 15 | ABISHNOIX = "https://te.legra.ph/file/abfc49a1cc4b5629dc8cd.jpg" 16 | 17 | 18 | @pbot.on_cmd("repo") 19 | async def repo(_, message): 20 | await message.reply_photo( 21 | photo=ABISHNOIX, 22 | caption=f"""✨ **ʜᴇʏ {message.from_user.mention},** 23 | 24 | **ᴏᴡɴᴇʀ : [𝐀ʙɪꜱʜɴᴏɪ](https://t.me/AshokShau)** 25 | **ᴘʏᴛʜᴏɴ ᴠᴇʀꜱɪᴏɴ :** `{y()}` 26 | **ʟɪʙʀᴀʀʏ ᴠᴇʀꜱɪᴏɴ :** `{o}` 27 | **ᴛᴇʟᴇᴛʜᴏɴ ᴠᴇʀꜱɪᴏɴ :** `{s}` 28 | **ᴘʏʀᴏɢʀᴀᴍ ᴠᴇʀꜱɪᴏɴ :** `{z}` 29 | """, 30 | reply_markup=InlineKeyboardMarkup( 31 | [ 32 | [ 33 | InlineKeyboardButton( 34 | "•ᴍᴜꜱɪᴄ•", url="https://github.com/AshokShau/AsuXMusic" 35 | ), 36 | InlineKeyboardButton( 37 | "•ʀᴏʙᴏᴠ1•", url="https://github.com/AshokShau/ExonRobot" 38 | ), 39 | ] 40 | ] 41 | ), 42 | ) 43 | -------------------------------------------------------------------------------- /Exon/modules/resources/asu.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AshokShau/ExonRobot/58860d12ffd832714f79a4f9ae5b2055ddc93f3c/Exon/modules/resources/asu.ttf -------------------------------------------------------------------------------- /Exon/modules/shell.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | import subprocess 31 | 32 | from telegram import ParseMode, Update 33 | from telegram.ext import CallbackContext, CommandHandler 34 | 35 | from Exon import LOGGER, dispatcher 36 | from Exon.modules.helper_funcs.chat_status import dev_plus 37 | 38 | 39 | @dev_plus 40 | def shell(update: Update, context: CallbackContext): 41 | message = update.effective_message 42 | cmd = message.text.split(" ", 1) 43 | if len(cmd) == 1: 44 | message.reply_text("ɴᴏ ᴄᴏᴍᴍᴀɴᴅ ᴛᴏ ᴇxᴄᴜᴛᴇ ᴡᴀꜱ ɢɪᴠᴇɴ ʙᴀʙʏ.") 45 | return 46 | cmd = cmd[1] 47 | process = subprocess.Popen( 48 | cmd, 49 | stdout=subprocess.PIPE, 50 | stderr=subprocess.PIPE, 51 | shell=True, 52 | ) 53 | stdout, stderr = process.communicate() 54 | reply = "" 55 | stderr = stderr.decode() 56 | if stdout := stdout.decode(): 57 | reply += f"*ꜱᴛᴅᴏᴜᴛ*\n`{stdout}`\n" 58 | LOGGER.info(f"Shell - {cmd} - {stdout}") 59 | if stderr: 60 | reply += f"*Stderr*\n`{stderr}`\n" 61 | LOGGER.error(f"Shell - {cmd} - {stderr}") 62 | if len(reply) > 3000: 63 | with open("shell_output.txt", "w") as file: 64 | file.write(reply) 65 | with open("shell_output.txt", "rb") as doc: 66 | context.bot.send_document( 67 | document=doc, 68 | filename=doc.name, 69 | reply_to_message_id=message.message_id, 70 | chat_id=message.chat_id, 71 | ) 72 | else: 73 | message.reply_text(reply, parse_mode=ParseMode.MARKDOWN) 74 | 75 | 76 | SHELL_HANDLER = CommandHandler(["sh"], shell, run_async=True) 77 | dispatcher.add_handler(SHELL_HANDLER) 78 | __mod_name__ = "Shell" 79 | __command_list__ = ["sh"] 80 | __handlers__ = [SHELL_HANDLER] 81 | -------------------------------------------------------------------------------- /Exon/modules/sql/ABISHNOI COPYRIGHT ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi 27 | # MY ALL BOTS :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" -------------------------------------------------------------------------------- /Exon/modules/sql/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | from sqlalchemy import create_engine 31 | from sqlalchemy.ext.declarative import declarative_base 32 | from sqlalchemy.orm import scoped_session, sessionmaker 33 | 34 | from Exon import DB_URL as DB_URI 35 | from Exon import LOGGER as log 36 | 37 | if DB_URI and DB_URI.startswith("postgres://"): 38 | DB_URI = DB_URI.replace("postgres://", "postgresql://", 1) 39 | 40 | 41 | def start() -> scoped_session: 42 | engine = create_engine(DB_URI, client_encoding="utf8") 43 | log.info("[PostgreSQL] Connecting to database......") 44 | BASE.metadata.bind = engine 45 | BASE.metadata.create_all(engine) 46 | return scoped_session(sessionmaker(bind=engine, autoflush=False)) 47 | 48 | 49 | BASE = declarative_base() 50 | try: 51 | SESSION: scoped_session = start() 52 | except Exception as e: 53 | log.exception(f"[PostgreSQL] Failed to connect due to {e}") 54 | exit() 55 | 56 | log.info("[PostgreSQL] Connection successful, session started.") 57 | -------------------------------------------------------------------------------- /Exon/modules/sql/acm_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | 31 | import threading 32 | 33 | from sqlalchemy import Boolean, Column, String 34 | 35 | from Exon.modules.sql import BASE, SESSION 36 | 37 | 38 | class CleanLinked(BASE): 39 | __tablename__ = "clean_linked" 40 | chat_id = Column(String(14), primary_key=True) 41 | status = Column(Boolean, default=False) 42 | 43 | def __init__(self, chat_id, status): 44 | self.chat_id = str(chat_id) 45 | self.status = status 46 | 47 | 48 | CleanLinked.__table__.create(checkfirst=True) 49 | 50 | CLEANLINKED_LOCK = threading.RLock() 51 | 52 | 53 | def getCleanLinked(chat_id): 54 | try: 55 | if resultObj := SESSION.query(CleanLinked).get(str(chat_id)): 56 | return resultObj.status 57 | return False # default 58 | finally: 59 | SESSION.close() 60 | 61 | 62 | def setCleanLinked(chat_id, status): 63 | with CLEANLINKED_LOCK: 64 | if prevObj := SESSION.query(CleanLinked).get(str(chat_id)): 65 | SESSION.delete(prevObj) 66 | newObj = CleanLinked(str(chat_id), status) 67 | SESSION.add(newObj) 68 | SESSION.commit() 69 | -------------------------------------------------------------------------------- /Exon/modules/sql/antiflood_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | 31 | import threading 32 | 33 | from sqlalchemy import Column, Integer, String, UnicodeText 34 | from sqlalchemy.sql.sqltypes import BigInteger 35 | 36 | from Exon.modules.sql import BASE, SESSION 37 | 38 | DEF_COUNT = 1 39 | DEF_LIMIT = 0 40 | DEF_OBJ = (None, DEF_COUNT, DEF_LIMIT) 41 | 42 | 43 | class FloodControl(BASE): 44 | __tablename__ = "antiflood" 45 | chat_id = Column(String(14), primary_key=True) 46 | user_id = Column(BigInteger) 47 | count = Column(Integer, default=DEF_COUNT) 48 | limit = Column(Integer, default=DEF_LIMIT) 49 | 50 | def __init__(self, chat_id): 51 | self.chat_id = str(chat_id) # ensure string 52 | 53 | def __repr__(self): 54 | return f"" 55 | 56 | 57 | class FloodSettings(BASE): 58 | __tablename__ = "antiflood_settings" 59 | chat_id = Column(String(14), primary_key=True) 60 | flood_type = Column(Integer, default=1) 61 | value = Column(UnicodeText, default="0") 62 | 63 | def __init__(self, chat_id, flood_type=1, value="0"): 64 | self.chat_id = str(chat_id) 65 | self.flood_type = flood_type 66 | self.value = value 67 | 68 | def __repr__(self): 69 | return f"<{self.chat_id} will executing {self.flood_type} for flood.>" 70 | 71 | 72 | FloodControl.__table__.create(checkfirst=True) 73 | FloodSettings.__table__.create(checkfirst=True) 74 | 75 | INSERTION_FLOOD_LOCK = threading.RLock() 76 | INSERTION_FLOOD_SETTINGS_LOCK = threading.RLock() 77 | 78 | CHAT_FLOOD = {} 79 | 80 | 81 | def set_flood(chat_id, amount): 82 | with INSERTION_FLOOD_LOCK: 83 | flood = SESSION.query(FloodControl).get(str(chat_id)) or FloodControl(str(chat_id)) 84 | 85 | flood.user_id = None 86 | flood.limit = amount 87 | 88 | CHAT_FLOOD[str(chat_id)] = (None, DEF_COUNT, amount) 89 | 90 | SESSION.add(flood) 91 | SESSION.commit() 92 | 93 | 94 | def update_flood(chat_id: str, user_id) -> bool: 95 | if chat_id not in CHAT_FLOOD: 96 | return 97 | 98 | curr_user_id, count, limit = CHAT_FLOOD.get(chat_id, DEF_OBJ) 99 | 100 | if limit == 0: # no antiflood 101 | return False 102 | 103 | if user_id != curr_user_id or user_id is None: # other user 104 | CHAT_FLOOD[chat_id] = (user_id, DEF_COUNT, limit) 105 | return False 106 | 107 | count += 1 108 | if count > limit: # too many msgs, kick 109 | CHAT_FLOOD[chat_id] = (None, DEF_COUNT, limit) 110 | return True 111 | 112 | # default -> update 113 | CHAT_FLOOD[chat_id] = (user_id, count, limit) 114 | return False 115 | 116 | 117 | def get_flood_limit(chat_id): 118 | return CHAT_FLOOD.get(str(chat_id), DEF_OBJ)[2] 119 | 120 | 121 | def set_flood_strength(chat_id, flood_type, value): 122 | # for flood_type 123 | # 1 = ban 124 | # 2 = kick 125 | # 3 = mute 126 | # 4 = tban 127 | # 5 = tmute 128 | with INSERTION_FLOOD_SETTINGS_LOCK: 129 | curr_setting = SESSION.query(FloodSettings).get(str(chat_id)) or FloodSettings( 130 | chat_id, 131 | flood_type=int(flood_type), 132 | value=value, 133 | ) 134 | 135 | curr_setting.flood_type = int(flood_type) 136 | curr_setting.value = str(value) 137 | 138 | SESSION.add(curr_setting) 139 | SESSION.commit() 140 | 141 | 142 | def get_flood_setting(chat_id): 143 | try: 144 | if setting := SESSION.query(FloodSettings).get(str(chat_id)): 145 | return setting.flood_type, setting.value 146 | return 1, "0" 147 | 148 | finally: 149 | SESSION.close() 150 | 151 | 152 | def migrate_chat(old_chat_id, new_chat_id): 153 | with INSERTION_FLOOD_LOCK: 154 | if flood := SESSION.query(FloodControl).get(str(old_chat_id)): 155 | CHAT_FLOOD[str(new_chat_id)] = CHAT_FLOOD.get(str(old_chat_id), DEF_OBJ) 156 | flood.chat_id = str(new_chat_id) 157 | SESSION.commit() 158 | 159 | SESSION.close() 160 | 161 | 162 | def __load_flood_settings(): 163 | global CHAT_FLOOD 164 | try: 165 | all_chats = SESSION.query(FloodControl).all() 166 | CHAT_FLOOD = {chat.chat_id: (None, DEF_COUNT, chat.limit) for chat in all_chats} 167 | finally: 168 | SESSION.close() 169 | 170 | 171 | __load_flood_settings() 172 | -------------------------------------------------------------------------------- /Exon/modules/sql/antilinkedchannel_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import threading 31 | 32 | from sqlalchemy import Boolean, Column 33 | from sqlalchemy.sql.sqltypes import String 34 | 35 | from Exon.modules.sql import BASE, SESSION 36 | 37 | 38 | class AntiLinkedChannelSettings(BASE): 39 | __tablename__ = "anti_linked_channel_settings" 40 | 41 | chat_id = Column(String(14), primary_key=True) 42 | setting = Column(Boolean, default=False, nullable=False) 43 | 44 | def __init__(self, chat_id: int, disabled: bool): 45 | self.chat_id = str(chat_id) 46 | self.setting = disabled 47 | 48 | def __repr__(self): 49 | return f"" 50 | 51 | 52 | class AntiPinChannelSettings(BASE): 53 | __tablename__ = "anti_pin_channel_settings" 54 | 55 | chat_id = Column(String(14), primary_key=True) 56 | setting = Column(Boolean, default=False, nullable=False) 57 | 58 | def __init__(self, chat_id: int, disabled: bool): 59 | self.chat_id = str(chat_id) 60 | self.setting = disabled 61 | 62 | def __repr__(self): 63 | return f"" 64 | 65 | 66 | AntiLinkedChannelSettings.__table__.create(checkfirst=True) 67 | ANTI_LINKED_CHANNEL_SETTING_LOCK = threading.RLock() 68 | 69 | AntiPinChannelSettings.__table__.create(checkfirst=True) 70 | ANTI_PIN_CHANNEL_SETTING_LOCK = threading.RLock() 71 | 72 | 73 | def enable(chat_id: int): 74 | with ANTI_LINKED_CHANNEL_SETTING_LOCK: 75 | chat = SESSION.query(AntiLinkedChannelSettings).get(str(chat_id)) or AntiLinkedChannelSettings(chat_id, True) 76 | 77 | chat.setting = True 78 | SESSION.add(chat) 79 | SESSION.commit() 80 | 81 | 82 | def enable_pin(chat_id: int): 83 | with ANTI_PIN_CHANNEL_SETTING_LOCK: 84 | chat = SESSION.query(AntiPinChannelSettings).get(str(chat_id)) or AntiPinChannelSettings(chat_id, True) 85 | 86 | chat.setting = True 87 | SESSION.add(chat) 88 | SESSION.commit() 89 | 90 | 91 | def disable_linked(chat_id: int): 92 | with ANTI_LINKED_CHANNEL_SETTING_LOCK: 93 | chat = SESSION.query(AntiLinkedChannelSettings).get(str(chat_id)) or AntiLinkedChannelSettings(chat_id, False) 94 | 95 | chat.setting = False 96 | SESSION.add(chat) 97 | SESSION.commit() 98 | 99 | 100 | def disable_pin(chat_id: int): 101 | with ANTI_PIN_CHANNEL_SETTING_LOCK: 102 | chat = SESSION.query(AntiPinChannelSettings).get(str(chat_id)) or AntiPinChannelSettings(chat_id, False) 103 | 104 | chat.setting = False 105 | SESSION.add(chat) 106 | SESSION.commit() 107 | 108 | 109 | def status_linked(chat_id: int) -> bool: 110 | with ANTI_LINKED_CHANNEL_SETTING_LOCK: 111 | d = SESSION.query(AntiLinkedChannelSettings).get(str(chat_id)) 112 | return d.setting if d else False 113 | 114 | 115 | def status_pin(chat_id: int) -> bool: 116 | with ANTI_PIN_CHANNEL_SETTING_LOCK: 117 | d = SESSION.query(AntiPinChannelSettings).get(str(chat_id)) 118 | return d.setting if d else False 119 | 120 | 121 | def migrate_chat(old_chat_id, new_chat_id): 122 | with ANTI_LINKED_CHANNEL_SETTING_LOCK: 123 | if chat := SESSION.query(AntiLinkedChannelSettings).get( 124 | str(old_chat_id) 125 | ): 126 | chat.chat_id = new_chat_id 127 | SESSION.add(chat) 128 | 129 | SESSION.commit() 130 | with ANTI_PIN_CHANNEL_SETTING_LOCK: 131 | if chat := SESSION.query(AntiPinChannelSettings).get(str(old_chat_id)): 132 | chat.chat_id = new_chat_id 133 | SESSION.add(chat) 134 | 135 | SESSION.commit() 136 | -------------------------------------------------------------------------------- /Exon/modules/sql/approve_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @Abishnoi1m 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import threading 30 | 31 | from sqlalchemy import Column, String 32 | from sqlalchemy.sql.sqltypes import BigInteger 33 | 34 | from Exon.modules.sql import BASE, SESSION 35 | 36 | 37 | class Approvals(BASE): 38 | __tablename__ = "approval" 39 | chat_id = Column(String(14), primary_key=True) 40 | user_id = Column(BigInteger, primary_key=True) 41 | 42 | def __init__(self, chat_id, user_id): 43 | self.chat_id = str(chat_id) # ensure string 44 | self.user_id = user_id 45 | 46 | def __repr__(self): 47 | return f"" 48 | 49 | 50 | Approvals.__table__.create(checkfirst=True) 51 | 52 | APPROVE_INSERTION_LOCK = threading.RLock() 53 | 54 | 55 | def approve(chat_id, user_id): 56 | with APPROVE_INSERTION_LOCK: 57 | approve_user = Approvals(str(chat_id), user_id) 58 | SESSION.add(approve_user) 59 | SESSION.commit() 60 | 61 | 62 | def is_approved(chat_id, user_id): 63 | try: 64 | return SESSION.query(Approvals).get((str(chat_id), user_id)) 65 | finally: 66 | SESSION.close() 67 | 68 | 69 | def disapprove(chat_id, user_id): 70 | with APPROVE_INSERTION_LOCK: 71 | if disapprove_user := SESSION.query(Approvals).get( 72 | (str(chat_id), user_id) 73 | ): 74 | SESSION.delete(disapprove_user) 75 | SESSION.commit() 76 | return True 77 | SESSION.close() 78 | return False 79 | 80 | 81 | def list_approved(chat_id): 82 | try: 83 | return ( 84 | SESSION.query(Approvals) 85 | .filter(Approvals.chat_id == str(chat_id)) 86 | .order_by(Approvals.user_id.asc()) 87 | .all() 88 | ) 89 | finally: 90 | SESSION.close() 91 | -------------------------------------------------------------------------------- /Exon/modules/sql/blacklistusers_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import threading 30 | 31 | from sqlalchemy import Column, String, UnicodeText 32 | 33 | from Exon.modules.sql import BASE, SESSION 34 | 35 | 36 | class BlacklistUsers(BASE): 37 | __tablename__ = "blacklistusers" 38 | user_id = Column(String(14), primary_key=True) 39 | reason = Column(UnicodeText) 40 | 41 | def __init__(self, user_id, reason=None): 42 | self.user_id = user_id 43 | self.reason = reason 44 | 45 | 46 | BlacklistUsers.__table__.create(checkfirst=True) 47 | 48 | BLACKLIST_LOCK = threading.RLock() 49 | BLACKLIST_USERS = set() 50 | 51 | 52 | def blacklist_user(user_id, reason=None): 53 | with BLACKLIST_LOCK: 54 | user = SESSION.query(BlacklistUsers).get(str(user_id)) 55 | if not user: 56 | user = BlacklistUsers(str(user_id), reason) 57 | else: 58 | user.reason = reason 59 | 60 | SESSION.add(user) 61 | SESSION.commit() 62 | __load_blacklist_userid_list() 63 | 64 | 65 | def unblacklist_user(user_id): 66 | with BLACKLIST_LOCK: 67 | if user := SESSION.query(BlacklistUsers).get(str(user_id)): 68 | SESSION.delete(user) 69 | 70 | SESSION.commit() 71 | __load_blacklist_userid_list() 72 | 73 | 74 | def get_reason(user_id): 75 | user = SESSION.query(BlacklistUsers).get(str(user_id)) 76 | rep = user.reason if user else "" 77 | SESSION.close() 78 | return rep 79 | 80 | 81 | def is_user_blacklisted(user_id): 82 | return user_id in BLACKLIST_USERS 83 | 84 | 85 | def __load_blacklist_userid_list(): 86 | global BLACKLIST_USERS 87 | try: 88 | BLACKLIST_USERS = {int(x.user_id) for x in SESSION.query(BlacklistUsers).all()} 89 | finally: 90 | SESSION.close() 91 | 92 | 93 | __load_blacklist_userid_list() 94 | -------------------------------------------------------------------------------- /Exon/modules/sql/clear_cmd_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import threading 31 | 32 | from sqlalchemy import Column, Integer, String, UnicodeText 33 | 34 | from Exon.modules.sql import BASE, SESSION 35 | 36 | 37 | class ClearCmd(BASE): 38 | __tablename__ = "clear_cmd" 39 | chat_id = Column(String(14), primary_key=True) 40 | cmd = Column(UnicodeText, primary_key=True, nullable=False) 41 | time = Column(Integer) 42 | 43 | def __init__(self, chat_id, cmd, time): 44 | self.chat_id = chat_id 45 | self.cmd = cmd 46 | self.time = time 47 | 48 | 49 | ClearCmd.__table__.create(checkfirst=True) 50 | 51 | CLEAR_CMD_LOCK = threading.RLock() 52 | 53 | 54 | def get_allclearcmd(chat_id): 55 | try: 56 | return SESSION.query(ClearCmd).filter(ClearCmd.chat_id == str(chat_id)).all() 57 | finally: 58 | SESSION.close() 59 | 60 | 61 | def get_clearcmd(chat_id, cmd): 62 | try: 63 | if clear_cmd := SESSION.query(ClearCmd).get((str(chat_id), cmd)): 64 | return clear_cmd 65 | return False 66 | finally: 67 | SESSION.close() 68 | 69 | 70 | def set_clearcmd(chat_id, cmd, time): 71 | with CLEAR_CMD_LOCK: 72 | clear_cmd = SESSION.query(ClearCmd).get((str(chat_id), cmd)) or ClearCmd(str(chat_id), cmd, time) 73 | 74 | clear_cmd.time = time 75 | SESSION.add(clear_cmd) 76 | SESSION.commit() 77 | 78 | 79 | def del_clearcmd(chat_id, cmd): 80 | with CLEAR_CMD_LOCK: 81 | if del_cmd := SESSION.query(ClearCmd).get((str(chat_id), cmd)): 82 | SESSION.delete(del_cmd) 83 | SESSION.commit() 84 | return True 85 | else: 86 | SESSION.close() 87 | return False 88 | 89 | 90 | def del_allclearcmd(chat_id): 91 | with CLEAR_CMD_LOCK: 92 | if ( 93 | del_cmd := SESSION.query(ClearCmd) 94 | .filter(ClearCmd.chat_id == str(chat_id)) 95 | .all() 96 | ): 97 | for cmd in del_cmd: 98 | SESSION.delete(cmd) 99 | SESSION.commit() 100 | return True 101 | else: 102 | SESSION.close() 103 | return False 104 | 105 | 106 | def migrate_chat(old_chat_id, new_chat_id): 107 | with CLEAR_CMD_LOCK: 108 | chat_filters = ( 109 | SESSION.query(ClearCmd).filter(ClearCmd.chat_id == str(old_chat_id)).all() 110 | ) 111 | for filt in chat_filters: 112 | filt.chat_id = str(new_chat_id) 113 | SESSION.commit() 114 | -------------------------------------------------------------------------------- /Exon/modules/sql/disable_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import threading 31 | 32 | from sqlalchemy import Column, String, UnicodeText, distinct, func 33 | 34 | from Exon.modules.sql import BASE, SESSION 35 | 36 | 37 | class Disable(BASE): 38 | __tablename__ = "disabled_commands" 39 | chat_id = Column(String(14), primary_key=True) 40 | command = Column(UnicodeText, primary_key=True) 41 | 42 | def __init__(self, chat_id, command): 43 | self.chat_id = chat_id 44 | self.command = command 45 | 46 | def __repr__(self): 47 | return f"Disabled cmd {self.command} in {self.chat_id}" 48 | 49 | 50 | Disable.__table__.create(checkfirst=True) 51 | DISABLE_INSERTION_LOCK = threading.RLock() 52 | 53 | DISABLED = {} 54 | 55 | 56 | def disable_command(chat_id, disable): 57 | with DISABLE_INSERTION_LOCK: 58 | disabled = SESSION.query(Disable).get((str(chat_id), disable)) 59 | 60 | if not disabled: 61 | DISABLED.setdefault(str(chat_id), set()).add(disable) 62 | 63 | disabled = Disable(str(chat_id), disable) 64 | SESSION.add(disabled) 65 | SESSION.commit() 66 | return True 67 | 68 | SESSION.close() 69 | return False 70 | 71 | 72 | def enable_command(chat_id, enable): 73 | with DISABLE_INSERTION_LOCK: 74 | if disabled := SESSION.query(Disable).get((str(chat_id), enable)): 75 | if enable in DISABLED.get(str(chat_id)): # sanity check 76 | DISABLED.setdefault(str(chat_id), set()).remove(enable) 77 | 78 | SESSION.delete(disabled) 79 | SESSION.commit() 80 | return True 81 | 82 | SESSION.close() 83 | return False 84 | 85 | 86 | def is_command_disabled(chat_id, cmd): 87 | return str(cmd).lower() in DISABLED.get(str(chat_id), set()) 88 | 89 | 90 | def get_all_disabled(chat_id): 91 | return DISABLED.get(str(chat_id), set()) 92 | 93 | 94 | def num_chats(): 95 | try: 96 | return SESSION.query(func.count(distinct(Disable.chat_id))).scalar() 97 | finally: 98 | SESSION.close() 99 | 100 | 101 | def num_disabled(): 102 | try: 103 | return SESSION.query(Disable).count() 104 | finally: 105 | SESSION.close() 106 | 107 | 108 | def migrate_chat(old_chat_id, new_chat_id): 109 | with DISABLE_INSERTION_LOCK: 110 | chats = SESSION.query(Disable).filter(Disable.chat_id == str(old_chat_id)).all() 111 | for chat in chats: 112 | chat.chat_id = str(new_chat_id) 113 | SESSION.add(chat) 114 | 115 | if str(old_chat_id) in DISABLED: 116 | DISABLED[str(new_chat_id)] = DISABLED.get(str(old_chat_id), set()) 117 | 118 | SESSION.commit() 119 | 120 | 121 | def __load_disabled_commands(): 122 | try: 123 | all_chats = SESSION.query(Disable).all() 124 | for chat in all_chats: 125 | DISABLED.setdefault(chat.chat_id, set()).add(chat.command) 126 | 127 | finally: 128 | SESSION.close() 129 | 130 | 131 | __load_disabled_commands() 132 | -------------------------------------------------------------------------------- /Exon/modules/sql/fsub_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | from sqlalchemy import Column, Numeric, String 30 | 31 | from Exon.modules.sql import BASE, SESSION 32 | 33 | 34 | class forceSubscribe(BASE): 35 | __tablename__ = "forceSubscribe" 36 | chat_id = Column(Numeric, primary_key=True) 37 | channel = Column(String) 38 | 39 | def __init__(self, chat_id, channel): 40 | self.chat_id = chat_id 41 | self.channel = channel 42 | 43 | 44 | forceSubscribe.__table__.create(checkfirst=True) 45 | 46 | 47 | def fs_settings(chat_id): 48 | try: 49 | return ( 50 | SESSION.query(forceSubscribe) 51 | .filter(forceSubscribe.chat_id == chat_id) 52 | .one() 53 | ) 54 | except Exception: 55 | return None 56 | finally: 57 | SESSION.close() 58 | 59 | 60 | def add_channel(chat_id, channel): 61 | adder = SESSION.query(forceSubscribe).get(chat_id) 62 | if adder: 63 | adder.channel = channel 64 | else: 65 | adder = forceSubscribe(chat_id, channel) 66 | SESSION.add(adder) 67 | SESSION.commit() 68 | 69 | 70 | def disapprove(chat_id): 71 | if rem := SESSION.query(forceSubscribe).get(chat_id): 72 | SESSION.delete(rem) 73 | SESSION.commit() 74 | -------------------------------------------------------------------------------- /Exon/modules/sql/language_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import threading 30 | 31 | from sqlalchemy import Column, String, UnicodeText 32 | 33 | from Exon.modules.sql import BASE, SESSION 34 | 35 | 36 | class ChatLangs(BASE): 37 | __tablename__ = "chatlangs" 38 | chat_id = Column(String(14), primary_key=True) 39 | language = Column(UnicodeText) 40 | 41 | def __init__(self, chat_id, language): 42 | self.chat_id = str(chat_id) # ensure string 43 | self.language = language 44 | 45 | def __repr__(self): 46 | return f"Language {self.language} chat {self.chat_id}" 47 | 48 | 49 | CHAT_LANG = {} 50 | LANG_LOCK = threading.RLock() 51 | ChatLangs.__table__.create(checkfirst=True) 52 | 53 | 54 | def set_lang(chat_id: str, lang: str) -> None: 55 | with LANG_LOCK: 56 | if curr := SESSION.query(ChatLangs).get(chat_id): 57 | curr.language = lang 58 | 59 | else: 60 | curr = ChatLangs(chat_id, lang) 61 | SESSION.add(curr) 62 | SESSION.flush() 63 | CHAT_LANG[chat_id] = lang 64 | SESSION.commit() 65 | 66 | 67 | def get_chat_lang(chat_id: str) -> str: 68 | lang = CHAT_LANG.get(chat_id) 69 | if lang is None: 70 | lang = "en" 71 | return lang 72 | 73 | 74 | def __load_chat_language() -> None: 75 | global CHAT_LANG 76 | try: 77 | allchats = SESSION.query(ChatLangs).all() 78 | CHAT_LANG = {x.chat_id: x.language for x in allchats} 79 | finally: 80 | SESSION.close() 81 | 82 | 83 | __load_chat_language() 84 | -------------------------------------------------------------------------------- /Exon/modules/sql/logger_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import threading 31 | 32 | from sqlalchemy import Boolean, Column, String 33 | 34 | from Exon.modules.sql import BASE, SESSION 35 | 36 | 37 | class LoggerSettings(BASE): 38 | __tablename__ = "chat_log_settings" 39 | chat_id = Column(String(14), primary_key=True) 40 | setting = Column(Boolean, default=False, nullable=False) 41 | 42 | def __init__(self, chat_id, disabled): 43 | self.chat_id = str(chat_id) 44 | self.setting = disabled 45 | 46 | def __repr__(self): 47 | return f"" 48 | 49 | 50 | LoggerSettings.__table__.create(checkfirst=True) 51 | 52 | LOG_SETTING_LOCK = threading.RLock() 53 | 54 | 55 | def enable_chat_log(chat_id): 56 | with LOG_SETTING_LOCK: 57 | chat = SESSION.query(LoggerSettings).get(str(chat_id)) or LoggerSettings(chat_id, True) 58 | chat.setting = True 59 | SESSION.add(chat) 60 | SESSION.commit() 61 | 62 | 63 | def disable_chat_log(chat_id): 64 | with LOG_SETTING_LOCK: 65 | chat = SESSION.query(LoggerSettings).get(str(chat_id)) or LoggerSettings(chat_id, False) 66 | 67 | chat.setting = False 68 | SESSION.add(chat) 69 | SESSION.commit() 70 | 71 | 72 | def does_chat_log(chat_id): 73 | with LOG_SETTING_LOCK: 74 | d = SESSION.query(LoggerSettings).get(str(chat_id)) 75 | return d.setting if d else False 76 | 77 | 78 | def migrate_chat(old_chat_id, new_chat_id): 79 | with LOG_SETTING_LOCK: 80 | if chat := SESSION.query(LoggerSettings).get(str(old_chat_id)): 81 | chat.chat_id = new_chat_id 82 | SESSION.add(chat) 83 | 84 | SESSION.commit() 85 | -------------------------------------------------------------------------------- /Exon/modules/sql/night_mode_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | from sqlalchemy import Column, String 31 | 32 | from Exon.modules.sql import BASE, SESSION 33 | 34 | 35 | class Nightmode(BASE): 36 | __tablename__ = "nightmode" 37 | chat_id = Column(String(14), primary_key=True) 38 | 39 | def __init__(self, chat_id): 40 | self.chat_id = chat_id 41 | 42 | 43 | Nightmode.__table__.create(checkfirst=True) 44 | 45 | 46 | def add_nightmode(chat_id: str): 47 | nightmoddy = Nightmode(chat_id) 48 | SESSION.add(nightmoddy) 49 | SESSION.commit() 50 | 51 | 52 | def rmnightmode(chat_id: str): 53 | if rmnightmoddy := SESSION.query(Nightmode).get(chat_id): 54 | SESSION.delete(rmnightmoddy) 55 | SESSION.commit() 56 | 57 | 58 | def get_all_chat_id(): 59 | stark = SESSION.query(Nightmode).all() 60 | SESSION.close() 61 | return stark 62 | 63 | 64 | def is_nightmode_indb(chat_id: str): 65 | try: 66 | if s__ := SESSION.query(Nightmode).get(chat_id): 67 | return str(s__.chat_id) 68 | finally: 69 | SESSION.close() 70 | -------------------------------------------------------------------------------- /Exon/modules/sql/reporting_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import threading 31 | from typing import Union 32 | 33 | from sqlalchemy import Boolean, Column, String 34 | from sqlalchemy.sql.sqltypes import BigInteger 35 | 36 | from Exon.modules.sql import BASE, SESSION 37 | 38 | 39 | class ReportingUserSettings(BASE): 40 | __tablename__ = "user_report_settings" 41 | user_id = Column(BigInteger, primary_key=True) 42 | should_report = Column(Boolean, default=True) 43 | 44 | def __init__(self, user_id): 45 | self.user_id = user_id 46 | 47 | def __repr__(self): 48 | return f"" 49 | 50 | 51 | class ReportingChatSettings(BASE): 52 | __tablename__ = "chat_report_settings" 53 | chat_id = Column(String(14), primary_key=True) 54 | should_report = Column(Boolean, default=True) 55 | 56 | def __init__(self, chat_id): 57 | self.chat_id = str(chat_id) 58 | 59 | def __repr__(self): 60 | return f"" 61 | 62 | 63 | ReportingUserSettings.__table__.create(checkfirst=True) 64 | ReportingChatSettings.__table__.create(checkfirst=True) 65 | 66 | CHAT_LOCK = threading.RLock() 67 | USER_LOCK = threading.RLock() 68 | 69 | 70 | def chat_should_report(chat_id: Union[str, int]) -> bool: 71 | try: 72 | if chat_setting := SESSION.query(ReportingChatSettings).get( 73 | str(chat_id) 74 | ): 75 | return chat_setting.should_report 76 | return False 77 | finally: 78 | SESSION.close() 79 | 80 | 81 | def user_should_report(user_id: int) -> bool: 82 | try: 83 | if user_setting := SESSION.query(ReportingUserSettings).get(user_id): 84 | return user_setting.should_report 85 | return True 86 | finally: 87 | SESSION.close() 88 | 89 | 90 | def set_chat_setting(chat_id: Union[int, str], setting: bool): 91 | with CHAT_LOCK: 92 | chat_setting = SESSION.query(ReportingChatSettings).get(str(chat_id)) or ReportingChatSettings(chat_id) 93 | 94 | chat_setting.should_report = setting 95 | SESSION.add(chat_setting) 96 | SESSION.commit() 97 | 98 | 99 | def set_user_setting(user_id: int, setting: bool): 100 | with USER_LOCK: 101 | user_setting = SESSION.query(ReportingUserSettings).get(user_id) or ReportingUserSettings(user_id) 102 | 103 | user_setting.should_report = setting 104 | SESSION.add(user_setting) 105 | SESSION.commit() 106 | 107 | 108 | def migrate_chat(old_chat_id, new_chat_id): 109 | with CHAT_LOCK: 110 | chat_notes = ( 111 | SESSION.query(ReportingChatSettings) 112 | .filter(ReportingChatSettings.chat_id == str(old_chat_id)) 113 | .all() 114 | ) 115 | for note in chat_notes: 116 | note.chat_id = str(new_chat_id) 117 | SESSION.commit() 118 | -------------------------------------------------------------------------------- /Exon/modules/sql/rules_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import threading 30 | 31 | from sqlalchemy import Column, String, UnicodeText, distinct, func 32 | 33 | from Exon.modules.sql import BASE, SESSION 34 | 35 | 36 | class Rules(BASE): 37 | __tablename__ = "rules" 38 | chat_id = Column(String(14), primary_key=True) 39 | rules = Column(UnicodeText, default="") 40 | 41 | def __init__(self, chat_id): 42 | self.chat_id = chat_id 43 | 44 | def __repr__(self): 45 | return f"" 46 | 47 | 48 | Rules.__table__.create(checkfirst=True) 49 | 50 | INSERTION_LOCK = threading.RLock() 51 | 52 | 53 | def set_rules(chat_id, rules_text): 54 | with INSERTION_LOCK: 55 | rules = SESSION.query(Rules).get(str(chat_id)) or Rules(str(chat_id)) 56 | rules.rules = rules_text 57 | 58 | SESSION.add(rules) 59 | SESSION.commit() 60 | 61 | 62 | def get_rules(chat_id): 63 | rules = SESSION.query(Rules).get(str(chat_id)) 64 | ret = rules.rules if rules else "" 65 | SESSION.close() 66 | return ret 67 | 68 | 69 | def num_chats(): 70 | try: 71 | return SESSION.query(func.count(distinct(Rules.chat_id))).scalar() 72 | finally: 73 | SESSION.close() 74 | 75 | 76 | def migrate_chat(old_chat_id, new_chat_id): 77 | with INSERTION_LOCK: 78 | if chat := SESSION.query(Rules).get(str(old_chat_id)): 79 | chat.chat_id = str(new_chat_id) 80 | SESSION.commit() 81 | -------------------------------------------------------------------------------- /Exon/modules/sql/userinfo_sql.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import threading 30 | 31 | from sqlalchemy import Column, UnicodeText 32 | from sqlalchemy.sql.sqltypes import BigInteger 33 | 34 | from Exon.modules.sql import BASE, SESSION 35 | 36 | 37 | class UserInfo(BASE): 38 | __tablename__ = "userinfo" 39 | user_id = Column(BigInteger, primary_key=True) 40 | info = Column(UnicodeText) 41 | 42 | def __init__(self, user_id, info): 43 | self.user_id = user_id 44 | self.info = info 45 | 46 | def __repr__(self): 47 | return "" % self.user_id 48 | 49 | 50 | class UserBio(BASE): 51 | __tablename__ = "userbio" 52 | user_id = Column(BigInteger, primary_key=True) 53 | bio = Column(UnicodeText) 54 | 55 | def __init__(self, user_id, bio): 56 | self.user_id = user_id 57 | self.bio = bio 58 | 59 | def __repr__(self): 60 | return "" % self.user_id 61 | 62 | 63 | UserInfo.__table__.create(checkfirst=True) 64 | UserBio.__table__.create(checkfirst=True) 65 | 66 | INSERTION_LOCK = threading.RLock() 67 | 68 | 69 | def get_user_me_info(user_id): 70 | userinfo = SESSION.query(UserInfo).get(user_id) 71 | SESSION.close() 72 | return userinfo.info if userinfo else None 73 | 74 | 75 | def set_user_me_info(user_id, info): 76 | with INSERTION_LOCK: 77 | userinfo = SESSION.query(UserInfo).get(user_id) 78 | if userinfo: 79 | userinfo.info = info 80 | else: 81 | userinfo = UserInfo(user_id, info) 82 | SESSION.add(userinfo) 83 | SESSION.commit() 84 | 85 | 86 | def get_user_bio(user_id): 87 | userbio = SESSION.query(UserBio).get(user_id) 88 | SESSION.close() 89 | return userbio.bio if userbio else None 90 | 91 | 92 | def set_user_bio(user_id, bio): 93 | with INSERTION_LOCK: 94 | userbio = SESSION.query(UserBio).get(user_id) 95 | if userbio: 96 | userbio.bio = bio 97 | else: 98 | userbio = UserBio(user_id, bio) 99 | 100 | SESSION.add(userbio) 101 | SESSION.commit() 102 | -------------------------------------------------------------------------------- /Exon/modules/stats.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | import os 30 | import time 31 | 32 | import psutil 33 | 34 | import Exon.modules.no_sql.users_db as users_db 35 | from Exon import BOT_NAME, StartTime 36 | from Exon.modules.helper_funcs import formatter 37 | 38 | 39 | # sᴛᴀᴛs ᴍᴏᴅᴜʟᴇ 40 | 41 | 42 | async def bot_sys_stats(): 43 | bot_uptime = int(time.time() - StartTime) 44 | cpu = psutil.cpu_percent() 45 | mem = psutil.virtual_memory().percent 46 | disk = psutil.disk_usage("/").percent 47 | process = psutil.Process(os.getpid()) 48 | return f""" 49 | ------------------ 50 | ⛖ {BOT_NAME} ᴜᴘᴛɪᴍᴇ : {formatter.get_readable_time(bot_uptime)} 51 | ⛖ ʙᴏᴛ ᴄᴀᴘᴀᴄɪᴛʏ : {round(process.memory_info()[0] / 1024 ** 2)} ᴍʙ 52 | ⛖ ᴄᴘᴜ ᴜsᴀɢᴇ : {cpu}% 53 | ⛖ ʀᴀᴍ ᴜsᴀɢᴇ : {mem}% 54 | ⛖ ᴅɪsᴋ ᴜsᴀɢᴇ : {disk}% 55 | ⛖ ᴜsᴇʀs : 0{users_db.num_users()} ᴜsᴇʀs. 56 | ⛖ ɢʀᴏᴜᴘs : 0{users_db.num_chats()} ɢʀᴏᴜᴘs. 57 | """ 58 | -------------------------------------------------------------------------------- /Exon/modules/truth_and_dare.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | 31 | import requests 32 | 33 | from Exon import SUPPORT_CHAT 34 | from Exon.events import register as abishnoi 35 | 36 | 37 | @abishnoi(pattern="[/!]dare") 38 | async def _(asux): 39 | try: 40 | ak = requests.get("https://api.truthordarebot.xyz/v1/dare").json() 41 | results = f"{ak['question']}" 42 | return await asux.reply(results) 43 | except Exception: 44 | await asux.reply(f"ᴇʀʀᴏʀ ʀᴇᴘᴏʀᴛ @{SUPPORT_CHAT}") 45 | 46 | 47 | @abishnoi(pattern="[/!]truth") 48 | async def _(asux): 49 | try: 50 | ak = requests.get("https://api.truthordarebot.xyz/v1/truth").json() 51 | results = f"{ak['question']}" 52 | return await asux.reply(results) 53 | except Exception: 54 | await asux.reply(f"ᴇʀʀᴏʀ ʀᴇᴘᴏʀᴛ @{SUPPORT_CHAT}") 55 | 56 | 57 | __mod_name__ = "𝐓ʀᴜᴛʜ-Dᴀʀᴇ" 58 | 59 | from Exon.modules.language import gs 60 | 61 | 62 | def get_help(chat): 63 | return gs(chat, "td_help") 64 | -------------------------------------------------------------------------------- /Exon/modules/ubot.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | from asyncio.exceptions import TimeoutError 31 | 32 | from telethon.errors.rpcerrorlist import YouBlockedUserError 33 | 34 | from Exon import ubot 35 | from Exon.events import register 36 | 37 | 38 | @register(pattern="^/sg ?(.*)") 39 | @register(pattern="^/check_name ?(.*)") 40 | async def lastname(steal): 41 | steal.pattern_match.group(1) 42 | puki = await steal.reply("```Retrieving Such User Information..```") 43 | if steal.fwd_from: 44 | return 45 | if not steal.reply_to_msg_id: 46 | await puki.edit("```Please Reply To User Message.```") 47 | return 48 | message = await steal.get_reply_message() 49 | chat = "@SangMataInfo_bot" 50 | user_id = message.sender.id 51 | id = f"/search_id {user_id}" 52 | if message.sender.bot: 53 | await puki.edit("```Reply To Real User's Message.```") 54 | return 55 | await puki.edit("```Please wait...```") 56 | try: 57 | async with ubot.conversation(chat) as conv: 58 | try: 59 | msg = await conv.send_message(id) 60 | r = await conv.get_response() 61 | response = await conv.get_response() 62 | except YouBlockedUserError: 63 | await steal.reply("```Error, report to @AbishnoiMF```") 64 | return 65 | if r.text.startswith("Name"): 66 | respond = await conv.get_response() 67 | await puki.edit(f"`{r.message}`") 68 | await ubot.delete_messages( 69 | conv.chat_id, [msg.id, r.id, response.id, respond.id] 70 | ) 71 | return 72 | if response.text.startswith("No records") or r.text.startswith( 73 | "No records" 74 | ): 75 | await puki.edit( 76 | "```I Can't Find This User's Information, This User Has Never Changed His Name Before.```" 77 | ) 78 | await ubot.delete_messages(conv.chat_id, [msg.id, r.id, response.id]) 79 | return 80 | else: 81 | respond = await conv.get_response() 82 | await puki.edit(f"```{response.message}```") 83 | await ubot.delete_messages( 84 | conv.chat_id, [msg.id, r.id, response.id, respond.id] 85 | ) 86 | except TimeoutError: 87 | return await puki.edit("`I'm Sick Sorry...`") 88 | -------------------------------------------------------------------------------- /Exon/modules/wallpaper.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- ABISHNOI69 "" 29 | 30 | import random 31 | from random import randint 32 | 33 | import requests 34 | from pyrogram import enums 35 | from pyrogram.types import Message 36 | 37 | from Exon import Abishnoi, arq 38 | 39 | 40 | @Abishnoi.on_cmd(["wallpaper"]) 41 | async def wallpaper(_, msg): 42 | if len(msg.command) < 2: 43 | await msg.reply_text("ʜᴇʏ ʙᴀʙʏ ɢɪᴠᴇ sᴏᴍᴇᴛʜɪɴɢ ᴛᴏ sᴇᴀʀᴄʜ.") 44 | return 45 | query = ( 46 | msg.text.split(None, 1)[1] 47 | if len(msg.command) < 3 48 | else msg.text.split(None, 1)[1].replace(" ", "%20") 49 | ) 50 | 51 | if not query: 52 | await msg.reply_text("ʜᴇʏ ʙᴀʙʏ ɢɪᴠᴇ sᴏᴍᴇᴛʜɪɴɢ ᴛᴏ sᴇᴀʀᴄʜ.") 53 | url = f"https://api.safone.me/wall?query={query}" 54 | re = requests.get(url).json() 55 | walls = re.get("results") 56 | if not walls: 57 | await msg.reply_text("ɴᴏ ʀᴇsᴜʟᴛs ғᴏᴜɴᴅ! ") 58 | return 59 | wall_index = randint(0, len(walls) - 1) 60 | wallpaper = walls[wall_index] 61 | wallpaper.get("imageUrl") 62 | preview = wallpaper.get("thumbUrl") 63 | title = wallpaper.get("title") 64 | try: 65 | await Abishnoi.send_chat_action(msg.chat.id, enums.ChatAction.UPLOAD_PHOTO) 66 | await msg.reply_photo( 67 | preview, caption=f"🔎 ᴛɪᴛʟᴇ - {title}\nᴊᴏɪɴ [@ᴀʙɪsʜɴᴏɪᴍғ](t.me/AbishnoiMF)" 68 | ) 69 | # await msg.reply_document(pic, caption=f"🔎 ᴛɪᴛʟᴇ - {title} \n🥀 **ʀᴇǫᴜᴇsᴛᴇᴅ ʙʏ :** {msg.from_user.mention}") 70 | except Exception as error: 71 | await msg.reply_text(f"ᴀɴ ᴇʀʀᴏʀ ᴏᴄᴄᴜʀᴇᴅ.\n {error}") 72 | 73 | 74 | @Abishnoi.on_cmd("wall") 75 | async def wall(_, m: Message): 76 | if len(m.command) < 2: 77 | return await m.reply_text("ɢɪᴠᴇ ᴍᴇ ᴀ ᴛᴇxᴛ !") 78 | search = m.text.split(None, 1)[1] 79 | x = await arq.wall(search) 80 | y = x.result 81 | await m.reply_photo(random.choice(y).url_image) 82 | # await m.reply_document(random.choice(y).url_image) 83 | -------------------------------------------------------------------------------- /Exon/modules/weather.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 AshokShau 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # UPDATE :- Abishnoi_bots 28 | # GITHUB :- AshokShau "" 29 | 30 | import httpx 31 | from pyrogram import Client 32 | from pyrogram.types import Message 33 | 34 | from Exon import Abishnoi 35 | 36 | timeout = httpx.Timeout(40, pool=None) 37 | 38 | http = httpx.AsyncClient(http2=True, timeout=timeout) 39 | 40 | # Api key used in weather.com's mobile app. 41 | weather_apikey = "8de2d8b3a93542c9a2d8b3a935a2c909" 42 | 43 | get_coords = "https://api.weather.com/v3/location/search" 44 | url = "https://api.weather.com/v3/aggcommon/v3-wx-observations-current" 45 | 46 | headers = { 47 | "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 12; M2012K11AG Build/SQ1D.211205.017)" 48 | } 49 | 50 | 51 | @Abishnoi.on_cmd("weather") 52 | async def weather(c: Client, m: Message): 53 | if len(m.command) == 1: 54 | return await m.reply_text( 55 | "ᴜsᴀɢᴇ: /weather location ᴏʀ city - ɢᴇᴛ ɪɴғᴏʀᴍᴀᴛɪᴏɴ ᴀʙᴏᴜᴛ ᴛʜᴇ ᴡᴇᴀᴛʜᴇʀ ɪɴ ʟᴏᴄᴀᴛɪᴏɴ ᴏʀ ᴄɪᴛʏ" 56 | ) 57 | 58 | r = await http.get( 59 | get_coords, 60 | headers=headers, 61 | params=dict( 62 | apiKey=weather_apikey, 63 | format="json", 64 | language="en", 65 | query=m.text.split(maxsplit=1)[1], 66 | ), 67 | ) 68 | loc_json = r.json() 69 | 70 | if not loc_json.get("location"): 71 | await m.reply_text("ʟᴏᴄᴀᴛɪᴏɴ ɴᴏᴛ ғᴏᴜɴᴅ") 72 | else: 73 | pos = f"{loc_json['location']['latitude'][0]},{loc_json['location']['longitude'][0]}" 74 | r = await http.get( 75 | url, 76 | headers=headers, 77 | params=dict( 78 | apiKey=weather_apikey, 79 | format="json", 80 | language="en", 81 | geocode=pos, 82 | units="m", 83 | ), 84 | ) 85 | res_json = r.json() 86 | 87 | obs_dict = res_json["v3-wx-observations-current"] 88 | 89 | res = "{location}:\n\nᴛᴇᴍᴘᴇʀᴀᴛᴜʀᴇ: {temperature} °C\nᴛᴇᴍᴘᴇʀᴀᴛᴜʀᴇ ғᴇᴇʟs ʟɪᴋᴇ: {feels_like} °C\nᴀɪʀ ʜᴜᴍɪᴅɪᴛʏ: {air_humidity}%\nᴡɪɴᴅ sᴘᴇᴇᴅ: {wind_speed} km/h\n\n- {overview}".format( 90 | location=loc_json["location"]["address"][0], 91 | temperature=obs_dict["temperature"], 92 | feels_like=obs_dict["temperatureFeelsLike"], 93 | air_humidity=obs_dict["relativeHumidity"], 94 | wind_speed=obs_dict["windSpeed"], 95 | overview=obs_dict["wxPhraseLong"], 96 | ) 97 | 98 | await m.reply_text(res) 99 | -------------------------------------------------------------------------------- /Exon/modules/webss.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABISHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | # ""DEAR PRO PEOPLE, DON'T REMOVE & CHANGE THIS LINE 26 | # TG :- @AshokShau 27 | # :- Abishnoi_bots 28 | # GITHUB :- Abishnoi69 "" 29 | 30 | 31 | from base64 import b64decode 32 | from inspect import getfullargspec 33 | from io import BytesIO 34 | 35 | from pyrogram.types import Message 36 | 37 | from Exon import Abishnoi as app 38 | from Exon import aiohttpsession as session 39 | 40 | 41 | async def post(url: str, *args, **kwargs): 42 | async with session.post(url, *args, **kwargs) as resp: 43 | try: 44 | data = await resp.json() 45 | except Exception: 46 | data = await resp.text() 47 | return data 48 | 49 | 50 | async def take_screenshot(url: str, full: bool = False): 51 | url = url if url.startswith("http") else f"https://{url}" 52 | payload = { 53 | "url": url, 54 | "width": 1920, 55 | "height": 1080, 56 | "scale": 1, 57 | "format": "jpeg", 58 | } 59 | if full: 60 | payload["full"] = True 61 | data = await post( 62 | "https://webscreenshot.vercel.app/api", 63 | data=payload, 64 | ) 65 | if "image" not in data: 66 | return None 67 | b = data["image"].replace("data:image/jpeg;base64,", "") 68 | file = BytesIO(b64decode(b)) 69 | file.name = "webss.jpg" 70 | return file 71 | 72 | 73 | async def eor(msg: Message, **kwargs): 74 | func = ( 75 | (msg.edit_text if msg.from_user.is_self else msg.reply) 76 | if msg.from_user 77 | else msg.reply 78 | ) 79 | spec = getfullargspec(func.__wrapped__).args 80 | return await func(**{k: v for k, v in kwargs.items() if k in spec}) 81 | 82 | 83 | @app.on_cmd(["webss", "ss", "webshot"]) 84 | async def take_ss(_, message: Message): 85 | if len(message.command) < 2: 86 | return await eor(message, text="ɢɪᴠᴇ ᴀ ᴜʀʟ ᴛᴏ ғᴇᴛᴄʜ sᴄʀᴇᴇɴsʜᴏᴛ.") 87 | 88 | if len(message.command) == 2: 89 | url = message.text.split(None, 1)[1] 90 | full = False 91 | elif len(message.command) == 3: 92 | url = message.text.split(None, 2)[1] 93 | full = message.text.split(None, 2)[2].lower().strip() in [ 94 | "yes", 95 | "y", 96 | "1", 97 | "true", 98 | ] 99 | else: 100 | return await eor(message, text="ɪɴᴠᴀʟɪᴅ ᴄᴏᴍᴍᴀɴᴅ.") 101 | 102 | m = await eor(message, text="ᴄᴀᴘᴛᴜʀɪɴɢ sᴄʀᴇᴇɴsʜᴏᴛ...") 103 | 104 | try: 105 | photo = await take_screenshot(url, full) 106 | if not photo: 107 | return await m.edit("ғᴀɪʟᴇᴅ ᴛᴏ ᴛᴀᴋᴇ sᴄʀᴇᴇɴsʜᴏᴛ.") 108 | 109 | m = await m.edit("ᴜᴘʟᴏᴀᴅɪɴɢ...") 110 | 111 | await message.reply_document(photo) 112 | await m.delete() 113 | except Exception as e: 114 | await m.edit(str(e)) 115 | 116 | 117 | __mod_name__ = "𝐖ᴇʙsʜᴏᴛ" 118 | 119 | from Exon.modules.language import gs 120 | 121 | 122 | def get_help(chat): 123 | return gs(chat, "webss_help") 124 | -------------------------------------------------------------------------------- /Exon/modules/zombies.py: -------------------------------------------------------------------------------- 1 | from asyncio import sleep 2 | 3 | from telethon import events 4 | from telethon.errors import ChatAdminRequiredError, UserAdminInvalidError 5 | from telethon.tl.functions.channels import EditBannedRequest 6 | from telethon.tl.types import ChannelParticipantsAdmins, ChatBannedRights 7 | 8 | from Exon import DEMONS, DEV_USERS, DRAGONS, OWNER_ID, telethn 9 | 10 | # =================== CONSTANT =================== 11 | 12 | BANNED_RIGHTS = ChatBannedRights( 13 | until_date=None, 14 | view_messages=True, 15 | send_messages=True, 16 | send_media=True, 17 | send_stickers=True, 18 | send_gifs=True, 19 | send_games=True, 20 | send_inline=True, 21 | embed_links=True, 22 | ) 23 | 24 | UNBAN_RIGHTS = ChatBannedRights( 25 | until_date=None, 26 | send_messages=None, 27 | send_media=None, 28 | send_stickers=None, 29 | send_gifs=None, 30 | send_games=None, 31 | send_inline=None, 32 | embed_links=None, 33 | ) 34 | 35 | OFFICERS = [OWNER_ID] + DEV_USERS + DRAGONS + DEMONS 36 | 37 | 38 | # Check if user has admin rights 39 | async def is_administrator(user_id: int, message): 40 | admin = False 41 | async for user in telethn.iter_participants( 42 | message.chat_id, filter=ChannelParticipantsAdmins 43 | ): 44 | if user_id == user.id or user_id in OFFICERS: 45 | admin = True 46 | break 47 | return admin 48 | 49 | 50 | @telethn.on(events.NewMessage(pattern="^[!/]zombies ?(.*)")) 51 | async def zombies(event): 52 | """For .zombies command, list all the zombies in a chat.""" 53 | con = event.pattern_match.group(1).lower() 54 | del_u = 0 55 | del_status = "ɴᴏ ᴅᴇʟᴇᴛᴇᴅ ᴀᴄᴄᴏᴜɴᴛꜱ ꜰᴏᴜɴᴅ, ɢʀᴏᴜᴘ ɪꜱ ᴄʟᴇᴀɴ ᴇɴᴊᴏʏ." 56 | 57 | if con != "clean": 58 | find_zombies = await event.respond("ꜱᴇᴀʀᴄʜɪɴɢ ꜰᴏʀ ᴢᴏᴍʙɪᴇꜱ...") 59 | async for user in event.client.iter_participants(event.chat_id): 60 | if user.deleted: 61 | del_u += 1 62 | await sleep(1) 63 | if del_u > 0: 64 | del_status = f"ꜰᴏᴜɴᴅ **{del_u}** ᴢᴏᴍʙɪᴇꜱ ɪɴ ᴛʜɪꜱ ɢʀᴏᴜᴘ.\ 65 | \nᴄʟᴇᴀɴ ᴛʜᴇᴍ ʙʏ ᴜꜱɪɴɢ - `/zombies clean`" 66 | await find_zombies.edit(del_status) 67 | return 68 | 69 | # Here laying the sanity check 70 | chat = await event.get_chat() 71 | admin = chat.admin_rights 72 | creator = chat.creator 73 | 74 | # Well 75 | if not await is_administrator(user_id=event.sender_id, message=event): 76 | await event.respond("You're Not An Admin!") 77 | return 78 | 79 | if not admin and not creator: 80 | await event.respond("ɪ ᴀᴍ ɴᴏᴛ ᴀᴅᴍɪɴ ʜᴇʀᴇ!") 81 | return 82 | 83 | cleaning_zombies = await event.respond("ᴄʟᴇᴀɴɪɴɢ ᴢᴏᴍʙɪᴇꜱ...") 84 | del_u = 0 85 | del_a = 0 86 | 87 | async for user in event.client.iter_participants(event.chat_id): 88 | if user.deleted: 89 | try: 90 | await event.client( 91 | EditBannedRequest(event.chat_id, user.id, BANNED_RIGHTS) 92 | ) 93 | except ChatAdminRequiredError: 94 | await cleaning_zombies.edit("ɪ ᴅᴏɴᴛ ʜᴀᴠᴇ ʙᴀɴ ʀɪɢʜᴛ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ.") 95 | return 96 | except UserAdminInvalidError: 97 | del_u -= 1 98 | del_a += 1 99 | await event.client(EditBannedRequest(event.chat_id, user.id, UNBAN_RIGHTS)) 100 | del_u += 1 101 | 102 | if del_u > 0: 103 | del_status = f"ᴄʟᴇᴀɴᴇᴅ `{del_u}` ᴢᴏᴍʙɪᴇꜱ" 104 | 105 | if del_a > 0: 106 | del_status = f"ᴄʟᴇᴀɴᴇᴅ `{del_u}` ᴢᴏᴍʙɪᴇꜱ \ 107 | \n`{del_a}` ᴢᴏᴍʙɪᴇꜱ ᴀᴅᴍɪɴ ᴀᴄᴄᴏᴜɴᴛꜱ ᴀʀᴇ ɴᴏᴛ ʀᴇᴍᴏᴠᴇᴅ!" 108 | 109 | await cleaning_zombies.edit(del_status) 110 | 111 | 112 | __mod_name__ = "𝐙ᴏᴍʙɪᴇs" 113 | 114 | # ғᴏʀ ʜᴇʟᴘ ᴍᴇɴᴜ 115 | 116 | 117 | # """ 118 | from Exon.modules.language import gs 119 | 120 | 121 | def get_help(chat): 122 | return gs(chat, "zombies_help") 123 | 124 | # """ 125 | -------------------------------------------------------------------------------- /Exon/utils/ABISHNOI ©: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | -------------------------------------------------------------------------------- /Exon/utils/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | -------------------------------------------------------------------------------- /Exon/utils/adminpermissions.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from Exon import Abishnoi as AsuX 26 | 27 | 28 | async def member_permissions(chat_id: int, user_id: int): 29 | perms = [] 30 | member = await AsuX.get_chat_member(chat_id, user_id) 31 | if member.can_post_messages: 32 | perms.append("can_post_messages") 33 | if member.can_edit_messages: 34 | perms.append("can_edit_messages") 35 | if member.can_delete_messages: 36 | perms.append("can_delete_messages") 37 | if member.can_restrict_members: 38 | perms.append("can_restrict_members") 39 | if member.can_promote_members: 40 | perms.append("can_promote_members") 41 | if member.can_change_info: 42 | perms.append("can_change_info") 43 | if member.can_invite_users: 44 | perms.append("can_invite_users") 45 | if member.can_pin_messages: 46 | perms.append("can_pin_messages") 47 | if member.can_manage_voice_chats: 48 | perms.append("can_manage_voice_chats") 49 | return perms 50 | -------------------------------------------------------------------------------- /Exon/utils/errors.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import sys 26 | import traceback 27 | from functools import wraps 28 | 29 | from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden 30 | 31 | from Exon import SUPPORT_CHAT, Abishnoi 32 | 33 | 34 | def split_limits(text): 35 | if len(text) < 2048: 36 | return [text] 37 | 38 | lines = text.splitlines(True) 39 | small_msg = "" 40 | result = [] 41 | for line in lines: 42 | if len(small_msg) + len(line) < 2048: 43 | small_msg += line 44 | else: 45 | result.append(small_msg) 46 | small_msg = line 47 | 48 | result.append(small_msg) 49 | 50 | return result 51 | 52 | 53 | def capture_err(func): 54 | @wraps(func) 55 | async def capture(client, message, *args, **kwargs): 56 | try: 57 | return await func(client, message, *args, **kwargs) 58 | except ChatWriteForbidden: 59 | await Abishnoi.leave_chat(message.chat.id) 60 | return 61 | except Exception as err: 62 | exc_type, exc_obj, exc_tb = sys.exc_info() 63 | errors = traceback.format_exception( 64 | etype=exc_type, 65 | value=exc_obj, 66 | tb=exc_tb, 67 | ) 68 | error_feedback = split_limits( 69 | "**ᴇʀʀᴏʀ** | `{}` | `{}`\n\n```{}```\n\n```{}```\n".format( 70 | message.from_user.id if message.from_user else 0, 71 | message.chat.id if message.chat else 0, 72 | message.text or message.caption, 73 | "".join(errors), 74 | ), 75 | ) 76 | for x in error_feedback: 77 | await Abishnoi.send_message(SUPPORT_CHAT, x) 78 | raise err 79 | 80 | return capture 81 | -------------------------------------------------------------------------------- /Exon/utils/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | 26 | class CancelProcess(Exception): 27 | """ 28 | Cancel Process 29 | """ 30 | -------------------------------------------------------------------------------- /Exon/utils/fetch.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from Exon import aiohttpsession 26 | 27 | headers = { 28 | "Accept": "application/json", 29 | "Content-Type": "application/json", 30 | } 31 | 32 | 33 | async def fetch(url: str): 34 | async with aiohttpsession.get(url, headers=headers) as resp: 35 | try: 36 | data = await resp.json() 37 | except Exception: 38 | data = await resp.text() 39 | return data 40 | -------------------------------------------------------------------------------- /Exon/utils/formatter.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | 26 | def get_readable_time(seconds: int) -> str: 27 | count = 0 28 | ping_time = "" 29 | time_list = [] 30 | time_suffix_list = ["s", "ᴍ", "ʜ", "ᴅᴀʏs"] 31 | while count < 4: 32 | count += 1 33 | remainder, result = divmod(seconds, 60) if count < 3 else divmod(seconds, 24) 34 | if seconds == 0 and remainder == 0: 35 | break 36 | time_list.append(int(result)) 37 | seconds = int(remainder) 38 | for i in range(len(time_list)): 39 | time_list[i] = str(time_list[i]) + time_suffix_list[i] 40 | if len(time_list) == 4: 41 | ping_time += f"{time_list.pop()}, " 42 | time_list.reverse() 43 | ping_time += ":".join(time_list) 44 | return ping_time 45 | 46 | 47 | # Convert seconds to mm:ss @AbishnoiMF 48 | async def convert_seconds_to_minutes(seconds: int): 49 | seconds = seconds 50 | seconds %= 24 * 3600 51 | seconds %= 3600 52 | minutes = seconds // 60 53 | seconds %= 60 54 | return "%02d:%02d" % (minutes, seconds) 55 | -------------------------------------------------------------------------------- /Exon/utils/http.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from asyncio import gather 26 | 27 | from Exon import aiohttpsession as session 28 | 29 | 30 | async def get(url: str, *args, **kwargs): 31 | async with session.get(url, *args, **kwargs) as resp: 32 | try: 33 | data = await resp.json() 34 | except Exception: 35 | data = await resp.text() 36 | return data 37 | 38 | 39 | async def head(url: str, *args, **kwargs): 40 | async with session.head(url, *args, **kwargs) as resp: 41 | try: 42 | data = await resp.json() 43 | except Exception: 44 | data = await resp.text() 45 | return data 46 | 47 | 48 | async def post(url: str, *args, **kwargs): 49 | async with session.post(url, *args, **kwargs) as resp: 50 | try: 51 | data = await resp.json() 52 | except Exception: 53 | data = await resp.text() 54 | return data 55 | 56 | 57 | async def multiget(url: str, times: int, *args, **kwargs): 58 | return await gather(*[get(url, *args, **kwargs) for _ in range(times)]) 59 | 60 | 61 | async def multihead(url: str, times: int, *args, **kwargs): 62 | return await gather(*[head(url, *args, **kwargs) for _ in range(times)]) 63 | 64 | 65 | async def multipost(url: str, times: int, *args, **kwargs): 66 | return await gather(*[post(url, *args, **kwargs) for _ in range(times)]) 67 | 68 | 69 | async def resp_get(url: str, *args, **kwargs): 70 | return await session.get(url, *args, **kwargs) 71 | 72 | 73 | async def resp_post(url: str, *args, **kwargs): 74 | return await session.post(url, *args, **kwargs) 75 | -------------------------------------------------------------------------------- /Exon/utils/keyboard.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from pykeyboard import InlineKeyboard 26 | from pyrogram.types import InlineKeyboardButton as Ikb 27 | 28 | from Exon.utils.functions import get_urls_from_text as is_url 29 | 30 | 31 | def keyboard(buttons_list, row_width: int = 2): 32 | """ 33 | Buttons builder, pass buttons in a list and it will 34 | return pyrogram.types.IKB object 35 | Ex: keyboard([["click here", "https://google.com"]]) 36 | if theres, a url, it will make url button, else callback button 37 | """ 38 | buttons = InlineKeyboard(row_width=row_width) 39 | data = [ 40 | ( 41 | Ikb(text=str(i[0]), url=str(i[1])) if is_url(i[1]) else Ikb(text=str(i[0]), callback_data=str(i[1])) 42 | ) 43 | for i in buttons_list 44 | ] 45 | buttons.add(*data) 46 | return buttons 47 | 48 | 49 | def ikb(data: dict, row_width: int = 2): 50 | """ 51 | Converts a dict to pyrogram buttons 52 | Ex: dict_to_keyboard({"click here": "this is callback data"}) 53 | """ 54 | return keyboard(data.items(), row_width=row_width) 55 | -------------------------------------------------------------------------------- /Exon/utils/pastebin.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import base64 26 | import json 27 | import socket 28 | import typing 29 | import zlib 30 | from asyncio import get_running_loop 31 | from functools import partial 32 | from urllib.parse import urljoin, urlparse, urlunparse 33 | 34 | import base58 35 | import requests 36 | from Crypto import Hash, Protocol, Random 37 | from Crypto.Cipher import AES 38 | 39 | from Exon.utils.http import post 40 | 41 | headers = { 42 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36", 43 | "content-type": "application/json", 44 | } 45 | 46 | BASE = "https://batbin.me/" 47 | 48 | 49 | def _netcat(host, port, content): 50 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 51 | s.connect((host, port)) 52 | s.sendall(content.encode()) 53 | s.shutdown(socket.SHUT_WR) 54 | while True: 55 | if data := s.recv(4096).decode("utf-8").strip("\n\x00"): 56 | return data 57 | else: 58 | break 59 | s.close() 60 | 61 | 62 | async def paste(content): 63 | loop = get_running_loop() 64 | return await loop.run_in_executor( 65 | None, partial(_netcat, "ezup.dev", 9999, content) 66 | ) 67 | 68 | 69 | async def hpaste(content: str): 70 | resp = await post(f"{BASE}api/v2/paste", data=content) 71 | if not resp["success"]: 72 | return 73 | return BASE + resp["message"] 74 | 75 | 76 | def upload_text(data: str) -> typing.Optional[str]: 77 | passphrase = Random.get_random_bytes(32) 78 | salt = Random.get_random_bytes(8) 79 | key = Protocol.KDF.PBKDF2( 80 | passphrase, salt, 32, 100000, hmac_hash_module=Hash.SHA256 81 | ) 82 | compress = zlib.compressobj(wbits=-15) 83 | paste_blob = ( 84 | compress.compress(json.dumps({"paste": data}, separators=(",", ":")).encode()) 85 | + compress.flush() 86 | ) 87 | cipher = AES.new(key, AES.MODE_GCM) 88 | paste_meta = [ 89 | [ 90 | base64.b64encode(cipher.nonce).decode(), 91 | base64.b64encode(salt).decode(), 92 | 100000, 93 | 256, 94 | 128, 95 | "aes", 96 | "gcm", 97 | "zlib", 98 | ], 99 | "syntaxhighlighting", 100 | 0, 101 | 0, 102 | ] 103 | cipher.update(json.dumps(paste_meta, separators=(",", ":")).encode()) 104 | ct, tag = cipher.encrypt_and_digest(paste_blob) 105 | resp = requests.post( 106 | "https://bin.nixnet.services", 107 | headers={"X-Requested-With": "JSONHttpRequest"}, 108 | data=json.dumps( 109 | { 110 | "v": 2, 111 | "adata": paste_meta, 112 | "ct": base64.b64encode(ct + tag).decode(), 113 | "meta": {"expire": "1week"}, 114 | }, 115 | separators=(",", ":"), 116 | ), 117 | ) 118 | data = resp.json() 119 | url = list(urlparse(urljoin("https://bin.nixnet.services", data["url"]))) 120 | url[5] = base58.b58encode(passphrase).decode() 121 | return urlunparse(url) 122 | -------------------------------------------------------------------------------- /Exon/utils/permissions.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | from functools import wraps 26 | 27 | from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden 28 | from pyrogram.types import Message 29 | 30 | from Exon import DRAGONS, Abishnoi 31 | from Exon.utils.pluginhelp import member_permissions 32 | 33 | 34 | async def authorised(func, subFunc2, client, message, *args, **kwargs): 35 | chatID = message.chat.id 36 | try: 37 | await func(client, message, *args, **kwargs) 38 | except ChatWriteForbidden: 39 | await Abishnoi.leave_chat(chatID) 40 | except Exception as e: 41 | try: 42 | await message.reply_text(str(e)) 43 | except ChatWriteForbidden: 44 | await Abishnoi.leave_chat(chatID) 45 | return subFunc2 46 | 47 | 48 | async def unauthorised(message: Message, permission, subFunc2): 49 | text = f"ʏᴏᴜ ᴅᴏɴ'ᴛ ʜᴀᴠᴇ ᴛʜᴇ ʀᴇǫᴜɪʀᴇᴅ ᴘᴇʀᴍɪssɪᴏɴ ᴛᴏ ᴘᴇʀғᴏʀᴍ ᴛʜɪs ᴀᴄᴛɪᴏɴ.\n**𝐏𝐞𝐫𝐦𝐢𝐬𝐬𝐢𝐨𝐧:** __{permission}__" 50 | chatID = message.chat.id 51 | try: 52 | await message.reply_text(text) 53 | except ChatWriteForbidden: 54 | await Abishnoi.leave_chat(chatID) 55 | return subFunc2 56 | 57 | 58 | def adminsOnly(permission): 59 | def subFunc(func): 60 | @wraps(func) 61 | async def subFunc2(client, message: Message, *args, **kwargs): 62 | chatID = message.chat.id 63 | if not message.from_user: 64 | # For anonymous admins 65 | if message.sender_chat and message.sender_chat.id == message.chat.id: 66 | return await authorised( 67 | func, 68 | subFunc2, 69 | client, 70 | message, 71 | *args, 72 | **kwargs, 73 | ) 74 | return await unauthorised(message, permission, subFunc2) 75 | # For admins and sudo users 76 | userID = message.from_user.id 77 | permissions = await member_permissions(chatID, userID) 78 | if userID not in DRAGONS and permission not in permissions: 79 | return await unauthorised(message, permission, subFunc2) 80 | return await authorised(func, subFunc2, client, message, *args, **kwargs) 81 | 82 | return subFunc2 83 | 84 | return subFunc 85 | -------------------------------------------------------------------------------- /Exon/utils/progress.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | import math 26 | import time 27 | 28 | from .exceptions import CancelProcess 29 | from .tools import humanbytes, time_formatter 30 | 31 | 32 | async def progress( 33 | current, total, gdrive, start, prog_type, file_name=None, is_cancelled=False 34 | ): 35 | now = time.time() 36 | diff = now - start 37 | if is_cancelled is True: 38 | raise CancelProcess 39 | 40 | if round(diff % 10.00) == 0 or current == total: 41 | percentage = current * 100 / total 42 | speed = current / diff 43 | elapsed_time = round(diff) 44 | eta = round((total - current) / speed) 45 | if "upload" in prog_type.lower(): 46 | status = "Uploading" 47 | elif "download" in prog_type.lower(): 48 | status = "Downloading" 49 | else: 50 | status = "Unknown" 51 | progress_str = "`{0}` | [{1}{2}] `{3}%`".format( 52 | status, 53 | "".join("●" for _ in range(math.floor(percentage / 10))), 54 | "".join("○" for _ in range(10 - math.floor(percentage / 10))), 55 | round(percentage, 2), 56 | ) 57 | tmp = ( 58 | f"{progress_str}\n" 59 | f"`{humanbytes(current)} of {humanbytes(total)}" 60 | f" @ {humanbytes(speed)}`\n" 61 | f"`ETA` -> {time_formatter(eta)}\n" 62 | f"`Duration` -> {time_formatter(elapsed_time)}" 63 | ) 64 | await gdrive.edit(f"`{prog_type}`\n\n" f"`Status`\n{tmp}") 65 | -------------------------------------------------------------------------------- /Exon/utils/sections.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2022 ABIAHNOI69 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | """ 24 | 25 | n = "\n" 26 | w = " " 27 | 28 | bold = lambda x: f"**{x}:** " 29 | bold_ul = lambda x: f"**--{x}:**-- " 30 | 31 | mono = lambda x: f"`{x}`{n}" 32 | 33 | 34 | def section( 35 | title: str, 36 | body: dict, 37 | indent: int = 2, 38 | underline: bool = False, 39 | ) -> str: 40 | text = (bold_ul(title) + n) if underline else bold(title) + n 41 | 42 | for key, value in body.items(): 43 | text += ( 44 | indent * w 45 | + bold(key) 46 | + ((value[0] + n) if isinstance(value, list) else mono(value)) 47 | ) 48 | return text 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ᴍʀ. x 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: bash start 2 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## sᴇᴄᴜʀɪᴛʏ ᴘᴏʟɪᴄʏ 2 | 3 | ## sᴜᴘᴘᴏʀᴛᴇᴅ ᴠᴇʀsɪᴏɴs 4 | 5 | ʙᴇʟᴏᴡ ᴛᴀʙʟᴇ shows ᴡʜɪᴄʜ ᴠᴇʀsɪᴏɴ ɪs sᴛᴀʙʟᴇ ᴀɴᴅ sᴇᴄᴜʀɪᴛʏ ᴜᴘᴅᴀᴛᴇᴅ ᴀɴᴅ ᴡʜɪᴄʜ ɪs ɴᴏᴛ 6 | | ᴠᴇʀsɪᴏɴ | sᴜᴘᴘᴏʀᴛᴇᴅ | 7 | | -------| ------------------| 8 | | v2.69 | :white_check_mark: | 9 | 10 | 11 | ## ʀᴇᴘᴏʀᴛɪɴɢ ᴀ ᴠᴜʟɴᴇʀᴀʙɪʟɪᴛʏ 12 | 13 | ɪғ ʏᴏᴜ ᴡᴀɴᴛ ᴛᴏ ʀᴇᴘᴏʀᴛ ᴀ ᴍᴀᴊᴏʀ ᴏʀ ᴍɪɴᴏʀ ᴠᴜʟɴᴇʀᴀʙɪʟɪᴛʏ ғʀᴏᴍ ᴏᴜʀ ᴘʀᴏᴊᴇᴄᴛ? 14 | 15 | ғɪʀsᴛ ᴏғ ᴀʟʟ ɪɴғᴏʀᴍ ᴛʜᴇ ᴏʀɪɢɪɴᴀʟ ᴄʀᴇᴀᴛᴏʀ ᴏғ ᴛʜᴇ ᴘᴀᴄᴋᴀɢᴇ ғʀᴏᴍ PyPi 16 | ᴀɴᴅ ᴛʜᴇɴ ᴍᴀᴋᴇ ᴀ ɪssᴜᴇ ɪɴ ᴏᴜʀ ᴘʀᴏᴊᴇᴄᴛ. 17 | 18 | ## ᴄʀᴇᴅɪᴛ ꜰᴏʀ ᴇxᴏɴ ʀᴏʙᴏᴛ 19 | - [ɢɪᴛʜᴜʙ](https://github.com/AshokShau) 20 | - [ᴛᴇʟᴇɢʀᴀᴍ](https://t.me/AshokShau) 21 | - [ᴄʜᴀᴛ ɢʀᴏᴜᴘ](https://t.me/AbishnoiMF) 22 | 23 | ## ɪɴғᴏ 24 | *ᴛʜɪs ɪs ᴇxᴏɴ ʀᴏʙᴏᴛ ,ᴏᴩᴇɴ sᴏᴜʀᴄᴇ ᴛᴇʟᴇɢʀᴀᴍ ɢʀᴏᴜᴩ ᴍᴀɴᴀɢᴇᴍᴇɴᴛ ʙᴏᴛ.* 25 | 26 | ᴡʀɪᴛᴛᴇɴ ɪɴ ᴩʏᴛʜᴏɴ ᴡɪᴛʜ ᴛʜᴇ ʜᴇʟᴩ ᴏғ : [ᴛᴇʟᴇᴛʜᴏɴ](https://github.com/LonamiWebs/Telethon), 27 | [ᴩʏʀᴏɢʀᴀᴍ](https://github.com/pyrogram/pyrogram), 28 | [ᴩʏᴛʜᴏɴ-ᴛᴇʟᴇɢʀᴀᴍ-ʙᴏᴛ](https://github.com/python-telegram-bot/python-telegram-bot), 29 | ᴀɴᴅ ᴜsɪɴɢ [sǫʟᴀʟᴄʜᴇᴍʏ](https://www.sqlalchemy.org) ᴀɴᴅ [ᴍᴏɴɢᴏ](https://cloud.mongodb.com) ᴀs ᴅᴀᴛᴀʙᴀsᴇ. 30 | 31 | *ʜᴇʀᴇ ɪs ᴍʏ sᴏᴜʀᴄᴇ ᴄᴏᴅᴇ :* [ɢɪᴛʜᴜʙ-ʟɪɴᴋ](https://github.com/AshokShau/ExonRobot) 32 | 33 | 34 | ᴇxᴏɴ ʀᴏʙᴏᴛ ɪs ʟɪᴄᴇɴsᴇᴅ ᴜɴᴅᴇʀ ᴛʜᴇ [ᴍɪᴛ ʟɪᴄᴇɴsᴇ](https://github.com/AshokShau/ExonRobot/blob/master/LICENSE). 35 | 36 | © 2022 - 2023 [@ᴀʙɪsʜɴᴏɪᴍғ](https://t.me/AbishnoiMF), ᴀʟʟ ʀɪɢʜᴛs ʀᴇsᴇʀᴠᴇᴅ 37 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "name": "ᴇxᴏɴᴏʙᴏᴛ", 4 | "description": "Telegram Group Management Bot Written In Python Using python-telegram-bot.", 5 | "repository": "https://github.com/AshokShau/ExonRobot", 6 | "logo": "https://te.legra.ph/file/b0e09aabe796209f01d3d.jpg", 7 | "keywords": [ 8 | "python3", 9 | "telegram", 10 | "bot", 11 | "ExonRobot", 12 | "telegram-bot", 13 | "management", 14 | "ptb", 15 | "pyrogram" 16 | ], 17 | "buildpacks": [ 18 | { 19 | "url": "https://github.com/heroku/heroku-buildpack-python" 20 | }, 21 | { 22 | "url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest" 23 | } 24 | ], 25 | "stack": "heroku-22", 26 | "addons": [ 27 | { 28 | "options": { 29 | "version": "14" 30 | }, 31 | "plan": "heroku-postgresql" 32 | } 33 | ], 34 | "env": { 35 | "API_ID": { 36 | "description": "ɢᴇᴛ ᴛʜɪs ᴠᴀʟᴜᴇ ғʀᴏᴍ my.telegram.org/apps.", 37 | "required": true, 38 | "value": "" 39 | }, 40 | "API_HASH": { 41 | "description": "ɢᴇᴛ ᴛʜɪs ᴠᴀʟᴜᴇ ғʀᴏᴍ my.telegram.org/apps.", 42 | "required": true, 43 | "value": "" 44 | }, 45 | "OWNER_ID": { 46 | "description": "ʏᴏᴜʀ ᴜsᴇʀ ID ᴀs ᴀɴ ɪɴᴛᴇɢᴇʀ.", 47 | "required": true, 48 | "value": "5938660179" 49 | }, 50 | "DEV_USERS": { 51 | "description": "ᴅᴇᴠs ᴜsᴇʀ ID ᴀs ᴀɴ ɪɴᴛᴇɢᴇʀ.", 52 | "required": true, 53 | "value": "5938660179" 54 | }, 55 | "OWNER_USERNAME": { 56 | "description": "ʏᴏᴜʀ ᴛɢ ᴜsᴇʀɴᴀᴍᴇ", 57 | "required": true, 58 | "value": "AshokShau" 59 | }, 60 | "LOGGER_ID": { 61 | "description": "ᴇᴠᴇɴᴛ ʟᴏɢs ᴄʜᴀɴɴᴇʟ ᴛᴏ ɴᴏᴛᴇ ᴅᴏᴡɴ ɪᴍᴘᴏʀᴛᴀɴᴛ ʙᴏᴛ ʟᴇᴠᴇʟ ᴇᴠᴇɴᴛs, ᴇx: '-10023456'", 62 | "required": true, 63 | "value": "-100" 64 | }, 65 | "MONGO_DB_URI": { 66 | "description": "ʀᴇǫᴜɪʀᴇᴅ ғᴏʀ ᴅᴀᴛᴀʙᴀsᴇ ᴄᴏɴɴᴇᴄᴛɪᴏɴs (ᴍᴏɴɢᴏ).", 67 | "required": true, 68 | "value": "mongodb+srv://public:abishnoimf@cluster0.rqk6ihd.mongodb.net/?retryWrites=true&w=majority" 69 | }, 70 | "TOKEN": { 71 | "description": "Get bot token from @BotFather on TG", 72 | "required": true, 73 | "value": "" 74 | } 75 | } 76 | } 77 | 78 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | from os import getenv 2 | 3 | from dotenv import load_dotenv 4 | 5 | load_dotenv() 6 | 7 | 8 | class Config(object): 9 | LOGGER = True 10 | 11 | API_ID = int(getenv("API_ID", 6)) 12 | API_HASH = getenv("API_HASH", None) 13 | ARQ_API_KEY = "PMPTTD-HOMLMF-SRBHNH-RZMWXL-ARQ" 14 | SPAMWATCH_API = None 15 | TOKEN = getenv("TOKEN", None) 16 | OWNER_ID = int(getenv("OWNER_ID", 5938660179)) 17 | OWNER_USERNAME = getenv("OWNER_USERNAME", "AshokShau") 18 | SUPPORT_CHAT = getenv("SUPPORT_CHAT", "AbishnoiMF") 19 | LOGGER_ID = int(getenv("LOGGER_ID", "-1001819078701")) 20 | MONGO_URI = getenv( 21 | "MONGO_DB_URI", 22 | "mongodb+srv://public:abishnoimf@cluster0.rqk6ihd.mongodb.net/?retryWrites=true&w=majority", 23 | ) 24 | DB_NAME = getenv("DB_NAME", "ExonRobot") 25 | REDIS_URL = "redis://default:wK6ZCiclq4iQKYpgfY90v6kd6WdPfEwl@redis-10186.c263.us-east-1-2.ec2.cloud.redislabs.com:10186/default" 26 | DATABASE_URL = getenv("DATABASE_URL", None) 27 | 28 | # ɴᴏ ᴇᴅɪᴛ ᴢᴏɴᴇ 29 | if DATABASE_URL.startswith("postgres://"): 30 | DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://") 31 | 32 | 33 | class Production(Config): 34 | LOGGER = True 35 | 36 | 37 | class Development(Config): 38 | LOGGER = True 39 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "1.0" 2 | services: 3 | worker: 4 | build: . 5 | environment: 6 | APP_ID: $API_ID 7 | API_HASH: $API_HASH 8 | TOKEN: $TOKEN 9 | OWNER_ID: $OWNER_ID 10 | OWNER_USERNAME: $OWNER_USERNAME 11 | DATABASE_URL: $DATABASE_URL 12 | MONGO_URI: $MONGO_DB_URI 13 | -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | run: 5 | worker: bash start 6 | -------------------------------------------------------------------------------- /okteto-pipeline.yml: -------------------------------------------------------------------------------- 1 | icon: https://img.shields.io/github/v/release/AshokShau/ExonRobot?color=black&logo=github&logoColor=black&style=social 2 | deploy: 3 | - okteto stack deploy --build -f docker-compose.yml 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | abg==2.5.3 2 | aiofiles 3 | aiohttp>=3.9.2 4 | httpx[http2]>=0.18.1,<1.0.0 5 | alphabet_detector==0.0.7 6 | beautifulsoup4==4.11.1 7 | bleach==6.1.0 8 | cachetools 9 | configparser==5.3.0 10 | dateparser 11 | emoji==1.7.0 12 | feedparser==6.0.10 13 | ffmpeg-python==0.2.0 14 | future==0.18.3 15 | gitpython==3.1.43 16 | markdown2==2.5.1 17 | multicolorcaptcha==1.2.0 18 | Pillow>=10.2.0 19 | psutil==5.9.8 20 | psycopg2-binary==2.9.10 21 | pyYAML==6.0.2 22 | pyrate-limiter==2.8.5 23 | python-telegram-bot==13.15 24 | requests==2.32.4 25 | spamwatch==0.3.0 26 | speedtest-cli==2.1.3 27 | SQLAlchemy==1.4.44 28 | telethon==1.35.0 29 | ujson==5.8.0 30 | pycryptodome==3.20.0 31 | prettyconf 32 | base58==2.1.1 33 | pytimeparse==1.1.8 34 | SibylSystem==0.0.24 35 | tgcrypto-pyrofork 36 | pyrofork 37 | python-arq==6.0.7 38 | python-dotenv==1.1.1 39 | redis==5.2.0 40 | telegraph==2.2.0 41 | motor 42 | pymongo==4.12.0 43 | odmantic==0.9.2 44 | opencv-python-headless==4.10.0.82 45 | pykeyboard 46 | wget==3.2 47 | wikipedia==1.4.0 48 | bing_image_downloader==1.1.2 49 | lyricsgenius==3.6.0 50 | jikanpy==4.3.2 51 | gtts==2.5.1 52 | search_engine_parser 53 | googletrans==2.4.0 54 | gpytranslate==1.5.1 55 | cloudscraper==1.2.70 56 | carbonnow 57 | pretty_errors 58 | -------------------------------------------------------------------------------- /restart.bat: -------------------------------------------------------------------------------- 1 | start cmd.exe /c start_service.bat 2 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.11.4 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample.env: -------------------------------------------------------------------------------- 1 | API_ID=12334 2 | API_HASH= 3 | TOKEN= 4 | OWNER_ID=5938660179 5 | OWNER_USERNAME=AshokShau 6 | SUPPORT_CHAT=AbishnoiMF 7 | LOGGER_ID=-1001573019550 8 | DEV_USERS=5938660179 9 | MONGO_DB_URI= 10 | DATABASE_URL= 11 | -------------------------------------------------------------------------------- /start: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #git clone $REPO_URL Repo 4 | #cd Repo 5 | #pip3 install -U -r requirements.txt 6 | python3 -m Exon 7 | 8 | -------------------------------------------------------------------------------- /start.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | TITLE Exon bot 3 | :: Enables virtual env mode and then starts Telegram bot 4 | env\scripts\activate.bat && py -m Exon 5 | -------------------------------------------------------------------------------- /start_service.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | :: BatchGotAdmin 4 | :------------------------------------- 5 | REM --> Check for permissions 6 | >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" 7 | 8 | REM --> If error flag set, we do not have admin. 9 | if '%errorlevel%' NEQ '0' ( 10 | echo Requesting administrative privileges... 11 | goto UACPrompt 12 | ) else ( goto gotAdmin ) 13 | 14 | :UACPrompt 15 | echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" 16 | set params = %*:"="" 17 | echo UAC.ShellExecute "cmd.exe", "/c %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" 18 | 19 | "%temp%\getadmin.vbs" 20 | del "%temp%\getadmin.vbs" 21 | exit /B 22 | 23 | :gotAdmin 24 | pushd "%CD%" 25 | CD /D "%~dp0" 26 | :-------------------------------------- 27 | :: your commands begin from this point. 28 | :: stops the service and then starts it 29 | nssm restart Exon 30 | --------------------------------------------------------------------------------