├── .github
├── FUNDING.yml
└── workflows
│ └── pythonapp.yml
├── .gitignore
├── CODE_OF_CONDUCT
├── Dockerfile
├── LICENSE
├── Procfile.txt
├── README.md
├── app.json
├── generate_session_file.py
├── heroku.yml
├── requirements.txt
├── resources
└── MutantAcademyStyle.ttf
├── sample_config.env
├── string_session.py
├── terminal_getstring.sh
├── termux_install.sh
├── userbot
├── __init__.py
├── __main__.py
├── events.py
├── modules
│ ├── __init__.py
│ ├── admin.py
│ ├── adzan.py
│ ├── afk.py
│ ├── android.py
│ ├── anime.py
│ ├── anti_spambot.py
│ ├── aria.py
│ ├── blacklist.py
│ ├── chat.py
│ ├── chatinfo.py
│ ├── covid.py
│ ├── create.py
│ ├── deezload.py
│ ├── direct_links.py
│ ├── dogbin.py
│ ├── evaluators.py
│ ├── fban.py
│ ├── figlet.py
│ ├── filemanager.py
│ ├── filter.py
│ ├── fonts.py
│ ├── gdrive.py
│ ├── getmusic.py
│ ├── github.py
│ ├── hash.py
│ ├── help.py
│ ├── heroku.py
│ ├── invite.py
│ ├── lastfm.py
│ ├── locks.py
│ ├── lyrics.py
│ ├── mega_downloader.py
│ ├── memes.py
│ ├── misc.py
│ ├── multimemes.py
│ ├── nhentai.py
│ ├── notes.py
│ ├── ocr.py
│ ├── pics.py
│ ├── pmpermit.py
│ ├── profile.py
│ ├── purge.py
│ ├── qrcode.py
│ ├── remove_bg.py
│ ├── reverse.py
│ ├── scrapers.py
│ ├── screencapture.py
│ ├── sed.py
│ ├── snips.py
│ ├── spam.py
│ ├── sql_helper
│ │ ├── .DS_Store
│ │ ├── __init__.py
│ │ ├── blacklist_sql.py
│ │ ├── fban_sql.py
│ │ ├── filter_sql.py
│ │ ├── globals.py
│ │ ├── gmute_sql.py
│ │ ├── google_drive_sql.py
│ │ ├── keep_read_sql.py
│ │ ├── lydia_sql.py
│ │ ├── notes_sql.py
│ │ ├── pm_permit_sql.py
│ │ ├── snips_sql.py
│ │ ├── spam_mute_sql.py
│ │ └── welcome_sql.py
│ ├── ssvideo.py
│ ├── stickers.py
│ ├── system_stats.py
│ ├── telegraph.py
│ ├── time.py
│ ├── torrent.py
│ ├── updater.py
│ ├── upload_download.py
│ ├── weather.py
│ ├── welcomes.py
│ ├── whois.py
│ ├── www.py
│ └── zipfile.py
└── utils
│ ├── __init__.py
│ ├── chrome.py
│ ├── exceptions.py
│ ├── google_images_download.py
│ ├── progress.py
│ └── tools.py
└── windows_startup_script.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [MoveAngel] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: [Mina-Project] # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/workflows/pythonapp.yml:
--------------------------------------------------------------------------------
1 | name: FailedChecker
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 | strategy:
10 | max-parallel: 5
11 | matrix:
12 | python-version: [3.8]
13 |
14 | steps:
15 | - uses: actions/checkout@v1
16 | - name: Set up Python ${{ matrix.python-version }}
17 | uses: actions/setup-python@v1
18 | with:
19 | python-version: ${{ matrix.python-version }}
20 | - name: Install dependencies
21 | run: |
22 | sudo apt-get install libpq-dev
23 | python -m pip install --upgrade pip
24 | pip install -r requirements.txt
25 | pip install flake8 flake8-print flake8-quotes
26 | - name: Check for showstoppers
27 | run: |
28 | # stop the build if there are Python syntax errors
29 | flake8 . --count --select=E999 --show-source --statistics
30 |
31 | shellcheck:
32 |
33 | runs-on: ubuntu-latest
34 |
35 | steps:
36 | - uses: actions/checkout@v1
37 | - name: Check for install script errors
38 | uses: ludeeus/action-shellcheck@0.1.0
39 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | config.env
2 | __pycache__/*
3 | userbot.db
4 | userbot.session
5 | userbot.session-journal
6 | userbot/__pycache__/*
7 | userbot/modules/__pycache__/*
8 | userbot/modules/sql_helper/__pycache__/*
9 | .progress
10 | .vscode/*
11 | bin/*
12 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | All participants of RaphielGang are expected to abide by our Code of Conduct,
4 | both online and during in-person events that are hosted and/or associated with RaphielGang.
5 |
6 |
7 | ### The Pledge
8 |
9 | In the interest of fostering an open and welcoming environment, we pledge to make participation
10 | in our project and our community a harassment-free experience for everyone, regardless of age,
11 | body size, disability, ethnicity, gender identity and expression, level of experience,
12 | nationality, personal appearance, race, religion, or sexual identity and orientation.
13 |
14 |
15 | ### The Standards
16 |
17 | Examples of behaviour that contributes to creating a positive environment include:
18 |
19 | * **Be welcoming**: We strive to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, colour, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
20 | * **Be considerate**: Your work will be used by other people, and you in turn will depend on the work of others. Any decision you take will affect users and colleagues, and you should take those consequences into account when making decisions. Remember that we're a world-wide community, so you might not be communicating in someone else's primary language.
21 | * **Be respectful**: Not all of us will agree all the time, but disagreement is no excuse for poor behavior and poor manners. We might all experience some frustration now and then, but we cannot allow that frustration to turn into a personal attack. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one.
22 | * **Gracefully accepting constructive criticism**: Not everyone are perfect, you can get some critism of your works from us, but it's not means that we don't accepting your contribution, we just want you to fixing it and making it better.
23 | * **Referring to people by their preferred pronouns/words**, but we do not have standardized gender-neutral pronouns/words, so your milleage may vary.
24 | * **Do not attack somebody because you have a different opinion** All opinions are accepted as long as they are reasonable, and everyone have right to shouting their opinion.
25 | * **Just chill :D**
26 | * **Don't forget, nobody is perfect, mistakes can be made**
27 | * **Equality is not a privilege, it's a rule!**
28 |
29 | ### Examples of unacceptable behaviour by participants include:
30 |
31 | * **Trolling, insulting/derogatory comments, public or private harassment**
32 | * **Publishing others' private information (Doxing)** such as a physical or electronic address, without explicit permission
33 | * **Not being respectful to reasonable communication boundaries** such as 'leave me alone,' 'go away,' or 'Fuck off.'
34 | * **The usage of sexualised language or imagery and unwelcome sexual attention or advances**
35 | * **Demonstrating the graphics or any other content you know may be considered disturbing**
36 | * **Assuming or promoting any kind of inequality** including but not limited to: age, body size, disability, ethnicity, gender identity and expression, nationality and race, personal appearance, religion, or sexual identity and orientation
37 | * **Drug promotion of any kind**
38 | * **Attacking personal tastes**
39 | * **Other conduct which you know could reasonably be considered inappropriate in a professional setting**
40 |
41 |
42 | ### Enforcement
43 |
44 | Violations of the Code of Conduct may be reported by sending an email to [raphielscape@outlook.com](mailto:raphielscape@outlook.com).
45 | All reports will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
46 | Further details of specific enforcement policies may be posted separately.
47 |
48 | We hold the right and responsibility to remove comments or other contributions that
49 | are not aligned to this Code of Conduct, or to ban temporarily or permanently any members
50 | for other behaviours that they deem inappropriate, threatening, offensive, or harmful.
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM movecrew/one4ubot:alpine-latest
2 |
3 | RUN mkdir /One4uBot && chmod 777 /One4uBot
4 | ENV PATH="/One4uBot/bin:$PATH"
5 | WORKDIR /One4uBot
6 |
7 | RUN git clone https://github.com/MoveAngel/One4uBot -b sql-extended /One4uBot
8 |
9 | #
10 | # Copies session and config(if it exists)
11 | #
12 | COPY ./sample_config.env ./userbot.session* ./config.env* /One4uBot/
13 |
14 | #
15 | # Make open port TCP
16 | #
17 | EXPOSE 80 443
18 |
19 | #
20 | # Finalization
21 | #
22 | CMD ["python3","-m","userbot"]
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | RAPHIELSCAPE PUBLIC LICENSE
2 | Version 1.d, February 2020
3 |
4 | Copyright (C) 2020 Devscapes Open Source Holding GmbH.
5 |
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, and changing it is prohibited.
8 |
9 | RAPHIELSCAPE PUBLIC LICENSE
10 | A-1. DEFINITIONS
11 |
12 | 0. “This License” refers to version 1.d of the Raphielscape Public License.
13 |
14 | 1. “Copyright” also means copyright-like laws that apply to other kinds of works.
15 |
16 | 2. “The Work" refers to any copyrightable work licensed under this License.
17 | Each licensee is addressed as “you”. “Licensees” and “recipients” may be
18 | individuals or organizations.
19 |
20 | 3. To “modify” a work means to copy from or adapt all or part of the work
21 | in a fashion requiring copyright permission, other than the making of
22 | an exact copy. The resulting work is called a “modified version” of
23 | the earlier work or a work “based on” the earlier work.
24 |
25 | 4. Source Form. The “source form” for a work means the preferred form
26 | of the work for making modifications to it. “Object code” means any
27 | non-source form of a work.
28 |
29 | The “Corresponding Source” for a work in object code form means all
30 | the source code needed to generate, install, and (for an executable work)
31 | run the object code and to modify the work, including scripts to control
32 | those activities.
33 |
34 | The Corresponding Source need not include anything that users can
35 | regenerate automatically from other parts of the Corresponding Source.
36 | The Corresponding Source for a work in source code form is that same work.
37 |
38 | 5. "The author" refers to "author" of the code, which is the one that made
39 | the particular code that exists inside of the Corresponding Source.
40 |
41 | 6. "Owner" refers to any parties which are owning the Corresponding Source.
42 |
43 | 7. "Maintainers" refers to any parties which are keeping in existence or
44 | continuance, preserving and retaining The Work and the Corresponding Source.
45 |
46 | 8. “Deprecation” refers to an act of The author and Owner without Maintainers'
47 | agreement to discontinuing the maintainership of The Work.
48 |
49 | 9. "Discontinuation" refers to all Maintainers, The Author, and Owner to
50 | discontinuing the maintainership of The Work.
51 |
52 | 10. "Upstream" refers to the place or site where The Work and the
53 | Corresponding Source getting worked on and where all Maintainers,
54 | The Author, and Owner keeping the existence, continuance, preservation,
55 | and retainment of The Work and Corresponding Source.
56 |
57 | A-2. TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
58 |
59 | 0. You must give any other recipients of the Work or Derivative
60 | Works a copy of this License; and
61 |
62 | 1. You must cause any modified files to carry prominent notices
63 | stating that You changed the files; and
64 |
65 | 2. You must retain, in the Source form of any Derivative Works
66 | that You distribute, this license, all copyright, patent, trademark,
67 | authorships, and attribution notices from the Source form of the Work; and
68 |
69 | 3. You must cause the maintainers of the works to democratically
70 | selecting the new Owner in case of Deprecation with the Signoffs from
71 | all Maintainers and final Signoff from The Author of The Work and the
72 | Corresponding Source.
73 |
74 | If the works are Discontinued, the Owner should archive The Work and
75 | the Corresponding Source or optionally removing The Work entirely and
76 | may stop the distribution of The Work and the Corresponding Source.
77 |
78 | The Owner or The Author may give The Work or the Corresponding Source
79 | to a specific person for a new maintainership structure in case
80 | The Owner, Author, and The Maintainers failed to democratically
81 | selecting a new Owner to continuing, preserving and retaining
82 | The Work and the Corresponding Source; and
83 |
84 | 4. Respecting the author and owner of works that are distributed in
85 | any way. In the means that decisions that are taken by Upstream are
86 | immediately imposed on both Upstream and Modified Version of
87 | The Works and Corresponding Source.
88 |
89 | Any use, reproduction, or distribution of Your modifications, or
90 | for any such Derivative Works as a whole, provided Your use, reproduction,
91 | and distribution of the Work should comply with the conditions stated in
92 | this License.
93 |
94 | B. DISCLAIMER OF WARRANTY
95 |
96 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
97 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
98 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
99 | ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
100 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
105 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106 |
107 |
108 | C. REVISED VERSION OF THIS LICENSE
109 |
110 | The Devscapes Open Source Holding GmbH. may publish revised and/or new versions
111 | of the Raphielscape Public License from time to time. Such new versions will be
112 | similar in spirit to the present version but may differ in detail to address new
113 | problems or concerns.
114 |
115 | Each version is given a distinguishing version number. If the Program specifies
116 | that a certain numbered version of the Raphielscape Public License
117 | "or any later version" applies to it, you have the option of following the terms
118 | and conditions either of that numbered version or of any later version published
119 | by the Devscapes Open Source Holding GmbH. If the Program does not specify a
120 | version number of the Raphielscape Public License, you may use the latest version
121 | published by the Devscapes Open Source Holding GmbH.
122 |
123 | END OF LICENSE
--------------------------------------------------------------------------------
/Procfile.txt:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | worker: Dockerfile
4 | run:
5 | worker: python3 -m userbot
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # One4uBot userbot project
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 
16 |
17 | ```
18 | #include
19 | /**
20 | Your Telegram account may get banned.
21 | I am not responsible for any improper use of this bot
22 | This bot is intended for the purpose of having fun with memes,
23 | as well as efficiently managing groups.
24 | You ended up spamming groups, getting reported left and right,
25 | and you ended up in a Finale Battle with Telegram and at the end
26 | Telegram Team deleted your account?
27 | And after that, then you pointed your fingers at us
28 | for getting your acoount deleted?
29 | I will be rolling on the floor laughing at you.
30 | /**
31 | ```
32 |
33 | ## Generate String Session
34 | Easy way to get STRING_SESSION. Click the button and then click button colored green in top 'Run'
35 |
36 | ### Run on repl.it
37 | [](https://repl.it/@MoveAngel/UserbotSession?lite=1&outputonly=1)
38 |
39 | ### or Run on your terminal
40 | ```
41 | wget https://raw.githubusercontent.com/MoveAngel/One4uBot/sql-extended/terminal_getstring.sh && bash terminal_getstring.sh
42 | ```
43 |
44 | ## How To Host?
45 |
46 | The easiest way to deploy this great bot! is click on button below.
47 | Make sure you have an account of heroku and follow all the steps required.
48 |
49 |
50 |
51 | For further guide you can head to [Groups and Support](https://github.com/MoveAngel/One4uBot#Groups-and-Support) or read this [guide](https://telegra.ph/How-to-host-a-Telegram-Userbot-07-01-2)
52 |
53 | ## Groups and Support
54 |
55 | if you want new features, or announcements, you can follow our [UserbotIndo Channel](https://t.me/userbotindocloud).
56 |
57 | For discussion, bug reporting, and help, you can join [UserbotIndo Support Group](https://t.me/userbotindo).
58 |
59 | ## Credits
60 |
61 | Thanks:
62 | * [RaphielGang](https://github.com/RaphielGang) - Telegram-Paperplane
63 | * [AvinashReddy3108](https://github.com/AvinashReddy3108) - PaperplaneExtended
64 | * [kandnub](https://github.com/kandnub) - TG-UserBot
65 | * [AdekMaulana](https://github.com/adekmaulana) - ProjectBish
66 | * [Mr.Miss](https://github.com/keselekpermen69) - Userbutt
67 | * [GengKapak](https://github.com/GengKapak) - DCLXVI
68 | * [Mkaraniya](https://github.com/mkaraniya) & [Dev73](https://github.com/Devp73) - OpenUserBot
69 |
70 | and many more people who aren't mentioned here, but may be found in [Contributors](https://github.com/MoveAngel/One4uBot/graphs/contributors).
71 |
72 | ## License
73 |
74 | This userbot licensed on [Raphielscape Public License](https://github.com/MoveAngel/One4uBot/blob/sql-extended/LICENSE) - Version 1.d, February 2020
--------------------------------------------------------------------------------
/generate_session_file.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # This script wont run your bot, it just generates a session.
7 |
8 | from telethon import TelegramClient
9 | from dotenv import load_dotenv
10 | import os
11 |
12 | load_dotenv("config.env")
13 |
14 | API_KEY = os.environ.get("API_KEY", None)
15 | API_HASH = os.environ.get("API_HASH", None)
16 |
17 | bot = TelegramClient('userbot', API_KEY, API_HASH)
18 | bot.start()
19 |
--------------------------------------------------------------------------------
/heroku.yml:
--------------------------------------------------------------------------------
1 | build:
2 | docker:
3 | worker: Dockerfile
4 | run:
5 | worker: python3 -m userbot
6 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiohttp
2 | aria2p
3 | async_generator
4 | bs4
5 | cowpy
6 | cffi
7 | coffeehouse
8 | covid
9 | cryptg
10 | dnspython
11 | deezloader
12 | emoji
13 | gitpython
14 | glitch_this
15 | google-api-python-client
16 | google-auth-httplib2
17 | google-auth-oauthlib
18 | google_images_download
19 | google_trans_new
20 | gTTS
21 | gTTS-token
22 | hachoir
23 | heroku3
24 | html_telegraph_poster
25 | httplib2
26 | humanize
27 | jikanpy
28 | lxml
29 | lyricsgenius
30 | oauth2client
31 | pendulum
32 | Pillow
33 | psutil
34 | psycopg2
35 | psycopg2-binary
36 | pybase64
37 | pyfiglet
38 | pylast
39 | pySmartDL
40 | python-barcode
41 | python-dotenv
42 | youtube-dl
43 | pytz
44 | qrcode
45 | redis
46 | requests
47 | search-engine-parser
48 | speedtest-cli
49 | sqlalchemy
50 | TgCrypto
51 | telethon
52 | telethon-session-sqlalchemy
53 | telegraph
54 | urbandict
55 | wikipedia
56 | PyGithub
57 | python-dateutil
58 | vcsi
59 | youtube_search
60 |
--------------------------------------------------------------------------------
/resources/MutantAcademyStyle.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoveAngel/One4uBot/e153f632feb419bbc93909198e809c513cd0e988/resources/MutantAcademyStyle.ttf
--------------------------------------------------------------------------------
/sample_config.env:
--------------------------------------------------------------------------------
1 | # Remove this line first before doing anything
2 | ___________PLOX_______REMOVE_____THIS_____LINE__________=True
3 |
4 | # Get these from https://my.telegram.org/
5 | API_KEY = "YOUR API KEY"
6 | API_HASH = "YOUR API HASH"
7 |
8 | # OpenWeather Map API Key for .weather command
9 | # Get from https://openweathermap.org/
10 | OPEN_WEATHER_MAP_APPID = ""
11 | WEATHER_DEFCITY = ""
12 | WEATHER_DEFLANG = ""
13 |
14 | # Location of ChromeDriver for .carbon module
15 | # Example for Linux Machines : "/usr/bin/chromedriver"
16 | CHROME_DRIVER = ""
17 |
18 | # Get this value by running python3 string_session.py locally
19 | STRING_SESSION = ""
20 |
21 | # Headless GoogleChrome location for .carbon module
22 | # Example for Linux Machines : "/usr/bin/chromium-browser"
23 | GOOGLE_CHROME_BIN = ""
24 |
25 | # OCR Space API Key for .ocr command
26 | # Get from https://ocr.space/ocrapi
27 | OCR_SPACE_API_KEY = ""
28 |
29 | # remove.bg API Key for .rbg command
30 | # Get from https://www.remove.bg/api
31 | REM_BG_API_KEY = ""
32 |
33 | # ChatID for the Log group
34 | # Add a Hypen or a Negative Sign before ID
35 | # This is a integer, Please don't use Strings
36 | BOTLOG_CHATID = # this is an integer, please don't use quotes.
37 |
38 | # Incase you want to turn off logging, put this to false
39 | BOTLOG = False
40 |
41 | # Set this to True if you want the error logs to be stored in
42 | # the userbot log, rather than spamming other chats with it.
43 | # Note that this requires a valid BOTLOG_CHATID to be set.
44 | LOGSPAMMER = False
45 |
46 | # If you need Verbosity on the Logging
47 | CONSOLE_LOGGER_VERBOSE = False
48 |
49 | # PM Auto-Ban Feature Switch
50 | PM_AUTO_BAN = False
51 |
52 | # Custom Default name for .alive
53 | ALIVE_NAME = ""
54 |
55 | # Your Database URL
56 | # Example: 'postgres://userbot:userbot@localhost:5432/userbot'
57 | DATABASE_URL = ""
58 |
59 | # YouTube Data API Key for .yt command
60 | # Get from https://console.cloud.google.com
61 | YOUTUBE_API_KEY = ""
62 |
63 | # Country and Time Zone setup for
64 | # .time and .date modules
65 | COUNTRY = ""
66 | TZ_NUMBER = # this is an integer, please don't use quotes.
67 |
68 | # Google Drive Credentials
69 | # for .gdrive module.
70 | # Get from https://console.cloud.google.com
71 | G_DRIVE_CLIENT_ID = ""
72 | G_DRIVE_CLIENT_SECRET = ""
73 | G_DRIVE_AUTH_TOKEN_DATA = ""
74 | TEMP_DOWNLOAD_DIRECTORY = ""
75 |
76 | # You have to have your own unique two values for API_KEY and API_SECRET
77 | # Obtain yours from https://www.last.fm/api/account/create for Last.fm
78 | LASTFM_API = ""
79 | LASTFM_SECRET = ""
80 | LASTFM_USERNAME = "Your last.fm username"
81 | LASTFM_PASSWORD = "Your last.fm password"
82 |
83 | # Bot will add before song name. For last.fm module.
84 | # Example: GitHub: MacTavishAO : Skillet - Feel Invincible
85 | BIO_PREFIX = ""
86 |
87 | # default bio message
88 | DEFAULT_BIO = ""
89 |
90 | # FOR Lydia Access
91 | LYDIA_API_KEY = ""
92 | LYDIA_ANTI-PM = ""
93 |
94 |
95 | # Report or kick some known spammer bots after
96 | # they joins
97 | ANTI_SPAMBOT = False
98 | ANTI_SPAMBOT_SHOUT = False
99 |
100 | # Wolfram ID
101 | # Get an API KEY from products.wolframalpha.com/api/
102 | WOLFRAM_ID=""
103 |
--------------------------------------------------------------------------------
/string_session.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8-*-
3 | #
4 | # (c) https://t.me/TelethonChat/37677 and SpEcHiDe
5 | #
6 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
7 | # you may not use this file except in compliance with the License.
8 | #
9 |
10 | from telethon.sync import TelegramClient
11 | from telethon.sessions import StringSession
12 |
13 | print("""Please go-to my.telegram.org
14 | Login using your Telegram account
15 | Click on API Development Tools
16 | Create a new application, by entering the required details
17 | Check your Telegram saved messages section to copy the STRING_SESSION""")
18 | API_KEY = int(input("Enter API_KEY here: "))
19 | API_HASH = input("Enter API_HASH here: ")
20 |
21 | with TelegramClient(StringSession(), API_KEY, API_HASH) as client:
22 | print("Check your Telegram Saved Messages to copy the STRING_SESSION value")
23 | session_string = client.session.save()
24 | saved_messages_template = """Support: @userbotindo
25 |
26 | STRING_SESSION: {}
27 |
28 | ⚠️ Please be carefull to pass this value to third parties""".format(session_string)
29 | client.send_message("me", saved_messages_template, parse_mode="html")
30 |
--------------------------------------------------------------------------------
/terminal_getstring.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright (C) 2020 KeselekPermen69
4 | #
5 | # SPDX-License-Identifier: GPL-3.0-or-later
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | export LANG=C.UTF-8
20 |
21 | echo -e "\nChecking dependencies...\n"
22 |
23 | if command -v python3 >/dev/null 2>&1 ; then
24 | echo -e "python3 found "
25 | echo -e "version: $(python3 -V)"
26 | else
27 | echo -e "python not found "
28 | if [ "$(command -v pkg)" != "" ]; then
29 | arr+=(python ) #termux python3 is in python
30 | else
31 | arr+=(python3 )
32 | fi
33 | fi
34 |
35 | sleep 1
36 |
37 | if command -v wget >/dev/null 2>&1 ; then
38 | echo -e "\nwget found\n"
39 | else
40 | echo -e "\nwget not found\n"
41 | arr+=(wget )
42 | fi
43 |
44 | DEPENDENCIES=${arr[@]}
45 | sleep 1
46 |
47 | if [ ! -z "$DEPENDENCIES" ]; then
48 | echo -e "\nInstalling required dependencies\n"
49 | sleep 1
50 |
51 | if [ "$(command -v pkg)" != "" ]; then # termux
52 | pkg install "$DEPENDENCIES" -y
53 |
54 | elif [ "$(command -v apt-get)" != "" ]; then # debian
55 | sudo apt-get install "$DEPENDENCIES" -y
56 |
57 | elif [ "$(command -v pacman)" != "" ]; then # arch
58 | sudo pacman -S "$DEPENDENCIES" -y
59 |
60 | # Free to PR to add others
61 | else
62 | echo -e "\nDistro not supported \nInstall this packages yourself: $DEPENDENCIES\n"
63 | fi
64 |
65 | else
66 | echo -e "\nDependencies have been installed. \nContinuing to install python packages(PyPI)\n"
67 | sleep 1
68 | fi
69 |
70 | echo -e "\nUpgrading python pip\n"
71 | pip3 install --upgrade pip setuptools
72 | echo -e "\nInstalling telethon...\n"
73 | pip3 install telethon
74 | sleep 2
75 |
76 | if [ ! -e string_session.py ]; then
77 | echo -e "\nDownloading string_session.py\n"
78 | wget https://raw.githubusercontent.com/MoveAngel/One4uBot/sql-extended/string_session.py
79 |
80 | echo -e "\nRunning script...\n"
81 | sleep 1
82 | python3 string_session.py
83 | else
84 | echo -e "\nstring_session.py detected... \nrunning file\n"
85 | sleep 1
86 | python3 string_session.py
87 | fi
88 |
89 | echo -e "Do you want to cleanup your file?"
90 | echo -e "[1] cleanup: this delete string_session.py and this file"
91 | echo -e "[2] exit"
92 | echo -ne "\nEnter your choice[1-2]: "
93 | read choice
94 | if [ "$choice" = "1" ]; then
95 | echo -e "Cleanup: removing file"
96 | rm -f string_session.py terminal_getstring.sh
97 | elif [ "$choice" = "2" ]; then
98 | exit
99 | fi
--------------------------------------------------------------------------------
/termux_install.sh:
--------------------------------------------------------------------------------
1 | clear
2 | echo -E " ******,*,. ... "
3 | echo -E " /////*****,*... . . "
4 | echo -E " . . /((//*/*,*///*. . .. "
5 | echo -E ".. . . .((*,,. .*//*. . . . .. "
6 | echo -E ". . ../(((**((//,,/.......... .. .. .. "
7 | echo -E ". . . ./(/, ., , . . ...... "
8 | echo -E "..,,.... .. .. . **//*/*/*.... . . ...*,. "
9 | echo -E " .,,,..,,,.,...... //((/. /**,. ... .. .....,*,** "
10 | echo -E " /(/(*,/// ..,,,,,,,.,,,,,,,,*, "
11 | echo -E ". ((((((/ ., . ..**** "
12 | echo -E "....... */(##//((/ ,.*, ..... .,,,*** "
13 | echo -E "......................../((##(((###( .,.,. ,.... . ,.,*/ "
14 | echo -E " ...*, *,,...,//(((((((####(((*,.**.. **, ,*/***((# "
15 | echo -E " *((/,***(((((((((####((//*/*,,**(//(//(//((((( "
16 | echo -E " .(/ ,(#((((###((((((((#((/(#(*(#/(*((/((((.*,(//// "
17 | echo -E " (((//(( (###(((((/(##(*/((.(#/##((((((/**(/(#*( "
18 | echo -E "/////**/ /((//,*,,../(/,((((/((#(##/(*(/#%#(((/(((/. *****/ "
19 | echo -E " .*////(/((/(/*,**/((((##((//.,####/((#(#%#(((((((/ , .**** "
20 | echo -E ". /(//(#( (#(#(*,/#(#/#####%##(((((((/(////*, "
21 | echo -E "........ ((/((#( /((#(((/ /((#/###%%%#(((/(((//////(( "
22 | echo -E "........./((#(#*.... ((,(((((# /((#((#%%%/* **((. . .., "
23 | echo -E "........./((#(/(.......((((((///(/*((#((%%%%%##(((,*/. , . "
24 | echo -E "........./((((((......*###(((/(/*(# ####%%%%#(.*((..,. "
25 | echo -E ".........((####(......(#(##.(#(((,*((.#%%%%##(*((/..,,*. "
26 | echo -E "//(/***,*(###(//,,..,///#/(. /(((/((((*#%%##(/(,,,.. "
27 | echo -E "**/**,,,,####(/**//((////(##(.*..*((/*##%%%(((,/ .,/ . "
28 | echo -E ",,,,,,,,,#####%(,*///////(((((/(((((((###%##//*., ,/. "
29 | echo -E ",,,,,,,,,#####%(,,,,///((((((///*.,.. (##((((#/(*///*.. "
30 | echo -E " "
31 | sleep 5
32 | clear
33 |
34 | pkg update && pkg upgrade -y
35 | pkg install clang curl git libcrypt libffi libiconv libjpeg* libjpeg-turbo libwebp libxml2 libxslt make ndk-sysroot openssl postgresql python readline wget zlib -y
36 |
37 | git clone https://github.com/mkaraniya/OpenUserBot.git
38 | cd OpenUserBot
39 |
40 | pip install --upgrade pip setuptools
41 | pip install -r requirements.txt
42 |
43 | mv sample_config.env config.env
44 |
45 | mkdir -p $PREFIX/var/lib/postgresql
46 | initdb $PREFIX/var/lib/postgresql
47 | pg_ctl -D $PREFIX/var/lib/postgresql start
48 | createdb botdb
49 | createuser botuser
50 |
51 | cd ..
52 | echo "pg_ctl -D $PREFIX/var/lib/postgresql start" > startbot.sh
53 | echo "cd OpenUserBot" >> startbot.sh
54 | echo "python3 -m userbot" >> startbot.sh
55 | chmod 755 startbot.sh
56 |
57 | echo "Done."
58 | echo "Now edit config.env with nano or anything you want, then run the userbot with startbot.sh"
59 | echo "Please edit the db to postgresql://botuser:@localhost:5432/botdb"
60 | echo "Good luck!"
61 |
--------------------------------------------------------------------------------
/userbot/__main__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot start point """
7 |
8 | from importlib import import_module
9 | from sys import argv
10 |
11 | from telethon.errors.rpcerrorlist import PhoneNumberInvalidError
12 | from userbot import LOGS, bot
13 | from userbot.modules import ALL_MODULES
14 |
15 |
16 | INVALID_PH = '\nERROR: The Phone No. entered is INVALID' \
17 | '\n Tip: Use Country Code along with number.' \
18 | '\n or check your phone number and try again !'
19 |
20 | try:
21 | bot.start()
22 | except PhoneNumberInvalidError:
23 | print(INVALID_PH)
24 | exit(1)
25 |
26 | for module_name in ALL_MODULES:
27 | imported_module = import_module("userbot.modules." + module_name)
28 |
29 | LOGS.info("You are running One4uBot [v3.7]")
30 |
31 | LOGS.info(
32 | "Congratulations, your userbot is now running !! Test it by typing .alive / .on in any chat."
33 | "If you need assistance, head to https://t.me/userbotindo")
34 |
35 | if len(argv) not in (1, 3, 4):
36 | bot.disconnect()
37 | else:
38 | bot.run_until_disconnected()
39 |
--------------------------------------------------------------------------------
/userbot/events.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module for managing events.
7 | One of the main components of the userbot. """
8 |
9 | import sys
10 | from asyncio import create_subprocess_shell as asyncsubshell
11 | from asyncio import subprocess as asyncsub
12 | from os import remove
13 | from time import gmtime, strftime
14 | from traceback import format_exc
15 |
16 | from telethon import events
17 |
18 | from userbot import LOGSPAMMER, bot
19 |
20 |
21 | def register(**args):
22 | """ Register a new event. """
23 | pattern = args.get('pattern', None)
24 | disable_edited = args.get('disable_edited', False)
25 | ignore_unsafe = args.get('ignore_unsafe', False)
26 | unsafe_pattern = r'^[^/!#@\$A-Za-z]'
27 | groups_only = args.get('groups_only', False)
28 | trigger_on_fwd = args.get('trigger_on_fwd', False)
29 | disable_errors = args.get('disable_errors', False)
30 | insecure = args.get('insecure', False)
31 |
32 | if pattern is not None and not pattern.startswith('(?i)'):
33 | args['pattern'] = '(?i)' + pattern
34 |
35 | if "disable_edited" in args:
36 | del args['disable_edited']
37 |
38 | if "ignore_unsafe" in args:
39 | del args['ignore_unsafe']
40 |
41 | if "groups_only" in args:
42 | del args['groups_only']
43 |
44 | if "disable_errors" in args:
45 | del args['disable_errors']
46 |
47 | if "trigger_on_fwd" in args:
48 | del args['trigger_on_fwd']
49 |
50 | if "insecure" in args:
51 | del args['insecure']
52 |
53 | if pattern:
54 | if not ignore_unsafe:
55 | args['pattern'] = pattern.replace('^.', unsafe_pattern, 1)
56 |
57 | def decorator(func):
58 | async def wrapper(check):
59 | if check.edit_date and check.is_channel and not check.is_group:
60 | # Messages sent in channels can be edited by other users.
61 | # Ignore edits that take place in channels.
62 | return
63 | if not LOGSPAMMER:
64 | check.chat_id
65 | else:
66 | pass
67 |
68 | if not trigger_on_fwd and check.fwd_from:
69 | return
70 |
71 | if groups_only and not check.is_group:
72 | await check.respond("`I don't think this is a group.`")
73 | return
74 |
75 | if check.via_bot_id and not insecure and check.out:
76 | return
77 |
78 | try:
79 | await func(check)
80 |
81 | # Thanks to @kandnub for this HACK.
82 | # Raise StopPropagation to Raise StopPropagation
83 | # This needed for AFK to working properly
84 |
85 | except events.StopPropagation:
86 | raise events.StopPropagation
87 | # This is a gay exception and must be passed out. So that it doesnt
88 | # spam chats
89 | except KeyboardInterrupt:
90 | pass
91 | except BaseException:
92 |
93 | # Check if we have to disable it.
94 | # If not silence the log spam on the console,
95 | # with a dumb except.
96 |
97 | if not disable_errors:
98 | date = strftime("%Y-%m-%d %H:%M:%S", gmtime())
99 |
100 | text = "**USERBOT ERROR REPORT**\n"
101 | link = "[Userbot Indo Support](https://t.me/userbotindo)"
102 | text += "If you want to, you can report it"
103 | text += f". Head and forward this message to {link}.\n"
104 | text += "Nothing is logged except the fact of error and date\n"
105 |
106 | ftext = "========== DISCLAIMER =========="
107 | ftext += "\nThis file uploaded ONLY here,"
108 | ftext += "\nwe logged only fact of error and date,"
109 | ftext += "\nwe respect your privacy,"
110 | ftext += "\nyou may not report this error if you've"
111 | ftext += "\nany confidential data here, no one will see your data\n"
112 | ftext += "================================\n\n"
113 | ftext += "--------BEGIN USERBOT TRACEBACK LOG--------\n"
114 | ftext += "\nDate: " + date
115 | ftext += "\nChat ID: " + str(check.chat_id)
116 | ftext += "\nSender ID: " + str(check.sender_id)
117 | ftext += "\n\nEvent Trigger:\n"
118 | ftext += str(check.text)
119 | ftext += "\n\nTraceback info:\n"
120 | ftext += str(format_exc())
121 | ftext += "\n\nError text:\n"
122 | ftext += str(sys.exc_info()[1])
123 | ftext += "\n\n--------END USERBOT TRACEBACK LOG--------"
124 |
125 | command = "git log --pretty=format:\"%an: %s\" -10"
126 |
127 | ftext += "\n\n\nLast 10 commits:\n"
128 |
129 | process = await asyncsubshell(command,
130 | stdout=asyncsub.PIPE,
131 | stderr=asyncsub.PIPE)
132 | stdout, stderr = await process.communicate()
133 | result = str(stdout.decode().strip()) \
134 | + str(stderr.decode().strip())
135 |
136 | ftext += result
137 |
138 | file = open("error.log", "w+")
139 | file.write(ftext)
140 | file.close()
141 |
142 | # if LOGSPAMMER:
143 | # await check.respond(
144 | # "`Sorry, my userbot has crashed.\
145 | # \nThe error logs are stored in the userbot's log chat.`"
146 | # )
147 |
148 | # await check.client.send_file(send_to,
149 | # "error.log",
150 | # caption=text)
151 | remove("error.log")
152 | else:
153 | pass
154 |
155 | if not disable_edited:
156 | bot.add_event_handler(wrapper, events.MessageEdited(**args))
157 | bot.add_event_handler(wrapper, events.NewMessage(**args))
158 | return wrapper
159 |
160 | return decorator
161 |
--------------------------------------------------------------------------------
/userbot/modules/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Init file which loads all of the modules """
7 | from userbot import LOGS
8 |
9 |
10 | def __list_all_modules():
11 | import glob
12 | from os.path import basename, dirname, isfile
13 |
14 | mod_paths = glob.glob(dirname(__file__) + "/*.py")
15 | all_modules = [
16 | basename(f)[:-3]
17 | for f in mod_paths
18 | if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py")
19 | ]
20 | return all_modules
21 |
22 |
23 | ALL_MODULES = sorted(__list_all_modules())
24 | LOGS.info("Modules to load: %s", str(ALL_MODULES))
25 | __all__ = ALL_MODULES + ["ALL_MODULES"]
26 |
--------------------------------------------------------------------------------
/userbot/modules/adzan.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import requests
4 |
5 | from userbot import CMD_HELP
6 | from userbot.events import register
7 |
8 | PLACE = ""
9 |
10 |
11 | @register(pattern="^.adzan(?: |$)(.*)")
12 | async def get_adzan(adzan):
13 | if not adzan.pattern_match.group(1):
14 | LOCATION = PLACE
15 | if not LOCATION:
16 | await adzan.edit("Please specify a city or a state.")
17 | return
18 | else:
19 | LOCATION = adzan.pattern_match.group(1)
20 |
21 | # url = f'http://muslimsalat.com/{LOKASI}.json?key=bd099c5825cbedb9aa934e255a81a5fc'
22 | url = f"https://api.pray.zone/v2/times/today.json?city={LOCATION}"
23 | request = requests.get(url)
24 | if request.status_code == 500:
25 | return await adzan.edit(f"Couldn't find city `{LOCATION}`")
26 |
27 | parsed = json.loads(request.text)
28 |
29 | city = parsed["results"]["location"]["city"]
30 | country = parsed["results"]["location"]["country"]
31 | timezone = parsed["results"]["location"]["timezone"]
32 | date = parsed["results"]["datetime"][0]["date"]["gregorian"]
33 |
34 | imsak = parsed["results"]["datetime"][0]["times"]["Imsak"]
35 | subuh = parsed["results"]["datetime"][0]["times"]["Fajr"]
36 | zuhur = parsed["results"]["datetime"][0]["times"]["Dhuhr"]
37 | ashar = parsed["results"]["datetime"][0]["times"]["Asr"]
38 | maghrib = parsed["results"]["datetime"][0]["times"]["Maghrib"]
39 | isya = parsed["results"]["datetime"][0]["times"]["Isha"]
40 |
41 | result = (
42 | f"**Jadwal Sholat**:\n"
43 | f"📅 `{date} | {timezone}`\n"
44 | f"📍 `{city} | {country}`\n\n"
45 | f"**Imsak :** `{imsak}`\n"
46 | f"**Subuh :** `{subuh}`\n"
47 | f"**Zuhur :** `{zuhur}`\n"
48 | f"**Ashar :** `{ashar}`\n"
49 | f"**Maghrib :** `{maghrib}`\n"
50 | f"**Isya :** `{isya}`\n"
51 | )
52 |
53 | await adzan.edit(result)
54 |
55 |
56 | CMD_HELP.update(
57 | {
58 | "adzan": ".adzan \
59 | \nUsage: Gets the prayer time for moslem."
60 | }
61 | )
62 |
--------------------------------------------------------------------------------
/userbot/modules/blacklist.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port From UniBorg to UserBot by keselekpermen69
7 |
8 | import io
9 | import re
10 |
11 | import userbot.modules.sql_helper.blacklist_sql as sql
12 | from userbot import CMD_HELP
13 | from userbot.events import register
14 |
15 |
16 | @register(incoming=True, disable_edited=True, disable_errors=True)
17 | async def on_new_message(event):
18 | # TODO: exempt admins from locks
19 | name = event.raw_text
20 | snips = sql.get_chat_blacklist(event.chat_id)
21 | for snip in snips:
22 | pattern = r"( |^|[^\w])" + re.escape(snip) + r"( |$|[^\w])"
23 | if re.search(pattern, name, flags=re.IGNORECASE):
24 | try:
25 | await event.delete()
26 | except Exception:
27 | await event.reply("I do not have DELETE permission in this chat")
28 | sql.rm_from_blacklist(event.chat_id, snip.lower())
29 | break
30 |
31 |
32 | @register(outgoing=True, pattern="^.addbl(?: |$)(.*)")
33 | async def on_add_black_list(addbl):
34 | text = addbl.pattern_match.group(1)
35 | to_blacklist = list(
36 | set(trigger.strip() for trigger in text.split("\n") if trigger.strip())
37 | )
38 | for trigger in to_blacklist:
39 | sql.add_to_blacklist(addbl.chat_id, trigger.lower())
40 | await addbl.edit(
41 | "Added {} triggers to the blacklist in the current chat".format(
42 | len(to_blacklist)
43 | )
44 | )
45 |
46 |
47 | @register(outgoing=True, pattern="^.listbl(?: |$)(.*)")
48 | async def on_view_blacklist(listbl):
49 | all_blacklisted = sql.get_chat_blacklist(listbl.chat_id)
50 | OUT_STR = "Blacklists in the Current Chat:\n"
51 | if len(all_blacklisted) > 0:
52 | for trigger in all_blacklisted:
53 | OUT_STR += f"`{trigger}`\n"
54 | else:
55 | OUT_STR = "No BlackLists. Start Saving using `.addbl`"
56 | if len(OUT_STR) > 4096:
57 | with io.BytesIO(str.encode(OUT_STR)) as out_file:
58 | out_file.name = "blacklist.text"
59 | await listbl.client.send_file(
60 | listbl.chat_id,
61 | out_file,
62 | force_document=True,
63 | allow_cache=False,
64 | caption="BlackLists in the Current Chat",
65 | reply_to=listbl,
66 | )
67 | await listbl.delete()
68 | else:
69 | await listbl.edit(OUT_STR)
70 |
71 |
72 | @register(outgoing=True, pattern="^.rmbl(?: |$)(.*)")
73 | async def on_delete_blacklist(rmbl):
74 | text = rmbl.pattern_match.group(1)
75 | to_unblacklist = list(
76 | set(trigger.strip() for trigger in text.split("\n") if trigger.strip())
77 | )
78 | successful = 0
79 | for trigger in to_unblacklist:
80 | if sql.rm_from_blacklist(rmbl.chat_id, trigger.lower()):
81 | successful += 1
82 | await rmbl.edit(f"Removed {successful} / {len(to_unblacklist)} from the blacklist")
83 |
84 |
85 | CMD_HELP.update(
86 | {
87 | "blacklist": ".listbl\
88 | \nUsage: Lists all active userbot blacklist in a chat.\
89 | \n\n.addbl \
90 | \nUsage: Saves the message to the 'blacklist keyword'.\
91 | \nThe bot will delete to the message whenever 'blacklist keyword' is mentioned.\
92 | \n\n.rmbl \
93 | \nUsage: Stops the specified blacklist.\
94 | \n btw you need permissions **Delete Messages** of admin."
95 | }
96 | )
97 |
--------------------------------------------------------------------------------
/userbot/modules/chat.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module containing userid, chatid and log commands"""
7 |
8 | from asyncio import sleep
9 |
10 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP, bot
11 | from userbot.events import register
12 | from userbot.modules.admin import get_user_from_event
13 |
14 |
15 | @register(outgoing=True, pattern="^.userid$")
16 | async def useridgetter(target):
17 | """ For .userid command, returns the ID of the target user. """
18 | message = await target.get_reply_message()
19 | if message:
20 | if not message.forward:
21 | user_id = message.sender.id
22 | if message.sender.username:
23 | name = "@" + message.sender.username
24 | else:
25 | name = "**" + message.sender.first_name + "**"
26 | else:
27 | user_id = message.forward.sender.id
28 | if message.forward.sender.username:
29 | name = "@" + message.forward.sender.username
30 | else:
31 | name = "*" + message.forward.sender.first_name + "*"
32 | await target.edit("**Name:** {} \n**User ID:** `{}`".format(name, user_id))
33 |
34 |
35 | @register(outgoing=True, pattern="^.link(?: |$)(.*)")
36 | async def permalink(mention):
37 | """ For .link command, generates a link to the user's PM with a custom text. """
38 | user, custom = await get_user_from_event(mention)
39 | if not user:
40 | return
41 | if custom:
42 | await mention.edit(f"[{custom}](tg://user?id={user.id})")
43 | else:
44 | tag = (
45 | user.first_name.replace("\u2060", "") if user.first_name else user.username
46 | )
47 | await mention.edit(f"[{tag}](tg://user?id={user.id})")
48 |
49 |
50 | @register(outgoing=True, pattern="^.chatid$")
51 | async def chatidgetter(chat):
52 | """ For .chatid, returns the ID of the chat you are in at that moment. """
53 | await chat.edit("Chat ID: `" + str(chat.chat_id) + "`")
54 |
55 |
56 | @register(outgoing=True, pattern=r"^.log(?: |$)([\s\S]*)")
57 | async def log(log_text):
58 | """ For .log command, forwards a message or the command argument to the bot logs group """
59 | if BOTLOG:
60 | if log_text.reply_to_msg_id:
61 | reply_msg = await log_text.get_reply_message()
62 | await reply_msg.forward_to(BOTLOG_CHATID)
63 | elif log_text.pattern_match.group(1):
64 | user = f"#LOG / Chat ID: {log_text.chat_id}\n\n"
65 | textx = user + log_text.pattern_match.group(1)
66 | await bot.send_message(BOTLOG_CHATID, textx)
67 | else:
68 | await log_text.edit("`What am I supposed to log?`")
69 | return
70 | await log_text.edit("`Logged Successfully`")
71 | else:
72 | await log_text.edit("`This feature requires Logging to be enabled!`")
73 | await sleep(2)
74 | await log_text.delete()
75 |
76 |
77 | @register(outgoing=True, pattern="^.kickme$")
78 | async def kickme(leave):
79 | """ Basically it's .kickme command """
80 | await leave.edit("Nope, no, no, I go away")
81 | await leave.client.kick_participant(leave.chat_id, "me")
82 |
83 |
84 | @register(outgoing=True, pattern="^.unmutechat$")
85 | async def unmute_chat(unm_e):
86 | """ For .unmutechat command, unmute a muted chat. """
87 | try:
88 | from userbot.modules.sql_helper.keep_read_sql import unkread
89 | except AttributeError:
90 | await unm_e.edit("`Running on Non-SQL Mode!`")
91 | return
92 | unkread(str(unm_e.chat_id))
93 | await unm_e.edit("```Unmuted this chat Successfully```")
94 | await sleep(2)
95 | await unm_e.delete()
96 |
97 |
98 | @register(outgoing=True, pattern="^.mutechat$")
99 | async def mute_chat(mute_e):
100 | """ For .mutechat command, mute any chat. """
101 | try:
102 | from userbot.modules.sql_helper.keep_read_sql import kread
103 | except AttributeError:
104 | await mute_e.edit("`Running on Non-SQL mode!`")
105 | return
106 | await mute_e.edit(str(mute_e.chat_id))
107 | kread(str(mute_e.chat_id))
108 | await mute_e.edit("`Shush! This chat will be silenced!`")
109 | await sleep(2)
110 | await mute_e.delete()
111 | if BOTLOG:
112 | await mute_e.client.send_message(
113 | BOTLOG_CHATID, str(mute_e.chat_id) + " was silenced."
114 | )
115 |
116 |
117 | @register(incoming=True, disable_errors=True)
118 | async def keep_read(message):
119 | """ The mute logic. """
120 | try:
121 | from userbot.modules.sql_helper.keep_read_sql import is_kread
122 | except AttributeError:
123 | return
124 | kread = is_kread()
125 | if kread:
126 | for i in kread:
127 | if i.groupid == str(message.chat_id):
128 | await message.client.send_read_acknowledge(message.chat_id)
129 |
130 |
131 | # Regex-Ninja module by @Kandnub
132 | regexNinja = False
133 |
134 |
135 | @register(outgoing=True, pattern="^s/")
136 | async def sedNinja(event):
137 | """For regex-ninja module, auto delete command starting with s/"""
138 | if regexNinja:
139 | await sleep(0.5)
140 | await event.delete()
141 |
142 |
143 | @register(outgoing=True, pattern="^.regexninja (on|off)$")
144 | async def sedNinjaToggle(event):
145 | """ Enables or disables the regex ninja module. """
146 | global regexNinja
147 | if event.pattern_match.group(1) == "on":
148 | regexNinja = True
149 | await event.edit("`Successfully enabled ninja mode for Regexbot.`")
150 | await sleep(1)
151 | await event.delete()
152 | elif event.pattern_match.group(1) == "off":
153 | regexNinja = False
154 | await event.edit("`Successfully disabled ninja mode for Regexbot.`")
155 | await sleep(1)
156 | await event.delete()
157 |
158 |
159 | CMD_HELP.update(
160 | {
161 | "chat": ".chatid\
162 | \nUsage: Fetches the current chat's ID\
163 | \n\n.userid\
164 | \nUsage: Fetches the ID of the user in reply, if its a forwarded message, finds the ID for the source.\
165 | \n\n.log\
166 | \nUsage: Forwards the message you've replied to in your bot logs group.\
167 | \n\n.kickme\
168 | \nUsage: Leave from a targeted group.\
169 | \n\n.unmutechat\
170 | \nUsage: Unmutes a muted chat.\
171 | \n\n.mutechat\
172 | \nUsage: Allows you to mute any chat.\
173 | \n\n.link : (or) reply to someone's message with .link \
174 | \nUsage: Generate a permanent link to the user's profile with optional custom text.\
175 | \n\n.regexninja on/off\
176 | \nUsage: Globally enable/disables the regex ninja module.\
177 | \nRegex Ninja module helps to delete the regex bot's triggering messages."
178 | }
179 | )
180 |
--------------------------------------------------------------------------------
/userbot/modules/covid.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port to UserBot by @MoveAngel
7 |
8 | from covid import Covid
9 |
10 | from userbot import CMD_HELP
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern="^.covid (.*)")
15 | async def corona(event):
16 | await event.edit("`Processing...`")
17 | country = event.pattern_match.group(1)
18 | covid = Covid(source="worldometers")
19 | try:
20 | country_data = covid.get_status_by_country_name(country)
21 | output_text = (
22 | f"`Confirmed : {format_integer(country_data['confirmed'])}`\n"
23 | + f"`Active : {format_integer(country_data['active'])}`\n"
24 | + f"`Deaths : {format_integer(country_data['deaths'])}`\n"
25 | + f"`Recovered : {format_integer(country_data['recovered'])}`\n\n"
26 | + f"`New Cases : {format_integer(country_data['new_cases'])}`\n"
27 | + f"`New Deaths : {format_integer(country_data['new_deaths'])}`\n"
28 | + f"`Critical : {format_integer(country_data['critical'])}`\n"
29 | + f"`Total Tests : {format_integer(country_data['total_tests'])}`\n\n"
30 | + f"Data provided by [Worldometer](https://www.worldometers.info/coronavirus/country/{country})"
31 | )
32 | await event.edit(f"Corona Virus Info in {country}:\n\n{output_text}")
33 | except ValueError:
34 | await event.edit(
35 | f"No information found for: {country}!\nCheck your spelling and try again."
36 | )
37 |
38 |
39 | def format_integer(number, thousand_separator="."):
40 | def reverse(string):
41 | string = "".join(reversed(string))
42 | return string
43 |
44 | s = reverse(str(number))
45 | count = 0
46 | result = ""
47 | for char in s:
48 | count = count + 1
49 | if count % 3 == 0:
50 | if len(s) == count:
51 | result = char + result
52 | else:
53 | result = thousand_separator + char + result
54 | else:
55 | result = char + result
56 | return result
57 |
58 |
59 | CMD_HELP.update(
60 | {
61 | "covid": ".covid "
62 | "\nUsage: Get an information about data covid-19 in your country.\n"
63 | }
64 | )
65 |
--------------------------------------------------------------------------------
/userbot/modules/create.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # (c) Spechide - UniBorg
7 | # Port From UniBorg to UserBot by @afdulfauzan
8 |
9 | from telethon.tl import functions
10 |
11 | from userbot import CMD_HELP
12 | from userbot.events import register
13 |
14 |
15 | @register(outgoing=True, pattern="^.create (b|g|c)(?: |$)(.*)")
16 | async def telegraphs(grop):
17 | """ For .create command, Creating New Group & Channel """
18 | if not grop.text[0].isalpha() and grop.text[0] not in ("/", "#", "@", "!"):
19 | if grop.fwd_from:
20 | return
21 | type_of_group = grop.pattern_match.group(1)
22 | group_name = grop.pattern_match.group(2)
23 | if type_of_group == "b":
24 | try:
25 | result = await grop.client(
26 | functions.messages.CreateChatRequest( # pylint:disable=E0602
27 | users=["@userbotindobot"],
28 | # Not enough users (to create a chat, for example)
29 | # Telegram, no longer allows creating a chat with
30 | # ourselves
31 | title=group_name,
32 | )
33 | )
34 | created_chat_id = result.chats[0].id
35 | result = await grop.client(
36 | functions.messages.ExportChatInviteRequest(
37 | peer=created_chat_id,
38 | )
39 | )
40 | await grop.edit(
41 | "Your {} Group Created Successfully. Click [{}]({}) to join".format(
42 | group_name, group_name, result.link
43 | )
44 | )
45 | except Exception as e: # pylint:disable=C0103,W0703
46 | await grop.edit(str(e))
47 | elif type_of_group == "g" or type_of_group == "c":
48 | try:
49 | r = await grop.client(
50 | functions.channels.CreateChannelRequest( # pylint:disable=E0602
51 | title=group_name,
52 | about="Welcome to this Channel",
53 | megagroup=False if type_of_group == "c" else True,
54 | )
55 | )
56 | created_chat_id = r.chats[0].id
57 | result = await grop.client(
58 | functions.messages.ExportChatInviteRequest(
59 | peer=created_chat_id,
60 | )
61 | )
62 | await grop.edit(
63 | "Your {} Group/Channel Created Successfully. Click [{}]({}) to join".format(
64 | group_name, group_name, result.link
65 | )
66 | )
67 | except Exception as e: # pylint:disable=C0103,W0703
68 | await grop.edit(str(e))
69 |
70 |
71 | CMD_HELP.update(
72 | {
73 | "create": "\
74 | Create\
75 | \nUsage: Create Channel, Group & Group With Bot.\
76 | \n\n.create g \
77 | \nUsage: Create a Private Group.\
78 | \n\n.create b \
79 | \nUsage: Create a Group with Bot.\
80 | \n\n.create c \
81 | \nUsage: Create a Channel.\
82 | "
83 | }
84 | )
85 |
--------------------------------------------------------------------------------
/userbot/modules/deezload.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 The Authors UniBorg (telegram userbot)
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # requires: deezloader hachoir Pillow
7 | # Ported from UniBorg by AnggaR96s
8 |
9 | import os
10 | import shutil
11 | import time
12 |
13 | import deezloader
14 | from hachoir.metadata import extractMetadata
15 | from hachoir.parser import createParser
16 | from telethon.tl.types import DocumentAttributeAudio
17 |
18 | from userbot import CMD_HELP, DEEZER_ARL_TOKEN, TEMP_DOWNLOAD_DIRECTORY
19 | from userbot.events import register
20 |
21 |
22 | @register(outgoing=True, pattern=r"^\.deez (.+?|) (FLAC|MP3\_320|MP3\_256|MP3\_128)")
23 | async def _(event):
24 | """DeezLoader by @An0nimia
25 | Ported for UniBorg by @SpEcHlDe"""
26 | if event.fwd_from:
27 | return
28 |
29 | strings = {
30 | "name": "DeezLoad",
31 | "arl_token_cfg_doc": "ARL Token for Deezer",
32 | "invalid_arl_token": "please set the required variables for this module",
33 | "wrong_cmd_syntax": "bruh, now i think how far should we go. please terminate my Session!",
34 | "server_error": "We're experiencing technical difficulties.",
35 | "processing": "`Downloading...`",
36 | "uploading": "`Uploading...`",
37 | }
38 |
39 | ARL_TOKEN = DEEZER_ARL_TOKEN
40 |
41 | if ARL_TOKEN is None:
42 | await event.edit(strings["invalid_arl_token"])
43 | return
44 |
45 | try:
46 | loader = deezloader.Login(ARL_TOKEN)
47 | except Exception as er:
48 | await event.edit(str(er))
49 | return
50 |
51 | temp_dl_path = os.path.join(TEMP_DOWNLOAD_DIRECTORY, str(time.time()))
52 | if not os.path.exists(temp_dl_path):
53 | os.makedirs(temp_dl_path)
54 |
55 | required_link = event.pattern_match.group(1)
56 | required_qty = event.pattern_match.group(2)
57 |
58 | await event.edit(strings["processing"])
59 |
60 | if "spotify" in required_link:
61 | if "track" in required_link:
62 | required_track = loader.download_trackspo(
63 | required_link,
64 | output=temp_dl_path,
65 | quality=required_qty,
66 | recursive_quality=True,
67 | recursive_download=True,
68 | not_interface=True,
69 | )
70 | await event.edit(strings["uploading"])
71 | await upload_track(required_track, event)
72 | shutil.rmtree(temp_dl_path)
73 | await event.delete()
74 |
75 | elif "album" in required_link:
76 | reqd_albums = loader.download_albumspo(
77 | required_link,
78 | output=temp_dl_path,
79 | quality=required_qty,
80 | recursive_quality=True,
81 | recursive_download=True,
82 | not_interface=True,
83 | zips=False,
84 | )
85 | await event.edit(strings["uploading"])
86 | for required_track in reqd_albums:
87 | await upload_track(required_track, event)
88 | shutil.rmtree(temp_dl_path)
89 | await event.delete()
90 |
91 | elif "deezer" in required_link:
92 | if "track" in required_link:
93 | required_track = loader.download_trackdee(
94 | required_link,
95 | output=temp_dl_path,
96 | quality=required_qty,
97 | recursive_quality=True,
98 | recursive_download=True,
99 | not_interface=True,
100 | )
101 | await event.edit(strings["uploading"])
102 | await upload_track(required_track, event)
103 | shutil.rmtree(temp_dl_path)
104 | await event.delete()
105 |
106 | elif "album" in required_link:
107 | reqd_albums = loader.download_albumdee(
108 | required_link,
109 | output=temp_dl_path,
110 | quality=required_qty,
111 | recursive_quality=True,
112 | recursive_download=True,
113 | not_interface=True,
114 | zips=False,
115 | )
116 | await event.edit(strings["uploading"])
117 | for required_track in reqd_albums:
118 | await upload_track(required_track, event)
119 | shutil.rmtree(temp_dl_path)
120 | await event.delete()
121 |
122 | else:
123 | await event.edit(strings["wrong_cmd_syntax"])
124 |
125 |
126 | async def upload_track(track_location, message):
127 | metadata = extractMetadata(createParser(track_location))
128 | duration = 0
129 | title = ""
130 | performer = ""
131 | if metadata.has("duration"):
132 | duration = metadata.get("duration").seconds
133 | if metadata.has("title"):
134 | title = metadata.get("title")
135 | if metadata.has("artist"):
136 | performer = metadata.get("artist")
137 | document_attributes = [
138 | DocumentAttributeAudio(
139 | duration=duration,
140 | voice=False,
141 | title=title,
142 | performer=performer,
143 | waveform=None,
144 | )
145 | ]
146 | supports_streaming = True
147 | force_document = False
148 | caption_rts = os.path.basename(track_location)
149 | await message.client.send_file(
150 | message.chat_id,
151 | track_location,
152 | caption=caption_rts,
153 | force_document=force_document,
154 | supports_streaming=supports_streaming,
155 | allow_cache=False,
156 | attributes=document_attributes,
157 | )
158 | os.remove(track_location)
159 |
160 |
161 | CMD_HELP.update(
162 | {
163 | "deezload": ".deez "
164 | "\nUsage: Download music from deezer."
165 | "\n\n *Format= `FLAC`, `MP3_320`, `MP3_256`, `MP3_128`."
166 | }
167 | )
168 |
--------------------------------------------------------------------------------
/userbot/modules/figlet.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port to UserBot by @MoveAngel
7 |
8 | import pyfiglet
9 |
10 | from userbot import CMD_HELP
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern=r"^\.figlet(?: |$)(.*)")
15 | async def figlet(fg):
16 | if fg.fwd_from:
17 | return
18 | CMD_FIG = {
19 | "slant": "slant",
20 | "3D": "3-d",
21 | "5line": "5lineoblique",
22 | "alpha": "alphabet",
23 | "banner": "banner3-D",
24 | "doh": "doh",
25 | "iso": "isometric1",
26 | "letter": "letters",
27 | "allig": "alligator",
28 | "dotm": "dotmatrix",
29 | "bubble": "bubble",
30 | "bulb": "bulbhead",
31 | "digi": "digital",
32 | }
33 | input_str = fg.pattern_match.group(1)
34 | if "." in input_str:
35 | text, cmd = input_str.split(".", maxsplit=1)
36 | elif input_str is not None:
37 | cmd = None
38 | text = input_str
39 | else:
40 | await fg.edit("`Please add some text to figlet`")
41 | return
42 | if cmd is not None:
43 | try:
44 | font = CMD_FIG[cmd]
45 | except KeyError:
46 | await fg.edit("`Invalid selected font.`")
47 | return
48 | result = pyfiglet.figlet_format(text, font=font)
49 | else:
50 | result = pyfiglet.figlet_format(text)
51 | await fg.respond("`{}`".format(result))
52 | await fg.delete()
53 |
54 |
55 | CMD_HELP.update(
56 | {
57 | "figlet": ".figlet"
58 | "\nUsage: Enhance ur text to strip line with anvil."
59 | "\n\nExample: `.figlet `"
60 | "\nSTYLE LIST: `slant`, `3D`, `5line`, `alpha`, `banner`, `doh`, `iso`, `letter`, `allig`, `dotm`, `bubble`, `bulb`, `digi`"
61 | }
62 | )
63 |
--------------------------------------------------------------------------------
/userbot/modules/filemanager.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import io
8 | import os
9 | import os.path
10 | import time
11 | from os.path import exists, isdir
12 |
13 | from userbot import CMD_HELP
14 | from userbot.events import register
15 | from userbot.utils import humanbytes
16 |
17 | MAX_MESSAGE_SIZE_LIMIT = 4095
18 |
19 |
20 | @register(outgoing=True, pattern=r"^\.ls ?(.*)")
21 | async def lst(event):
22 | if event.fwd_from:
23 | return
24 | cat = event.pattern_match.group(1)
25 | if cat:
26 | path = cat
27 | else:
28 | path = os.getcwd()
29 | if not exists(path):
30 | await event.edit(
31 | f"There is no such directory or file with the name `{cat}` check again!"
32 | )
33 | return
34 | if isdir(path):
35 | if cat:
36 | msg = "Folders and Files in `{}` :\n\n".format(path)
37 | lists = os.listdir(path)
38 | else:
39 | msg = "Folders and Files in Current Directory :\n\n"
40 | lists = os.listdir(path)
41 | files = ""
42 | folders = ""
43 | for contents in sorted(lists):
44 | catpath = path + "/" + contents
45 | if not isdir(catpath):
46 | size = os.stat(catpath).st_size
47 | if contents.endswith((".mp3", ".flac", ".wav", ".m4a")):
48 | files += "🎵 " + f"`{contents}`\n"
49 | if contents.endswith((".opus")):
50 | files += "🎙 " + f"`{contents}`\n"
51 | elif contents.endswith(
52 | (".mkv", ".mp4", ".webm", ".avi", ".mov", ".flv")
53 | ):
54 | files += "🎞 " + f"`{contents}`\n"
55 | elif contents.endswith(
56 | (".zip", ".tar", ".tar.gz", ".rar", ".7z", ".xz")
57 | ):
58 | files += "🗜 " + f"`{contents}`\n"
59 | elif contents.endswith(
60 | (".jpg", ".jpeg", ".png", ".gif", ".bmp", ".ico", ". webp")
61 | ):
62 | files += "🖼 " + f"`{contents}`\n"
63 | elif contents.endswith((".exe", ".deb")):
64 | files += "⚙️ " + f"`{contents}`\n"
65 | elif contents.endswith((".iso", ".img")):
66 | files += "💿 " + f"`{contents}`\n"
67 | elif contents.endswith((".apk", ".xapk")):
68 | files += "📱 " + f"`{contents}`\n"
69 | elif contents.endswith((".py")):
70 | files += "🐍 " + f"`{contents}`\n"
71 | else:
72 | files += "📄 " + f"`{contents}`\n"
73 | else:
74 | folders += f"📁 `{contents}`\n"
75 | if files or folders:
76 | msg = msg + folders + files
77 | else:
78 | msg = msg + "__empty path__"
79 | else:
80 | size = os.stat(path).st_size
81 | msg = "The details of given file :\n\n"
82 | if path.endswith((".mp3", ".flac", ".wav", ".m4a")):
83 | mode = "🎵 "
84 | if path.endswith((".opus")):
85 | mode = "🎙 "
86 | elif path.endswith((".mkv", ".mp4", ".webm", ".avi", ".mov", ".flv")):
87 | mode = "🎞 "
88 | elif path.endswith((".zip", ".tar", ".tar.gz", ".rar", ".7z", ".xz")):
89 | mode = "🗜 "
90 | elif path.endswith((".jpg", ".jpeg", ".png", ".gif", ".bmp", ".ico", ". webp")):
91 | mode = "🖼 "
92 | elif path.endswith((".exe", ".deb")):
93 | mode = "⚙️ "
94 | elif path.endswith((".iso", ".img")):
95 | mode = "💿 "
96 | elif path.endswith((".apk", ".xapk")):
97 | mode = "📱 "
98 | elif path.endswith((".py")):
99 | mode = "🐍 "
100 | else:
101 | mode = "📄 "
102 | time.ctime(os.path.getctime(path))
103 | time2 = time.ctime(os.path.getmtime(path))
104 | time3 = time.ctime(os.path.getatime(path))
105 | msg += f"**Location :** `{path}`\n"
106 | msg += f"**Icon :** `{mode}`\n"
107 | msg += f"**Size :** `{humanbytes(size)}`\n"
108 | msg += f"**Last Modified Time:** `{time2}`\n"
109 | msg += f"**Last Accessed Time:** `{time3}`"
110 |
111 | if len(msg) > MAX_MESSAGE_SIZE_LIMIT:
112 | with io.BytesIO(str.encode(msg)) as out_file:
113 | out_file.name = "ls.txt"
114 | await event.client.send_file(
115 | event.chat_id,
116 | out_file,
117 | force_document=True,
118 | allow_cache=False,
119 | caption=path,
120 | )
121 | await event.delete()
122 | else:
123 | await event.edit(msg)
124 |
125 |
126 | CMD_HELP.update(
127 | {
128 | "file": ".ls "
129 | "\nUsage: Get an information about data covid-19 in your country."
130 | }
131 | )
132 |
--------------------------------------------------------------------------------
/userbot/modules/filter.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module for filter commands """
7 |
8 | from asyncio import sleep
9 | from re import IGNORECASE, escape, search
10 |
11 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP
12 | from userbot.events import register
13 |
14 |
15 | @register(incoming=True, disable_edited=True, disable_errors=True)
16 | async def filter_incoming_handler(handler):
17 | """ Checks if the incoming message contains handler of a filter """
18 | try:
19 | if not (await handler.get_sender()).bot:
20 | try:
21 | from userbot.modules.sql_helper.filter_sql import get_filters
22 | except AttributeError:
23 | await handler.edit("`Running on Non-SQL mode!`")
24 | return
25 | name = handler.raw_text
26 | filters = get_filters(handler.chat_id)
27 | if not filters:
28 | return
29 | for trigger in filters:
30 | pattern = r"( |^|[^\w])" + escape(trigger.keyword) + r"( |$|[^\w])"
31 | pro = search(pattern, name, flags=IGNORECASE)
32 | if pro and trigger.f_mesg_id:
33 | msg_o = await handler.client.get_messages(
34 | entity=BOTLOG_CHATID, ids=int(trigger.f_mesg_id)
35 | )
36 | await handler.reply(msg_o.message, file=msg_o.media)
37 | elif pro and trigger.reply:
38 | await handler.reply(trigger.reply)
39 | except AttributeError:
40 | pass
41 |
42 |
43 | @register(outgoing=True, pattern=r"^.filter (.*)")
44 | async def add_new_filter(new_handler):
45 | """ For .filter command, allows adding new filters in a chat """
46 | try:
47 | from userbot.modules.sql_helper.filter_sql import add_filter
48 | except AttributeError:
49 | await new_handler.edit("`Running on Non-SQL mode!`")
50 | return
51 | value = new_handler.pattern_match.group(1).split(None, 1)
52 | """ - The first words after .filter(space) is the keyword - """
53 | keyword = value[0]
54 | try:
55 | string = value[1]
56 | except IndexError:
57 | string = None
58 | msg = await new_handler.get_reply_message()
59 | msg_id = None
60 | if msg and msg.media and not string:
61 | if BOTLOG_CHATID:
62 | await new_handler.client.send_message(
63 | BOTLOG_CHATID,
64 | f"#FILTER\nCHAT ID: {new_handler.chat_id}\nTRIGGER: {keyword}"
65 | "\n\nThe following message is saved as the filter's reply data for the chat, please do NOT delete it !!",
66 | )
67 | msg_o = await new_handler.client.forward_messages(
68 | entity=BOTLOG_CHATID,
69 | messages=msg,
70 | from_peer=new_handler.chat_id,
71 | silent=True,
72 | )
73 | msg_id = msg_o.id
74 | else:
75 | return await new_handler.edit(
76 | "`Saving media as reply to the filter requires the BOTLOG_CHATID to be set.`"
77 | )
78 | elif new_handler.reply_to_msg_id and not string:
79 | rep_msg = await new_handler.get_reply_message()
80 | string = rep_msg.text
81 | success = "`Filter` **{}** `{} successfully`."
82 | if add_filter(str(new_handler.chat_id), keyword, string, msg_id) is True:
83 | await new_handler.edit(success.format(keyword, "added"))
84 | else:
85 | await new_handler.edit(success.format(keyword, "updated"))
86 |
87 |
88 | @register(outgoing=True, pattern=r"^.stop (.*)")
89 | async def remove_a_filter(r_handler):
90 | """ For .stop command, allows you to remove a filter from a chat. """
91 | try:
92 | from userbot.modules.sql_helper.filter_sql import remove_filter
93 | except AttributeError:
94 | return await r_handler.edit("`Running on Non-SQL mode!`")
95 | filt = r_handler.pattern_match.group(1)
96 | if not remove_filter(r_handler.chat_id, filt):
97 | await r_handler.edit("`Filter` **{}** `doesn't exist`.".format(filt))
98 | else:
99 | await r_handler.edit(
100 | "`Filter` **{}** `was deleted successfully`.".format(filt)
101 | )
102 |
103 |
104 | @register(outgoing=True, pattern="^.rmbotfilters (.*)")
105 | async def kick_marie_filter(event):
106 | """ For .rmfilters command, allows you to kick all \
107 | Marie(or her clones) filters from a chat. """
108 | event.text[0]
109 | bot_type = event.pattern_match.group(1).lower()
110 | if bot_type not in ["marie", "rose"]:
111 | return await event.edit("`That bot is not yet supported!`")
112 | await event.edit("```Will be kicking away all Filters!```")
113 | await sleep(3)
114 | resp = await event.get_reply_message()
115 | filters = resp.text.split("-")[1:]
116 | for i in filters:
117 | if bot_type.lower() == "marie":
118 | await event.reply("/stop %s" % (i.strip()))
119 | if bot_type.lower() == "rose":
120 | i = i.replace("`", "")
121 | await event.reply("/stop %s" % (i.strip()))
122 | await sleep(0.3)
123 | await event.respond("```Successfully purged bots filters yaay!```\n Gimme cookies!")
124 | if BOTLOG:
125 | await event.client.send_message(
126 | BOTLOG_CHATID, "I cleaned all filters at " + str(event.chat_id)
127 | )
128 |
129 |
130 | @register(outgoing=True, pattern="^.filters$")
131 | async def filters_active(event):
132 | """ For .filters command, lists all of the active filters in a chat. """
133 | try:
134 | from userbot.modules.sql_helper.filter_sql import get_filters
135 | except AttributeError:
136 | return await event.edit("`Running on Non-SQL mode!`")
137 | transact = "`There are no filters in this chat.`"
138 | filters = get_filters(event.chat_id)
139 | for filt in filters:
140 | if transact == "`There are no filters in this chat.`":
141 | transact = "Active filters in this chat:\n"
142 | transact += "`{}`\n".format(filt.keyword)
143 | else:
144 | transact += "`{}`\n".format(filt.keyword)
145 |
146 | await event.edit(transact)
147 |
148 |
149 | CMD_HELP.update(
150 | {
151 | "filter": ".filters\
152 | \nUsage: Lists all active userbot filters in a chat.\
153 | \n\n.filter or reply to a message with .filter \
154 | \nUsage: Saves the replied message as a reply to the 'keyword'.\
155 | \nThe bot will reply to the message whenever 'keyword' is mentioned.\
156 | \nWorks with everything from files to stickers.\
157 | \n\n.stop \
158 | \nUsage: Stops the specified filter.\
159 | \n\n.rmbotfilters \
160 | \nUsage: Removes all filters of admin bots (Currently supported: Marie, Rose and their clones.) in the chat."
161 | }
162 | )
163 |
--------------------------------------------------------------------------------
/userbot/modules/fonts.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # This module is maked by Project TESLA
6 |
7 | from userbot import CMD_HELP
8 | from userbot.events import register
9 |
10 | normiefont = [
11 | "a",
12 | "b",
13 | "c",
14 | "d",
15 | "e",
16 | "f",
17 | "g",
18 | "h",
19 | "i",
20 | "j",
21 | "k",
22 | "l",
23 | "m",
24 | "n",
25 | "o",
26 | "p",
27 | "q",
28 | "r",
29 | "s",
30 | "t",
31 | "u",
32 | "v",
33 | "w",
34 | "x",
35 | "y",
36 | "z",
37 | ]
38 | weebyfont = [
39 | "卂",
40 | "乃",
41 | "匚",
42 | "刀",
43 | "乇",
44 | "下",
45 | "厶",
46 | "卄",
47 | "工",
48 | "丁",
49 | "长",
50 | "乚",
51 | "从",
52 | "𠘨",
53 | "口",
54 | "尸",
55 | "㔿",
56 | "尺",
57 | "丂",
58 | "丅",
59 | "凵",
60 | "リ",
61 | "山",
62 | "乂",
63 | "丫",
64 | "乙",
65 | ]
66 | circlyfont = [
67 | "🅐",
68 | "🅑",
69 | "🅒",
70 | "🅓",
71 | "🅔",
72 | "🅕",
73 | "🅖",
74 | "🅗",
75 | "🅘",
76 | "🅙",
77 | "🅚",
78 | "🅛",
79 | "🅜",
80 | "🅝",
81 | "🅞",
82 | "🅟",
83 | "🅠",
84 | "🅡",
85 | "🅢",
86 | "🅣",
87 | "🅤",
88 | "🅥",
89 | "🅦",
90 | "🅧",
91 | "🅨",
92 | "🅩",
93 | ]
94 | oldengfont = [
95 | "𝔄",
96 | "𝔅",
97 | "ℭ",
98 | "𝔇",
99 | "𝔈",
100 | "𝔉",
101 | "𝔊",
102 | "ℌ",
103 | "ℑ",
104 | "𝔍",
105 | "𝔎",
106 | "𝔏",
107 | "𝔐",
108 | "𝔑",
109 | "𝔒",
110 | "𝔓",
111 | "𝔔",
112 | "ℜ",
113 | "𝔖",
114 | "𝔗",
115 | "𝔘",
116 | "𝔙",
117 | "𝔚",
118 | "𝔛",
119 | "𝔜",
120 | "ℨ",
121 | ]
122 |
123 |
124 | @register(outgoing=True, pattern="^.weebify(?: |$)(.*)")
125 | async def weebify(event):
126 |
127 | args = event.pattern_match.group(1)
128 | if not args:
129 | get = await event.get_reply_message()
130 | args = get.text
131 | if not args:
132 | await event.edit("`What I am Supposed to Weebify U Dumb`")
133 | return
134 | string = " ".join(args).lower()
135 | for normiecharacter in string:
136 | if normiecharacter in normiefont:
137 | weebycharacter = weebyfont[normiefont.index(normiecharacter)]
138 | string = string.replace(normiecharacter, weebycharacter)
139 | await event.edit(string)
140 |
141 |
142 | @register(outgoing=True, pattern="^.circlify(?: |$)(.*)")
143 | async def circly(event):
144 |
145 | args = event.pattern_match.group(1)
146 | if not args:
147 | get = await event.get_reply_message()
148 | args = get.text
149 | if not args:
150 | await event.edit("`What I am Supposed to circlyfy U Dumb`")
151 | return
152 | string = " ".join(args).lower()
153 | for normiecharacter in string:
154 | if normiecharacter in normiefont:
155 | circlycharacter = circlyfont[normiefont.index(normiecharacter)]
156 | string = string.replace(normiecharacter, circlycharacter)
157 | await event.edit(string)
158 |
159 |
160 | @register(outgoing=True, pattern="^.oldeng(?: |$)(.*)")
161 | async def oldy(event):
162 |
163 | args = event.pattern_match.group(1)
164 | if not args:
165 | get = await event.get_reply_message()
166 | args = get.text
167 | if not args:
168 | await event.edit("`What, I am Supposed To Work with text only`")
169 | return
170 | string = " ".join(args).lower()
171 | for normiecharacter in string:
172 | if normiecharacter in normiefont:
173 | oldycharacter = oldengfont[normiefont.index(normiecharacter)]
174 | string = string.replace(normiecharacter, oldycharacter)
175 | await event.edit(string)
176 |
177 |
178 | CMD_HELP.update(
179 | {
180 | "fonts": ".weebify :- weebifys your text \
181 | \n.circlify :- circlifies text \
182 | \n.oldeng :- old eng font"
183 | }
184 | )
185 |
--------------------------------------------------------------------------------
/userbot/modules/github.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import os
8 | import time
9 | from datetime import datetime
10 |
11 | import aiohttp
12 | from github import Github
13 |
14 | from userbot import CMD_HELP, GIT_REPO_NAME, GITHUB_ACCESS_TOKEN, bot
15 | from userbot.events import register
16 |
17 | GIT_TEMP_DIR = "/One4uBot/temp/"
18 |
19 |
20 | @register(outgoing=True, pattern=r".git (.*)")
21 | async def github(event):
22 | username = event.pattern_match.group(1)
23 | URL = f"https://api.github.com/users/{username}"
24 | await event.get_chat()
25 | async with aiohttp.ClientSession() as session:
26 | async with session.get(URL) as request:
27 | if request.status == 404:
28 | return await event.reply(f"`{username} not found`")
29 |
30 | result = await request.json()
31 |
32 | url = result.get("html_url", None)
33 | name = result.get("name", None)
34 | company = result.get("company", None)
35 | bio = result.get("bio", None)
36 | created_at = result.get("created_at", "Not Found")
37 |
38 | REPLY = (
39 | f"GitHub Info for `{username}`\n"
40 | f"Username: `{name}`\n"
41 | f"Bio: `{bio}`\n"
42 | f"URL: {url}\n"
43 | f"Company: `{company}`\n"
44 | f"Created at: `{created_at}`\n"
45 | f"More info : [Here](https://api.github.com/users/{username}/events/public)"
46 | )
47 |
48 | if not result.get("repos_url", None):
49 | return await event.edit(REPLY)
50 | async with session.get(result.get("repos_url", None)) as request:
51 | result = request.json
52 | if request.status == 404:
53 | return await event.edit(REPLY)
54 |
55 | result = await request.json()
56 |
57 | REPLY += "\nRepos:\n"
58 |
59 | for nr in range(len(result)):
60 | REPLY += f"[{result[nr].get('name', None)}]({result[nr].get('html_url', None)})\n"
61 |
62 | await event.edit(REPLY)
63 |
64 |
65 | @register(outgoing=True, pattern="^.commit(?: |$)(.*)")
66 | async def download(event):
67 | if event.fwd_from:
68 | return
69 | if GITHUB_ACCESS_TOKEN is None:
70 | await event.edit("`Please ADD Proper Access Token from github.com`")
71 | return
72 | if GIT_REPO_NAME is None:
73 | await event.edit("`Please ADD Proper Github Repo Name of your userbot`")
74 | return
75 | mone = await event.reply("Processing ...")
76 | if not os.path.isdir(GIT_TEMP_DIR):
77 | os.makedirs(GIT_TEMP_DIR)
78 | start = datetime.now()
79 | reply_message = await event.get_reply_message()
80 | try:
81 | time.time()
82 | print("Downloading to TEMP directory")
83 | downloaded_file_name = await bot.download_media(
84 | reply_message.media, GIT_TEMP_DIR
85 | )
86 | except Exception as e:
87 | await mone.edit(str(e))
88 | else:
89 | end = datetime.now()
90 | ms = (end - start).seconds
91 | await event.delete()
92 | await mone.edit(
93 | "Downloaded to `{}` in {} seconds.".format(downloaded_file_name, ms)
94 | )
95 | await mone.edit("Committing to Github....")
96 | await git_commit(downloaded_file_name, mone)
97 |
98 |
99 | async def git_commit(file_name, mone):
100 | content_list = []
101 | access_token = GITHUB_ACCESS_TOKEN
102 | g = Github(access_token)
103 | file = open(file_name, "r", encoding="utf-8")
104 | commit_data = file.read()
105 | repo = g.get_repo(GIT_REPO_NAME)
106 | print(repo.name)
107 | create_file = True
108 | contents = repo.get_contents("")
109 | for content_file in contents:
110 | content_list.append(str(content_file))
111 | print(content_file)
112 | for i in content_list:
113 | create_file = True
114 | if i == 'ContentFile(path="' + file_name + '")':
115 | return await mone.edit("`File Already Exists`")
116 | create_file = False
117 | file_name = "userbot/modules/" + file_name
118 | if create_file:
119 | file_name = file_name.replace(GIT_TEMP_DIR, "")
120 | print(file_name)
121 | try:
122 | repo.create_file(
123 | file_name, "Uploaded New Plugin", commit_data, branch="sql-extended"
124 | )
125 | print("Committed File")
126 | ccess = GIT_REPO_NAME
127 | ccess = ccess.strip()
128 | await mone.edit(
129 | f"`Commited On Your Github Repo`\n\n[Your Modules](https://github.com/{ccess}/tree/sql-extended/userbot/modules/)"
130 | )
131 | except BaseException:
132 | print("Cannot Create Plugin")
133 | await mone.edit("Cannot Upload Plugin")
134 | else:
135 | return await mone.edit("`Committed Suicide`")
136 |
137 |
138 | CMD_HELP.update(
139 | {
140 | "github": ".git "
141 | "\nUsage: Like .whois but for GitHub usernames."
142 | "\n\n.commit "
143 | "\nUsage: GITHUB File Uploader Plugin for userbot. Heroku Automation should be Enabled."
144 | }
145 | )
146 |
--------------------------------------------------------------------------------
/userbot/modules/hash.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module containing hash and encode/decode commands. """
7 |
8 | from subprocess import PIPE
9 | from subprocess import run as runapp
10 |
11 | import pybase64
12 |
13 | from userbot import CMD_HELP
14 | from userbot.events import register
15 |
16 |
17 | @register(outgoing=True, pattern="^.hash (.*)")
18 | async def gethash(hash_q):
19 | """ For .hash command, find the md5, sha1, sha256, sha512 of the string. """
20 | hashtxt_ = hash_q.pattern_match.group(1)
21 | hashtxt = open("hashdis.txt", "w+")
22 | hashtxt.write(hashtxt_)
23 | hashtxt.close()
24 | md5 = runapp(["md5sum", "hashdis.txt"], stdout=PIPE)
25 | md5 = md5.stdout.decode()
26 | sha1 = runapp(["sha1sum", "hashdis.txt"], stdout=PIPE)
27 | sha1 = sha1.stdout.decode()
28 | sha256 = runapp(["sha256sum", "hashdis.txt"], stdout=PIPE)
29 | sha256 = sha256.stdout.decode()
30 | sha512 = runapp(["sha512sum", "hashdis.txt"], stdout=PIPE)
31 | runapp(["rm", "hashdis.txt"], stdout=PIPE)
32 | sha512 = sha512.stdout.decode()
33 | ans = (
34 | "Text: `"
35 | + hashtxt_
36 | + "`\nMD5: `"
37 | + md5
38 | + "`SHA1: `"
39 | + sha1
40 | + "`SHA256: `"
41 | + sha256
42 | + "`SHA512: `"
43 | + sha512[:-1]
44 | + "`"
45 | )
46 | if len(ans) > 4096:
47 | hashfile = open("hashes.txt", "w+")
48 | hashfile.write(ans)
49 | hashfile.close()
50 | await hash_q.client.send_file(
51 | hash_q.chat_id,
52 | "hashes.txt",
53 | reply_to=hash_q.id,
54 | caption="`It's too big, sending a text file instead. `",
55 | )
56 | runapp(["rm", "hashes.txt"], stdout=PIPE)
57 | else:
58 | await hash_q.reply(ans)
59 |
60 |
61 | @register(outgoing=True, pattern="^.base64 (en|de) (.*)")
62 | async def endecrypt(query):
63 | """ For .base64 command, find the base64 encoding of the given string. """
64 | if query.pattern_match.group(1) == "en":
65 | lething = str(pybase64.b64encode(bytes(query.pattern_match.group(2), "utf-8")))[
66 | 2:
67 | ]
68 | await query.reply("Encoded: `" + lething[:-1] + "`")
69 | else:
70 | lething = str(
71 | pybase64.b64decode(
72 | bytes(query.pattern_match.group(2), "utf-8"), validate=True
73 | )
74 | )[2:]
75 | await query.reply("Decoded: `" + lething[:-1] + "`")
76 |
77 |
78 | CMD_HELP.update({"base64": "Find the base64 encoding of the given string"})
79 |
80 | CMD_HELP.update(
81 | {
82 | "hash": "Find the md5, sha1, sha256, sha512 of the string when written into a txt file."
83 | }
84 | )
85 |
--------------------------------------------------------------------------------
/userbot/modules/help.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot help command """
7 |
8 | from userbot import CMD_HELP
9 | from userbot.events import register
10 |
11 |
12 | @register(outgoing=True, pattern="^.help(?: |$)(.*)")
13 | async def help(event):
14 | """ For .help command,"""
15 | args = event.pattern_match.group(1).lower()
16 | if args:
17 | if args in CMD_HELP:
18 | await event.edit(str(CMD_HELP[args]))
19 | else:
20 | await event.edit("Please specify a valid module name.")
21 | else:
22 | string = ""
23 | for i in CMD_HELP:
24 | string += "`" + str(i)
25 | string += "`\t\t\t||\t\t\t "
26 | await event.edit(
27 | f"{string}"
28 | "\n\nSpecify which module do you want help for !!\
29 | \n**Usage:** `.help` "
30 | )
31 |
--------------------------------------------------------------------------------
/userbot/modules/invite.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port From UniBorg to UserBot by @afdulfauzan
7 |
8 | from asyncio import sleep
9 |
10 | from telethon import functions
11 |
12 | from userbot import CMD_HELP
13 | from userbot.events import register
14 |
15 |
16 | @register(outgoing=True, pattern="^.invite(?: |$)(.*)")
17 | async def _(event):
18 | if event.fwd_from:
19 | return
20 | to_add_users = event.pattern_match.group(1)
21 | if event.is_private:
22 | await event.edit("`.invite` users to a chat, not to a Private Message")
23 | else:
24 | if not event.is_channel and event.is_group:
25 | # https://lonamiwebs.github.io/Telethon/methods/messages/add_chat_user.html
26 | for user_id in to_add_users.split(" "):
27 | try:
28 | await event.client(
29 | functions.messages.AddChatUserRequest(
30 | chat_id=event.chat_id, user_id=user_id, fwd_limit=1000000
31 | )
32 | )
33 | except Exception as e:
34 | await event.edit(str(e))
35 | return
36 | await event.edit("`Invited Successfully`")
37 | await sleep(2)
38 | await event.delete()
39 | else:
40 | # https://lonamiwebs.github.io/Telethon/methods/channels/invite_to_channel.html
41 | for user_id in to_add_users.split(" "):
42 | try:
43 | await event.client(
44 | functions.channels.InviteToChannelRequest(
45 | channel=event.chat_id, users=[user_id]
46 | )
47 | )
48 | except Exception as e:
49 | await event.edit(str(e))
50 | return
51 | await event.edit("`Invited Successfully`")
52 | await sleep(2)
53 | await event.delete()
54 |
55 |
56 | CMD_HELP.update(
57 | {
58 | "invite": ".invite \
59 | \nUsage: Invite some user or bots if u want."
60 | }
61 | )
62 |
--------------------------------------------------------------------------------
/userbot/modules/locks.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | from telethon.tl.functions.messages import EditChatDefaultBannedRightsRequest
8 | from telethon.tl.types import ChatBannedRights
9 |
10 | from userbot import CMD_HELP
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern=r"^.lock ?(.*)")
15 | async def locks(event):
16 | input_str = event.pattern_match.group(1).lower()
17 | peer_id = event.chat_id
18 | msg = None
19 | media = None
20 | sticker = None
21 | gif = None
22 | gamee = None
23 | ainline = None
24 | gpoll = None
25 | adduser = None
26 | cpin = None
27 | changeinfo = None
28 | if input_str == "msg":
29 | msg = True
30 | what = "messages"
31 | elif input_str == "media":
32 | media = True
33 | what = "media"
34 | elif input_str == "sticker":
35 | sticker = True
36 | what = "stickers"
37 | elif input_str == "gif":
38 | gif = True
39 | what = "GIFs"
40 | elif input_str == "game":
41 | gamee = True
42 | what = "games"
43 | elif input_str == "inline":
44 | ainline = True
45 | what = "inline bots"
46 | elif input_str == "poll":
47 | gpoll = True
48 | what = "polls"
49 | elif input_str == "invite":
50 | adduser = True
51 | what = "invites"
52 | elif input_str == "pin":
53 | cpin = True
54 | what = "pins"
55 | elif input_str == "info":
56 | changeinfo = True
57 | what = "chat info"
58 | elif input_str == "all":
59 | msg = True
60 | media = True
61 | sticker = True
62 | gif = True
63 | gamee = True
64 | ainline = True
65 | gpoll = True
66 | adduser = True
67 | cpin = True
68 | changeinfo = True
69 | what = "everything"
70 | else:
71 | if not input_str:
72 | await event.edit("`I can't lock nothing !!`")
73 | return
74 | else:
75 | await event.edit(f"`Invalid lock type:` {input_str}")
76 | return
77 |
78 | lock_rights = ChatBannedRights(
79 | until_date=None,
80 | send_messages=msg,
81 | send_media=media,
82 | send_stickers=sticker,
83 | send_gifs=gif,
84 | send_games=gamee,
85 | send_inline=ainline,
86 | send_polls=gpoll,
87 | invite_users=adduser,
88 | pin_messages=cpin,
89 | change_info=changeinfo,
90 | )
91 | try:
92 | await event.client(
93 | EditChatDefaultBannedRightsRequest(peer=peer_id, banned_rights=lock_rights)
94 | )
95 | await event.edit(f"`Locked {what} for this chat !!`")
96 | except BaseException as e:
97 | await event.edit(f"`Do I have proper rights for that ??`\n**Error:** {str(e)}")
98 | return
99 |
100 |
101 | @register(outgoing=True, pattern=r"^.unlock ?(.*)")
102 | async def rem_locks(event):
103 | input_str = event.pattern_match.group(1).lower()
104 | peer_id = event.chat_id
105 | msg = None
106 | media = None
107 | sticker = None
108 | gif = None
109 | gamee = None
110 | ainline = None
111 | gpoll = None
112 | adduser = None
113 | cpin = None
114 | changeinfo = None
115 | if input_str == "msg":
116 | msg = False
117 | what = "messages"
118 | elif input_str == "media":
119 | media = False
120 | what = "media"
121 | elif input_str == "sticker":
122 | sticker = False
123 | what = "stickers"
124 | elif input_str == "gif":
125 | gif = False
126 | what = "GIFs"
127 | elif input_str == "game":
128 | gamee = False
129 | what = "games"
130 | elif input_str == "inline":
131 | ainline = False
132 | what = "inline bots"
133 | elif input_str == "poll":
134 | gpoll = False
135 | what = "polls"
136 | elif input_str == "invite":
137 | adduser = False
138 | what = "invites"
139 | elif input_str == "pin":
140 | cpin = False
141 | what = "pins"
142 | elif input_str == "info":
143 | changeinfo = False
144 | what = "chat info"
145 | elif input_str == "all":
146 | msg = False
147 | media = False
148 | sticker = False
149 | gif = False
150 | gamee = False
151 | ainline = False
152 | gpoll = False
153 | adduser = False
154 | cpin = False
155 | changeinfo = False
156 | what = "everything"
157 | else:
158 | if not input_str:
159 | await event.edit("`I can't unlock nothing !!`")
160 | return
161 | else:
162 | await event.edit(f"`Invalid unlock type:` {input_str}")
163 | return
164 |
165 | unlock_rights = ChatBannedRights(
166 | until_date=None,
167 | send_messages=msg,
168 | send_media=media,
169 | send_stickers=sticker,
170 | send_gifs=gif,
171 | send_games=gamee,
172 | send_inline=ainline,
173 | send_polls=gpoll,
174 | invite_users=adduser,
175 | pin_messages=cpin,
176 | change_info=changeinfo,
177 | )
178 | try:
179 | await event.client(
180 | EditChatDefaultBannedRightsRequest(
181 | peer=peer_id, banned_rights=unlock_rights
182 | )
183 | )
184 | await event.edit(f"`Unlocked {what} for this chat !!`")
185 | except BaseException as e:
186 | await event.edit(f"`Do I have proper rights for that ??`\n**Error:** {str(e)}")
187 | return
188 |
189 |
190 | CMD_HELP.update(
191 | {
192 | "locks": ".lock or .unlock \
193 | \nUsage: Allows you to lock/unlock some common message types in the chat.\
194 | [NOTE: Requires proper admin rights in the chat !!]\
195 | \n\nAvailable message types to lock/unlock are: \
196 | \n`all, msg, media, sticker, gif, game, inline, poll, invite, pin, info`"
197 | }
198 | )
199 |
--------------------------------------------------------------------------------
/userbot/modules/lyrics.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import os
8 |
9 | import lyricsgenius
10 | from pylast import User
11 |
12 | from userbot import CMD_HELP, GENIUS, LASTFM_USERNAME, lastfm
13 | from userbot.events import register
14 |
15 | if GENIUS is not None:
16 | genius = lyricsgenius.Genius(GENIUS)
17 |
18 |
19 | @register(outgoing=True, pattern="^.lyrics (?:(now)|(.*) - (.*))")
20 | async def lyrics(lyric):
21 | await lyric.edit("`Getting information...`")
22 | if GENIUS is None:
23 | await lyric.edit("`Provide genius access token to Heroku ConfigVars...`")
24 | return False
25 | if lyric.pattern_match.group(1) == "now":
26 | playing = User(LASTFM_USERNAME, lastfm).get_now_playing()
27 | if playing is None:
28 | await lyric.edit("`No information current lastfm scrobbling...`")
29 | return False
30 | artist = playing.get_artist()
31 | song = playing.get_title()
32 | else:
33 | artist = lyric.pattern_match.group(2)
34 | song = lyric.pattern_match.group(3)
35 | await lyric.edit(f"`Searching lyrics for {artist} - {song}...`")
36 | songs = genius.search_song(song, artist)
37 | if songs is None:
38 | await lyric.edit(f"`Song` **{artist} - {song}** `not found...`")
39 | return False
40 | if len(songs.lyrics) > 4096:
41 | await lyric.edit("`Lyrics is too big, view the file to see it.`")
42 | with open("lyrics.txt", "w+") as f:
43 | f.write(f"Search query: \n{artist} - {song}\n\n{songs.lyrics}")
44 | await lyric.client.send_file(
45 | lyric.chat_id,
46 | "lyrics.txt",
47 | reply_to=lyric.id,
48 | )
49 | os.remove("lyrics.txt")
50 | return True
51 | else:
52 | await lyric.edit(
53 | f"**Search query**:\n`{artist}` - `{song}`" f"\n\n```{songs.lyrics}```"
54 | )
55 | return True
56 |
57 |
58 | CMD_HELP.update(
59 | {
60 | "lyrics": ".lyrics ** - **"
61 | "\nUsage: Get lyrics matched artist and song."
62 | "\n\n.lyrics now"
63 | "\nUsage: Get lyrics artist and song from current lastfm scrobbling."
64 | }
65 | )
66 |
--------------------------------------------------------------------------------
/userbot/modules/misc.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # You can find misc modules, which dont fit in anything xD
7 | """ Userbot module for other small commands. """
8 |
9 | import io
10 | import sys
11 | from os import execl
12 | from random import randint
13 | from time import sleep
14 |
15 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP, bot
16 | from userbot.events import register
17 | from userbot.utils import time_formatter
18 |
19 |
20 | @register(outgoing=True, pattern="^.random")
21 | async def randomise(items):
22 | """ For .random command, get a random item from the list of items. """
23 | itemo = (items.text[8:]).split()
24 | if len(itemo) < 2:
25 | await items.edit(
26 | "`2 or more items are required! Check .help random for more info.`"
27 | )
28 | return
29 | index = randint(1, len(itemo) - 1)
30 | await items.edit(
31 | "**Query: **\n`" + items.text[8:] + "`\n**Output: **\n`" + itemo[index] + "`"
32 | )
33 |
34 |
35 | @register(outgoing=True, pattern="^.sleep ([0-9]+)$")
36 | async def sleepybot(time):
37 | """ For .sleep command, let the userbot snooze for a few second. """
38 | counter = int(time.pattern_match.group(1))
39 | await time.edit("`I am sulking and snoozing...`")
40 | if BOTLOG:
41 | str_counter = time_formatter(counter)
42 | await time.client.send_message(
43 | BOTLOG_CHATID,
44 | f"You put the bot to sleep for {str_counter}.",
45 | )
46 | sleep(counter)
47 | await time.edit("`OK, I'm awake now.`")
48 |
49 |
50 | @register(outgoing=True, pattern="^.shutdown$")
51 | async def killbot(shut):
52 | """For .shutdown command, shut the bot down."""
53 | await shut.edit("`Goodbye *Windows XP shutdown sound*....`")
54 | if BOTLOG:
55 | await shut.client.send_message(BOTLOG_CHATID, "#SHUTDOWN \n" "Bot shut down")
56 | await bot.disconnect()
57 |
58 |
59 | @register(outgoing=True, pattern="^.restart$")
60 | async def killdabot(reboot):
61 | await reboot.edit("`*i would be back in a moment*`")
62 | if BOTLOG:
63 | await reboot.client.send_message(BOTLOG_CHATID, "#RESTART \n" "Bot Restarted")
64 | await bot.disconnect()
65 | # Spin a new instance of bot
66 | execl(sys.executable, sys.executable, *sys.argv)
67 | # Shut the existing one down
68 | exit()
69 |
70 |
71 | @register(outgoing=True, pattern="^.readme$")
72 | async def reedme(event):
73 | await event.edit(
74 | "Here's something for you to read:\n"
75 | "\n[One4uBot's README.md file](https://github.com/MoveAngel/One4uBot/blob/sql-extended/README.md)"
76 | "\n[Setup Guide - Basic](https://telegra.ph/How-to-host-a-Telegram-Userbot-07-01-2)"
77 | "\n[Setup Guide - Google Drive](https://telegra.ph/How-To-Setup-Google-Drive-04-03)"
78 | "\n[Setup Guide - LastFM Module](https://telegra.ph/How-to-set-up-LastFM-module-for-Paperplane-userbot-11-02)"
79 | "\n[Setup Guide - From MiHub with Pict](https://www.mihub.my.id/2020/05/jadiuserbot.html)"
80 | "\n[Setup Guide - In Indonesian Language](https://telegra.ph/UserIndoBot-05-21-3)"
81 | "\n[Instant Setup - Generate String Session](https://repl.it/@MoveAngel/UserbotSession?lite=1&outputonly=1)"
82 | "\n*For Instant Setup, click the green button called 'run' before use"
83 | )
84 |
85 |
86 | # Copyright (c) Gegham Zakaryan | 2019
87 | @register(outgoing=True, pattern="^.repeat (.*)")
88 | async def repeat(rep):
89 | cnt, txt = rep.pattern_match.group(1).split(" ", 1)
90 | replyCount = int(cnt)
91 | toBeRepeated = txt
92 |
93 | replyText = toBeRepeated + "\n"
94 |
95 | for i in range(0, replyCount - 1):
96 | replyText += toBeRepeated + "\n"
97 |
98 | await rep.edit(replyText)
99 |
100 |
101 | @register(outgoing=True, pattern="^.repo$")
102 | async def repo_is_here(wannasee):
103 | """ For .repo command, just returns the repo URL. """
104 | await wannasee.edit(
105 | "[Click here](https://github.com/MoveAngel/One4uBot) to open One4uBot's GitHub page."
106 | )
107 |
108 |
109 | @register(outgoing=True, pattern="^.raw$")
110 | async def raw(rawtext):
111 | the_real_message = None
112 | reply_to_id = None
113 | if rawtext.reply_to_msg_id:
114 | previous_message = await rawtext.get_reply_message()
115 | the_real_message = previous_message.stringify()
116 | reply_to_id = rawtext.reply_to_msg_id
117 | else:
118 | the_real_message = rawtext.stringify()
119 | reply_to_id = rawtext.message.id
120 | with io.BytesIO(str.encode(the_real_message)) as out_file:
121 | out_file.name = "raw_message_data.txt"
122 | await rawtext.edit("`Check the userbot log for the decoded message data !!`")
123 | await rawtext.client.send_file(
124 | BOTLOG_CHATID,
125 | out_file,
126 | force_document=True,
127 | allow_cache=False,
128 | reply_to=reply_to_id,
129 | caption="`Here's the decoded message data !!`",
130 | )
131 |
132 |
133 | CMD_HELP.update(
134 | {
135 | "random": ".random ... \
136 | \nUsage: Get a random item from the list of items."
137 | }
138 | )
139 |
140 | CMD_HELP.update(
141 | {
142 | "sleep": ".sleep \
143 | \nUsage: Userbots get tired too. Let yours snooze for a few seconds."
144 | }
145 | )
146 |
147 | CMD_HELP.update(
148 | {
149 | "shutdown": ".shutdown\
150 | \nUsage: Sometimes you need to shut down your bot. Sometimes you just hope to\
151 | hear Windows XP shutdown sound... but you don't."
152 | }
153 | )
154 |
155 | CMD_HELP.update(
156 | {
157 | "repo": ".repo\
158 | \nUsage: If you are curious what makes the userbot work, this is what you need."
159 | }
160 | )
161 |
162 | CMD_HELP.update(
163 | {
164 | "readme": ".readme\
165 | \nUsage: Provide links to setup the userbot and it's modules."
166 | }
167 | )
168 |
169 | CMD_HELP.update(
170 | {
171 | "repeat": ".repeat \
172 | \nUsage: Repeats the text for a number of times. Don't confuse this with spam tho."
173 | }
174 | )
175 |
176 | CMD_HELP.update(
177 | {
178 | "restart": ".restart\
179 | \nUsage: Restarts the bot !!"
180 | }
181 | )
182 |
183 | CMD_HELP.update(
184 | {
185 | "raw": ".raw\
186 | \nUsage: Get detailed JSON-like formatted data about replied message."
187 | }
188 | )
189 |
--------------------------------------------------------------------------------
/userbot/modules/nhentai.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 KeselekPermen69
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | from telethon import events
8 | from telethon.errors.rpcerrorlist import YouBlockedUserError
9 |
10 | from userbot import CMD_HELP, bot
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern="^.nhentai(?: |$)(.*)")
15 | async def _(hentai):
16 | if hentai.fwd_from:
17 | return
18 | link = hentai.pattern_match.group(1)
19 | if not link:
20 | return await hentai.edit("`I can't search nothing`")
21 | chat = "@nHentaiBot"
22 | await hentai.edit("```Processing```")
23 | async with bot.conversation(chat) as conv:
24 | try:
25 | response = conv.wait_event(
26 | events.NewMessage(incoming=True, from_users=424466890)
27 | )
28 | msg = await bot.send_message(chat, link)
29 | response = await response
30 | """ - don't spam notif - """
31 | await bot.send_read_acknowledge(conv.chat_id)
32 | except YouBlockedUserError:
33 | await hentai.reply("```Please unblock @nHentaiBot and try again```")
34 | return
35 | if response.text.startswith("**Sorry I couldn't get manga from**"):
36 | await hentai.edit("```I think this is not the right link```")
37 | else:
38 | await hentai.delete()
39 | await bot.send_message(hentai.chat_id, response.message)
40 | await bot.send_read_acknowledge(hentai.chat_id)
41 | """ - cleanup chat after completed - """
42 | await hentai.client.delete_messages(conv.chat_id, [msg.id, response.id])
43 |
44 |
45 | CMD_HELP.update(
46 | {
47 | "nhentai": ".nhentai \
48 | \nUsage: view nhentai in telegra.ph\n"
49 | }
50 | )
51 |
--------------------------------------------------------------------------------
/userbot/modules/notes.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module containing commands for keeping notes. """
7 |
8 | from asyncio import sleep
9 |
10 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern="^.notes$")
15 | async def notes_active(svd):
16 | """ For .notes command, list all of the notes saved in a chat. """
17 | try:
18 | from userbot.modules.sql_helper.notes_sql import get_notes
19 | except AttributeError:
20 | await svd.edit("`Running on Non-SQL mode!`")
21 | return
22 | message = "`There are no saved notes in this chat`"
23 | notes = get_notes(svd.chat_id)
24 | for note in notes:
25 | if message == "`There are no saved notes in this chat`":
26 | message = "Notes saved in this chat:\n"
27 | message += "`#{}`\n".format(note.keyword)
28 | else:
29 | message += "`#{}`\n".format(note.keyword)
30 | await svd.edit(message)
31 |
32 |
33 | @register(outgoing=True, pattern=r"^.clear (\w*)")
34 | async def remove_notes(clr):
35 | """ For .clear command, clear note with the given name."""
36 | try:
37 | from userbot.modules.sql_helper.notes_sql import rm_note
38 | except AttributeError:
39 | await clr.edit("`Running on Non-SQL mode!`")
40 | return
41 | notename = clr.pattern_match.group(1)
42 | if rm_note(clr.chat_id, notename) is False:
43 | return await clr.edit("`Couldn't find note:` **{}**".format(notename))
44 | else:
45 | return await clr.edit("`Successfully deleted note:` **{}**".format(notename))
46 |
47 |
48 | @register(outgoing=True, pattern=r"^.save (\w*)")
49 | async def add_note(fltr):
50 | """ For .save command, saves notes in a chat. """
51 | try:
52 | from userbot.modules.sql_helper.notes_sql import add_note
53 | except AttributeError:
54 | await fltr.edit("`Running on Non-SQL mode!`")
55 | return
56 | keyword = fltr.pattern_match.group(1)
57 | string = fltr.text.partition(keyword)[2]
58 | msg = await fltr.get_reply_message()
59 | msg_id = None
60 | if msg and msg.media and not string:
61 | if BOTLOG_CHATID:
62 | await fltr.client.send_message(
63 | BOTLOG_CHATID,
64 | f"#NOTE\
65 | \nCHAT ID: {fltr.chat_id}\
66 | \nKEYWORD: {keyword}\
67 | \n\nThe following message is saved as the note's reply data for the chat, please do NOT delete it !!",
68 | )
69 | msg_o = await fltr.client.forward_messages(
70 | entity=BOTLOG_CHATID, messages=msg, from_peer=fltr.chat_id, silent=True
71 | )
72 | msg_id = msg_o.id
73 | else:
74 | await fltr.edit(
75 | "`Saving media as data for the note requires the BOTLOG_CHATID to be set.`"
76 | )
77 | return
78 | elif fltr.reply_to_msg_id and not string:
79 | rep_msg = await fltr.get_reply_message()
80 | string = rep_msg.text
81 | success = "`Note {} successfully. Use` #{} `to get it`"
82 | if add_note(str(fltr.chat_id), keyword, string, msg_id) is False:
83 | return await fltr.edit(success.format("updated", keyword))
84 | else:
85 | return await fltr.edit(success.format("added", keyword))
86 |
87 |
88 | @register(pattern=r"#\w*", disable_edited=True, disable_errors=True, ignore_unsafe=True)
89 | async def incom_note(getnt):
90 | """ Notes logic. """
91 | try:
92 | if not (await getnt.get_sender()).bot:
93 | try:
94 | from userbot.modules.sql_helper.notes_sql import get_note
95 | except AttributeError:
96 | return
97 | notename = getnt.text[1:]
98 | note = get_note(getnt.chat_id, notename)
99 | message_id_to_reply = getnt.message.reply_to_msg_id
100 | if not message_id_to_reply:
101 | message_id_to_reply = None
102 | if note and note.f_mesg_id:
103 | msg_o = await getnt.client.get_messages(
104 | entity=BOTLOG_CHATID, ids=int(note.f_mesg_id)
105 | )
106 | await getnt.client.send_message(
107 | getnt.chat_id,
108 | msg_o.mesage,
109 | reply_to=message_id_to_reply,
110 | file=msg_o.media,
111 | )
112 | elif note and note.reply:
113 | await getnt.client.send_message(
114 | getnt.chat_id, note.reply, reply_to=message_id_to_reply
115 | )
116 | except AttributeError:
117 | pass
118 |
119 |
120 | @register(outgoing=True, pattern="^.rmbotnotes (.*)")
121 | async def kick_marie_notes(kick):
122 | """ For .rmbotnotes command, allows you to kick all \
123 | Marie(or her clones) notes from a chat. """
124 | bot_type = kick.pattern_match.group(1).lower()
125 | if bot_type not in ["marie", "rose"]:
126 | await kick.edit("`That bot is not yet supported!`")
127 | return
128 | await kick.edit("```Will be kicking away all Notes!```")
129 | await sleep(3)
130 | resp = await kick.get_reply_message()
131 | filters = resp.text.split("-")[1:]
132 | for i in filters:
133 | if bot_type == "marie":
134 | await kick.reply("/clear %s" % (i.strip()))
135 | if bot_type == "rose":
136 | i = i.replace("`", "")
137 | await kick.reply("/clear %s" % (i.strip()))
138 | await sleep(0.3)
139 | await kick.respond("```Successfully purged bots notes yaay!```\n Gimme cookies!")
140 | if BOTLOG:
141 | await kick.client.send_message(
142 | BOTLOG_CHATID, "I cleaned all Notes at " + str(kick.chat_id)
143 | )
144 |
145 |
146 | CMD_HELP.update(
147 | {
148 | "notes": "\
149 | #\
150 | \nUsage: Gets the specified note.\
151 | \n\n.save or reply to a message with .save \
152 | \nUsage: Saves the replied message as a note with the notename. (Works with pics, docs, and stickers too!)\
153 | \n\n.notes\
154 | \nUsage: Gets all saved notes in a chat.\
155 | \n\n.clear \
156 | \nUsage: Deletes the specified note.\
157 | \n\n.rmbotnotes \
158 | \nUsage: Removes all notes of admin bots (Currently supported: Marie, Rose and their clones.) in the chat."
159 | }
160 | )
161 |
--------------------------------------------------------------------------------
/userbot/modules/ocr.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import os
8 |
9 | import requests
10 |
11 | from userbot import CMD_HELP, OCR_SPACE_API_KEY, TEMP_DOWNLOAD_DIRECTORY, bot
12 | from userbot.events import register
13 |
14 |
15 | async def ocr_space_file(
16 | filename, overlay=False, api_key=OCR_SPACE_API_KEY, language="eng"
17 | ):
18 | """OCR.space API request with local file.
19 | Python3.5 - not tested on 2.7
20 | :param filename: Your file path & name.
21 | :param overlay: Is OCR.space overlay required in your response.
22 | Defaults to False.
23 | :param api_key: OCR.space API key.
24 | Defaults to 'helloworld'.
25 | :param language: Language code to be used in OCR.
26 | List of available language codes can be found on https://ocr.space/OCRAPI
27 | Defaults to 'en'.
28 | :return: Result in JSON format.
29 | """
30 |
31 | payload = {
32 | "isOverlayRequired": overlay,
33 | "apikey": api_key,
34 | "language": language,
35 | }
36 | with open(filename, "rb") as f:
37 | r = requests.post(
38 | "https://api.ocr.space/parse/image",
39 | files={filename: f},
40 | data=payload,
41 | )
42 | return r.json()
43 |
44 |
45 | @register(pattern=r".ocr (.*)", outgoing=True)
46 | async def ocr(event):
47 | if not OCR_SPACE_API_KEY:
48 | return await event.edit(
49 | "`Error: OCR.Space API key is missing! Add it to environment variables or config.env.`"
50 | )
51 | await event.edit("`Reading...`")
52 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
53 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
54 | lang_code = event.pattern_match.group(1)
55 | downloaded_file_name = await bot.download_media(
56 | await event.get_reply_message(), TEMP_DOWNLOAD_DIRECTORY
57 | )
58 | test_file = await ocr_space_file(filename=downloaded_file_name, language=lang_code)
59 | try:
60 | ParsedText = test_file["ParsedResults"][0]["ParsedText"]
61 | except BaseException:
62 | await event.edit("`Couldn't read it.`\n`I guess I need new glasses.`")
63 | else:
64 | await event.edit(f"`Here's what I could read from it:`\n\n{ParsedText}")
65 | os.remove(downloaded_file_name)
66 |
67 |
68 | CMD_HELP.update(
69 | {
70 | "ocr": ".ocr \
71 | \nUsage: Reply to an image or sticker to extract text from it. \
72 | \n\nGet language codes from [here](https://ocr.space/OCRAPI#PostParameters)."
73 | }
74 | )
75 |
--------------------------------------------------------------------------------
/userbot/modules/pics.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Copyright (C) 2020-2069 The authorship
7 |
8 | from asyncio import sleep
9 | from io import BytesIO
10 |
11 | from telethon import types
12 | from telethon.errors import PhotoInvalidDimensionsError
13 | from telethon.tl.functions.messages import SendMediaRequest
14 |
15 | from userbot import CMD_HELP
16 | from userbot.events import register
17 |
18 |
19 | @register(outgoing=True, pattern=r"^\.pic(?: |$)(.*)")
20 | async def on_file_to_photo(pics):
21 | await pics.edit("Converting Document image to Full Size Image\nPlease wait...")
22 | await sleep(1.5)
23 | await pics.delete()
24 | target = await pics.get_reply_message()
25 | try:
26 | image = target.media.document
27 | except AttributeError:
28 | return
29 | if not image.mime_type.startswith("image/"):
30 | return # This isn't an image
31 | if image.mime_type == "image/webp":
32 | return # Telegram doesn't let you directly send stickers as photos
33 | if image.size > 10 * 2560 * 1440:
34 | return # We'd get PhotoSaveFileInvalidError otherwise
35 |
36 | file = await pics.client.download_media(target, file=BytesIO())
37 | file.seek(0)
38 | img = await pics.client.upload_file(file)
39 | img.name = "image.png"
40 |
41 | try:
42 | await pics.client(
43 | SendMediaRequest(
44 | peer=await pics.get_input_chat(),
45 | media=types.InputMediaUploadedPhoto(img),
46 | message=target.message,
47 | entities=target.entities,
48 | reply_to_msg_id=target.id,
49 | )
50 | )
51 | except PhotoInvalidDimensionsError:
52 | return
53 |
54 |
55 | CMD_HELP.update(
56 | {
57 | "pics": ".pic \
58 | \nUsage: Convert any Document Image to Full Size Image."
59 | }
60 | )
61 |
--------------------------------------------------------------------------------
/userbot/modules/purge.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module for purging unneeded messages(usually spam or ot). """
7 |
8 | from asyncio import sleep
9 |
10 | from telethon.errors import rpcbaseerrors
11 |
12 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP
13 | from userbot.events import register
14 |
15 |
16 | @register(outgoing=True, pattern="^.purge$")
17 | async def fastpurger(purg):
18 | """ For .purge command, purge all messages starting from the reply. """
19 | chat = await purg.get_input_chat()
20 | msgs = []
21 | itermsg = purg.client.iter_messages(chat, min_id=purg.reply_to_msg_id)
22 | count = 0
23 |
24 | if purg.reply_to_msg_id is not None:
25 | async for msg in itermsg:
26 | msgs.append(msg)
27 | count = count + 1
28 | msgs.append(purg.reply_to_msg_id)
29 | if len(msgs) == 100:
30 | await purg.client.delete_messages(chat, msgs)
31 | msgs = []
32 | else:
33 | await purg.edit("`I need a mesasge to start purging from.`")
34 | return
35 |
36 | if msgs:
37 | await purg.client.delete_messages(chat, msgs)
38 | done = await purg.client.send_message(
39 | purg.chat_id,
40 | f"`Fast purge complete!`\
41 | \nPurged {str(count)} messages",
42 | )
43 |
44 | if BOTLOG:
45 | await purg.client.send_message(
46 | BOTLOG_CHATID, "Purge of " + str(count) + " messages done successfully."
47 | )
48 | await sleep(2)
49 | await done.delete()
50 |
51 |
52 | @register(outgoing=True, pattern="^.purgeme")
53 | async def purgeme(delme):
54 | """ For .purgeme, delete x count of your latest message."""
55 | message = delme.text
56 | count = int(message[9:])
57 | i = 1
58 |
59 | async for message in delme.client.iter_messages(delme.chat_id, from_user="me"):
60 | if i > count + 1:
61 | break
62 | i = i + 1
63 | await message.delete()
64 |
65 | smsg = await delme.client.send_message(
66 | delme.chat_id,
67 | "`Purge complete!` Purged " + str(count) + " messages.",
68 | )
69 | if BOTLOG:
70 | await delme.client.send_message(
71 | BOTLOG_CHATID, "Purge of " + str(count) + " messages done successfully."
72 | )
73 | await sleep(2)
74 | i = 1
75 | await smsg.delete()
76 |
77 |
78 | @register(outgoing=True, pattern="^.del$")
79 | async def delete_it(delme):
80 | """ For .del command, delete the replied message. """
81 | msg_src = await delme.get_reply_message()
82 | if delme.reply_to_msg_id:
83 | try:
84 | await msg_src.delete()
85 | await delme.delete()
86 | if BOTLOG:
87 | await delme.client.send_message(
88 | BOTLOG_CHATID, "Deletion of message was successful"
89 | )
90 | except rpcbaseerrors.BadRequestError:
91 | if BOTLOG:
92 | await delme.client.send_message(
93 | BOTLOG_CHATID, "Well, I can't delete a message"
94 | )
95 |
96 |
97 | @register(outgoing=True, pattern="^.edit")
98 | async def editer(edit):
99 | """ For .editme command, edit your last message. """
100 | message = edit.text
101 | chat = await edit.get_input_chat()
102 | self_id = await edit.client.get_peer_id("me")
103 | string = str(message[6:])
104 | i = 1
105 | async for message in edit.client.iter_messages(chat, self_id):
106 | if i == 2:
107 | await message.edit(string)
108 | await edit.delete()
109 | break
110 | i = i + 1
111 | if BOTLOG:
112 | await edit.client.send_message(
113 | BOTLOG_CHATID, "Edit query was executed successfully"
114 | )
115 |
116 |
117 | @register(outgoing=True, pattern="^.sd")
118 | async def selfdestruct(destroy):
119 | """ For .sd command, make seflf-destructable messages. """
120 | message = destroy.text
121 | counter = int(message[4:6])
122 | text = str(destroy.text[6:])
123 | await destroy.delete()
124 | smsg = await destroy.client.send_message(destroy.chat_id, text)
125 | await sleep(counter)
126 | await smsg.delete()
127 | if BOTLOG:
128 | await destroy.client.send_message(BOTLOG_CHATID, "sd query done successfully")
129 |
130 |
131 | CMD_HELP.update(
132 | {
133 | "purge": ".purge\
134 | \nUsage: Purges all messages starting from the reply."
135 | }
136 | )
137 |
138 | CMD_HELP.update(
139 | {
140 | "purgeme": ".purgeme \
141 | \nUsage: Deletes x amount of your latest messages."
142 | }
143 | )
144 |
145 | CMD_HELP.update(
146 | {
147 | "del": ".del\
148 | \nUsage: Deletes the message you replied to."
149 | }
150 | )
151 |
152 | CMD_HELP.update(
153 | {
154 | "edit": ".edit \
155 | \nUsage: Replace your last message with ."
156 | }
157 | )
158 |
159 | CMD_HELP.update(
160 | {
161 | "sd": ".sd \
162 | \nUsage: Creates a message that selfdestructs in x seconds.\
163 | \nKeep the seconds under 100 since it puts your bot to sleep."
164 | }
165 | )
166 |
--------------------------------------------------------------------------------
/userbot/modules/qrcode.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # The entire source code is OSSRPL except 'makeqr and getqr' which is MPL
7 | # License: MPL and OSSRPL
8 | """ Userbot module containing commands related to QR Codes. """
9 |
10 | import asyncio
11 | import os
12 |
13 | import barcode
14 | import qrcode
15 | from barcode.writer import ImageWriter
16 | from bs4 import BeautifulSoup
17 |
18 | from userbot import CMD_HELP, LOGS
19 | from userbot.events import register
20 |
21 |
22 | @register(pattern=r"^.decode$", outgoing=True)
23 | async def parseqr(qr_e):
24 | """ For .decode command, get QR Code/BarCode content from the replied photo. """
25 | downloaded_file_name = await qr_e.client.download_media(
26 | await qr_e.get_reply_message()
27 | )
28 | # parse the Official ZXing webpage to decode the QRCode
29 | command_to_exec = [
30 | "curl",
31 | "-X",
32 | "POST",
33 | "-F",
34 | "f=@" + downloaded_file_name + "",
35 | "https://zxing.org/w/decode",
36 | ]
37 | process = await asyncio.create_subprocess_exec(
38 | *command_to_exec,
39 | # stdout must a pipe to be accessible as process.stdout
40 | stdout=asyncio.subprocess.PIPE,
41 | stderr=asyncio.subprocess.PIPE,
42 | )
43 | # Wait for the subprocess to finish
44 | stdout, stderr = await process.communicate()
45 | e_response = stderr.decode().strip()
46 | t_response = stdout.decode().strip()
47 | os.remove(downloaded_file_name)
48 | if not t_response:
49 | LOGS.info(e_response)
50 | LOGS.info(t_response)
51 | return await qr_e.edit("Failed to decode.")
52 | soup = BeautifulSoup(t_response, "html.parser")
53 | qr_contents = soup.find_all("pre")[0].text
54 | await qr_e.edit(qr_contents)
55 |
56 |
57 | @register(pattern=r".barcode(?: |$)([\s\S]*)", outgoing=True)
58 | async def bq(event):
59 | """ For .barcode command, genrate a barcode containing the given content. """
60 | await event.edit("`Processing..`")
61 | input_str = event.pattern_match.group(1)
62 | message = "SYNTAX: `.barcode `"
63 | reply_msg_id = event.message.id
64 | if input_str:
65 | message = input_str
66 | elif event.reply_to_msg_id:
67 | previous_message = await event.get_reply_message()
68 | reply_msg_id = previous_message.id
69 | if previous_message.media:
70 | downloaded_file_name = await event.client.download_media(previous_message)
71 | m_list = None
72 | with open(downloaded_file_name, "rb") as fd:
73 | m_list = fd.readlines()
74 | message = ""
75 | for m in m_list:
76 | message += m.decode("UTF-8") + "\r\n"
77 | os.remove(downloaded_file_name)
78 | else:
79 | message = previous_message.message
80 | else:
81 | return event.edit("SYNTAX: `.barcode `")
82 |
83 | bar_code_type = "code128"
84 | try:
85 | bar_code_mode_f = barcode.get(bar_code_type, message, writer=ImageWriter())
86 | filename = bar_code_mode_f.save(bar_code_type)
87 | await event.client.send_file(event.chat_id, filename, reply_to=reply_msg_id)
88 | os.remove(filename)
89 | except Exception as e:
90 | return await event.edit(str(e))
91 | await event.delete()
92 |
93 |
94 | @register(pattern=r".makeqr(?: |$)([\s\S]*)", outgoing=True)
95 | async def make_qr(makeqr):
96 | """ For .makeqr command, make a QR Code containing the given content. """
97 | input_str = makeqr.pattern_match.group(1)
98 | message = "SYNTAX: `.makeqr `"
99 | reply_msg_id = None
100 | if input_str:
101 | message = input_str
102 | elif makeqr.reply_to_msg_id:
103 | previous_message = await makeqr.get_reply_message()
104 | reply_msg_id = previous_message.id
105 | if previous_message.media:
106 | downloaded_file_name = await makeqr.client.download_media(previous_message)
107 | m_list = None
108 | with open(downloaded_file_name, "rb") as file:
109 | m_list = file.readlines()
110 | message = ""
111 | for media in m_list:
112 | message += media.decode("UTF-8") + "\r\n"
113 | os.remove(downloaded_file_name)
114 | else:
115 | message = previous_message.message
116 |
117 | qr = qrcode.QRCode(
118 | version=1,
119 | error_correction=qrcode.constants.ERROR_CORRECT_L,
120 | box_size=10,
121 | border=4,
122 | )
123 | qr.add_data(message)
124 | qr.make(fit=True)
125 | img = qr.make_image(fill_color="black", back_color="white")
126 | img.save("img_file.webp", "PNG")
127 | await makeqr.client.send_file(
128 | makeqr.chat_id, "img_file.webp", reply_to=reply_msg_id
129 | )
130 | os.remove("img_file.webp")
131 | await makeqr.delete()
132 |
133 |
134 | CMD_HELP.update(
135 | {
136 | "qr": ".makeqr \
137 | \nUsage: Make a QR Code from the given content.\
138 | \nExample: .makeqr www.google.com\
139 | \nNote: use .decode to get decoded content."
140 | }
141 | )
142 |
143 | CMD_HELP.update(
144 | {
145 | "barcode": ".barcode \
146 | \nUsage: Make a BarCode from the given content.\
147 | \nExample: .barcode www.google.com\
148 | \nNote: use .decode to get decoded content."
149 | }
150 | )
151 |
--------------------------------------------------------------------------------
/userbot/modules/remove_bg.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | # (c) Shrimadhav U K - UniBorg
8 | # Thanks to Prakasaka for porting.
9 |
10 | import io
11 | import os
12 |
13 | import requests
14 | from telethon.tl.types import MessageMediaPhoto
15 |
16 | from userbot import CMD_HELP, REM_BG_API_KEY, TEMP_DOWNLOAD_DIRECTORY
17 | from userbot.events import register
18 |
19 |
20 | @register(outgoing=True, pattern="^.rbg(?: |$)(.*)")
21 | async def kbg(remob):
22 | """ For .rbg command, Remove Image Background. """
23 | if REM_BG_API_KEY is None:
24 | await remob.edit(
25 | "`Error: Remove.BG API key missing! Add it to environment vars or config.env.`"
26 | )
27 | return
28 | input_str = remob.pattern_match.group(1)
29 | message_id = remob.message.id
30 | if remob.reply_to_msg_id:
31 | message_id = remob.reply_to_msg_id
32 | reply_message = await remob.get_reply_message()
33 | await remob.edit("`Processing..`")
34 | try:
35 | if isinstance(
36 | reply_message.media, MessageMediaPhoto
37 | ) or "image" in reply_message.media.document.mime_type.split("/"):
38 | downloaded_file_name = await remob.client.download_media(
39 | reply_message, TEMP_DOWNLOAD_DIRECTORY
40 | )
41 | await remob.edit("`Removing background from this image..`")
42 | output_file_name = await ReTrieveFile(downloaded_file_name)
43 | os.remove(downloaded_file_name)
44 | else:
45 | await remob.edit("`How do I remove the background from this ?`")
46 | except Exception as e:
47 | await remob.edit(str(e))
48 | return
49 | elif input_str:
50 | await remob.edit(
51 | f"`Removing background from online image hosted at`\n{input_str}"
52 | )
53 | output_file_name = await ReTrieveURL(input_str)
54 | else:
55 | await remob.edit("`I need something to remove the background from.`")
56 | return
57 | contentType = output_file_name.headers.get("content-type")
58 | if "image" in contentType:
59 | with io.BytesIO(output_file_name.content) as remove_bg_image:
60 | remove_bg_image.name = "removed_bg.png"
61 | await remob.client.send_file(
62 | remob.chat_id,
63 | remove_bg_image,
64 | caption="Background removed using remove.bg",
65 | force_document=True,
66 | reply_to=message_id,
67 | )
68 | await remob.delete()
69 | else:
70 | await remob.edit(
71 | "**Error (Invalid API key, I guess ?)**\n`{}`".format(
72 | output_file_name.content.decode("UTF-8")
73 | )
74 | )
75 |
76 |
77 | # this method will call the API, and return in the appropriate format
78 | # with the name provided.
79 | async def ReTrieveFile(input_file_name):
80 | headers = {
81 | "X-API-Key": REM_BG_API_KEY,
82 | }
83 | files = {
84 | "image_file": (input_file_name, open(input_file_name, "rb")),
85 | }
86 | r = requests.post(
87 | "https://api.remove.bg/v1.0/removebg",
88 | headers=headers,
89 | files=files,
90 | allow_redirects=True,
91 | stream=True,
92 | )
93 | return r
94 |
95 |
96 | async def ReTrieveURL(input_url):
97 | headers = {
98 | "X-API-Key": REM_BG_API_KEY,
99 | }
100 | data = {"image_url": input_url}
101 | r = requests.post(
102 | "https://api.remove.bg/v1.0/removebg",
103 | headers=headers,
104 | data=data,
105 | allow_redirects=True,
106 | stream=True,
107 | )
108 | return r
109 |
110 |
111 | CMD_HELP.update(
112 | {
113 | "rbg": ".rbg or reply to any image (Warning: does not work on stickers.)\
114 | \nUsage: Removes the background of images, using remove.bg API"
115 | }
116 | )
117 |
--------------------------------------------------------------------------------
/userbot/modules/reverse.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Thanks to @kandnub, for this awesome module !!
4 | #
5 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
6 | # you may not use this file except in compliance with the License.
7 | #
8 | """ Userbot module for reverse searching stickers and images on Google """
9 |
10 | import io
11 | import os
12 | import re
13 | import urllib
14 |
15 | import requests
16 | from bs4 import BeautifulSoup
17 | from PIL import Image
18 |
19 | from userbot import CMD_HELP, bot
20 | from userbot.events import register
21 |
22 | opener = urllib.request.build_opener()
23 | useragent = "Mozilla/5.0 (Linux; Android 9; SM-G960F Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.70 Mobile Safari/537.36"
24 | opener.addheaders = [("User-agent", useragent)]
25 |
26 |
27 | @register(outgoing=True, pattern=r"^.reverse(?: |$)(\d*)")
28 | async def okgoogle(img):
29 | """ For .reverse command, Google search images and stickers. """
30 | if os.path.isfile("okgoogle.png"):
31 | os.remove("okgoogle.png")
32 |
33 | message = await img.get_reply_message()
34 | if message and message.media:
35 | photo = io.BytesIO()
36 | await bot.download_media(message, photo)
37 | else:
38 | await img.edit("`Reply to photo or sticker nigger.`")
39 | return
40 |
41 | if photo:
42 | await img.edit("`Processing...`")
43 | try:
44 | image = Image.open(photo)
45 | except OSError:
46 | await img.edit("`Unsupported sexuality, most likely.`")
47 | return
48 | name = "okgoogle.png"
49 | image.save(name, "PNG")
50 | image.close()
51 | # https://stackoverflow.com/questions/23270175/google-reverse-image-search-using-post-request#28792943
52 | searchUrl = "https://www.google.com/searchbyimage/upload"
53 | multipart = {"encoded_image": (name, open(name, "rb")), "image_content": ""}
54 | response = requests.post(searchUrl, files=multipart, allow_redirects=False)
55 | fetchUrl = response.headers["Location"]
56 |
57 | if response != 400:
58 | await img.edit(
59 | "`Image successfully uploaded to Google. Maybe.`"
60 | "\n`Parsing source now. Maybe.`"
61 | )
62 | else:
63 | await img.edit("`Google told me to fuck off.`")
64 | return
65 |
66 | os.remove(name)
67 | match = await ParseSauce(fetchUrl + "&preferences?hl=en&fg=1#languages")
68 | guess = match["best_guess"]
69 | imgspage = match["similar_images"]
70 |
71 | if guess and imgspage:
72 | await img.edit(f"[{guess}]({fetchUrl})\n\n`Looking for images...`")
73 | else:
74 | await img.edit("`Couldn't find anything for your uglyass.`")
75 | return
76 |
77 | if img.pattern_match.group(1):
78 | lim = img.pattern_match.group(1)
79 | else:
80 | lim = 3
81 | images = await scam(match, lim)
82 | yeet = []
83 | for i in images:
84 | k = requests.get(i)
85 | yeet.append(k.content)
86 | try:
87 | await img.client.send_file(
88 | entity=await img.client.get_input_entity(img.chat_id),
89 | file=yeet,
90 | reply_to=img,
91 | )
92 | except TypeError:
93 | pass
94 | await img.edit(
95 | f"[{guess}]({fetchUrl})\n\n[Visually similar images]({imgspage})"
96 | )
97 |
98 |
99 | async def ParseSauce(googleurl):
100 | """Parse/Scrape the HTML code for the info we want."""
101 |
102 | source = opener.open(googleurl).read()
103 | soup = BeautifulSoup(source, "html.parser")
104 |
105 | results = {"similar_images": "", "best_guess": ""}
106 |
107 | try:
108 | for similar_image in soup.findAll("input", {"class": "gLFyf"}):
109 | url = "https://www.google.com/search?tbm=isch&q=" + urllib.parse.quote_plus(
110 | similar_image.get("value")
111 | )
112 | results["similar_images"] = url
113 | except BaseException:
114 | pass
115 |
116 | for best_guess in soup.findAll("div", attrs={"class": "r5a77d"}):
117 | results["best_guess"] = best_guess.get_text()
118 |
119 | return results
120 |
121 |
122 | async def scam(results, lim):
123 |
124 | single = opener.open(results["similar_images"]).read()
125 | decoded = single.decode("utf-8")
126 |
127 | imglinks = []
128 | counter = 0
129 |
130 | pattern = r"^,\[\"(.*[.png|.jpg|.jpeg])\",[0-9]+,[0-9]+\]$"
131 | oboi = re.findall(pattern, decoded, re.I | re.M)
132 |
133 | for imglink in oboi:
134 | counter += 1
135 | if not counter >= int(lim):
136 | imglinks.append(imglink)
137 | else:
138 | break
139 |
140 | return imglinks
141 |
142 |
143 | CMD_HELP.update(
144 | {
145 | "reverse": ".reverse\
146 | \nUsage: Reply to a pic/sticker to revers-search it on Google Images !!"
147 | }
148 | )
149 |
--------------------------------------------------------------------------------
/userbot/modules/screencapture.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # The entire source code is OSSRPL except 'screencapture' which is MPL
7 | # License: MPL and OSSRPL
8 |
9 | import io
10 | from asyncio import sleep
11 | from re import match
12 |
13 | from userbot import CMD_HELP
14 | from userbot.events import register
15 | from userbot.utils import chrome, options
16 |
17 |
18 | @register(pattern="^.ss (.*)", outgoing=True)
19 | async def capture(url):
20 | """ For .ss command, capture a website's screenshot and send the photo. """
21 | await url.edit("`Processing...`")
22 | chrome_options = await options()
23 | chrome_options.add_argument("--test-type")
24 | chrome_options.add_argument("--ignore-certificate-errors")
25 | chrome_options.arguments.remove("--window-size=1920x1080")
26 | driver = await chrome(chrome_options=chrome_options)
27 | input_str = url.pattern_match.group(1)
28 | link_match = match(r"\bhttps?://.*\.\S+", input_str)
29 | if link_match:
30 | link = link_match.group()
31 | else:
32 | return await url.edit("`I need a valid link to take screenshots from.`")
33 | driver.get(link)
34 | height = driver.execute_script(
35 | "return Math.max(document.body.scrollHeight, document.body.offsetHeight, "
36 | "document.documentElement.clientHeight, document.documentElement.scrollHeight, "
37 | "document.documentElement.offsetHeight);"
38 | )
39 | width = driver.execute_script(
40 | "return Math.max(document.body.scrollWidth, document.body.offsetWidth, "
41 | "document.documentElement.clientWidth, document.documentElement.scrollWidth, "
42 | "document.documentElement.offsetWidth);"
43 | )
44 | driver.set_window_size(width + 125, height + 125)
45 | wait_for = height / 1000
46 | await url.edit(
47 | "`Generating screenshot of the page...`"
48 | f"\n`Height of page = {height}px`"
49 | f"\n`Width of page = {width}px`"
50 | f"\n`Waiting ({int(wait_for)}s) for the page to load.`"
51 | )
52 | await sleep(int(wait_for))
53 | im_png = driver.get_screenshot_as_png()
54 | # saves screenshot of entire page
55 | driver.quit()
56 | message_id = url.message.id
57 | if url.reply_to_msg_id:
58 | message_id = url.reply_to_msg_id
59 | with io.BytesIO(im_png) as out_file:
60 | out_file.name = "screencapture.png"
61 | await url.edit("`Uploading screenshot as file..`")
62 | await url.client.send_file(
63 | url.chat_id,
64 | out_file,
65 | caption=input_str,
66 | force_document=True,
67 | reply_to=message_id,
68 | )
69 | await url.delete()
70 |
71 |
72 | CMD_HELP.update(
73 | {
74 | "ss": ".ss \
75 | \nUsage: Takes a screenshot of a website and sends the screenshot.\
76 | \nExample of a valid URL : `https://www.google.com`"
77 | }
78 | )
79 |
--------------------------------------------------------------------------------
/userbot/modules/sed.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # The entire source code is OSSRPL except 'sed' which is GPLv3
7 | # License: GPLv3 and OSSRPL
8 | """ Userbot command for sed. """
9 |
10 | import re
11 | from sre_constants import error as sre_err
12 |
13 | from userbot import CMD_HELP
14 | from userbot.events import register
15 |
16 | DELIMITERS = ("/", ":", "|", "_")
17 |
18 |
19 | async def separate_sed(sed_string):
20 | """ Separate sed arguments. """
21 |
22 | if len(sed_string) < 2:
23 | return
24 |
25 | if (
26 | len(sed_string) >= 2
27 | and sed_string[2] in DELIMITERS
28 | and sed_string.count(sed_string[2]) >= 2
29 | ):
30 | delim = sed_string[2]
31 | start = counter = 3
32 | while counter < len(sed_string):
33 | if sed_string[counter] == "\\":
34 | counter += 1
35 |
36 | elif sed_string[counter] == delim:
37 | replace = sed_string[start:counter]
38 | counter += 1
39 | start = counter
40 | break
41 |
42 | counter += 1
43 |
44 | else:
45 | return None
46 |
47 | while counter < len(sed_string):
48 | if (
49 | sed_string[counter] == "\\"
50 | and counter + 1 < len(sed_string)
51 | and sed_string[counter + 1] == delim
52 | ):
53 | sed_string = sed_string[:counter] + sed_string[counter + 1 :]
54 |
55 | elif sed_string[counter] == delim:
56 | replace_with = sed_string[start:counter]
57 | counter += 1
58 | break
59 |
60 | counter += 1
61 | else:
62 | return replace, sed_string[start:], ""
63 |
64 | flags = ""
65 | if counter < len(sed_string):
66 | flags = sed_string[counter:]
67 | return replace, replace_with, flags.lower()
68 | return None
69 |
70 |
71 | @register(outgoing=True, pattern="^.s")
72 | async def sed(command):
73 | """ For sed command, use sed on Telegram. """
74 | sed_result = await separate_sed(command.text)
75 | textx = await command.get_reply_message()
76 | if sed_result:
77 | if textx:
78 | to_fix = textx.text
79 | else:
80 | await command.edit(
81 | "`Master, I don't have brains. Well you too don't I guess.`"
82 | )
83 | return
84 |
85 | repl, repl_with, flags = sed_result
86 |
87 | if not repl:
88 | await command.edit(
89 | "`Master, I don't have brains. Well you too don't I guess.`"
90 | )
91 | return
92 |
93 | try:
94 | check = re.match(repl, to_fix, flags=re.IGNORECASE)
95 | if check and check.group(0).lower() == to_fix.lower():
96 | await command.edit("`Boi!, that's a reply. Don't use sed`")
97 | return
98 |
99 | if "i" in flags and "g" in flags:
100 | text = re.sub(repl, repl_with, to_fix, flags=re.I).strip()
101 | elif "i" in flags:
102 | text = re.sub(repl, repl_with, to_fix, count=1, flags=re.I).strip()
103 | elif "g" in flags:
104 | text = re.sub(repl, repl_with, to_fix).strip()
105 | else:
106 | text = re.sub(repl, repl_with, to_fix, count=1).strip()
107 | except sre_err:
108 | await command.edit("B O I! [Learn Regex](https://regexone.com)")
109 | return
110 | if text:
111 | await command.edit(f"Did you mean? \n\n{text}")
112 |
113 |
114 | CMD_HELP.update(
115 | {
116 | "sed": ".s\
117 | \nUsage: Replaces a word or words using sed.\
118 | \nDelimiters: `/, :, |, _`"
119 | }
120 | )
121 |
--------------------------------------------------------------------------------
/userbot/modules/snips.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module containing commands for keeping global notes. """
7 |
8 | from userbot import BOTLOG_CHATID, CMD_HELP
9 | from userbot.events import register
10 |
11 |
12 | @register(outgoing=True, pattern=r"\$\w*", ignore_unsafe=True, disable_errors=True)
13 | async def on_snip(event):
14 | """ Snips logic. """
15 | try:
16 | from userbot.modules.sql_helper.snips_sql import get_snip
17 | except AttributeError:
18 | return
19 | name = event.text[1:]
20 | snip = get_snip(name)
21 | message_id_to_reply = event.message.reply_to_msg_id
22 | if not message_id_to_reply:
23 | message_id_to_reply = None
24 | if snip and snip.f_mesg_id:
25 | msg_o = await event.client.get_messages(
26 | entity=BOTLOG_CHATID, ids=int(snip.f_mesg_id)
27 | )
28 | await event.client.send_message(
29 | event.chat_id, msg_o.message, reply_to=message_id_to_reply, file=msg_o.media
30 | )
31 | elif snip and snip.reply:
32 | await event.client.send_message(
33 | event.chat_id, snip.reply, reply_to=message_id_to_reply
34 | )
35 |
36 |
37 | @register(outgoing=True, pattern=r"^.snip (\w*)")
38 | async def on_snip_save(event):
39 | """ For .snip command, saves snips for future use. """
40 | try:
41 | from userbot.modules.sql_helper.snips_sql import add_snip
42 | except AtrributeError:
43 | await event.edit("`Running on Non-SQL mode!`")
44 | return
45 | keyword = event.pattern_match.group(1)
46 | string = event.text.partition(keyword)[2]
47 | msg = await event.get_reply_message()
48 | msg_id = None
49 | if msg and msg.media and not string:
50 | if BOTLOG_CHATID:
51 | await event.client.send_message(
52 | BOTLOG_CHATID,
53 | f"#SNIP\
54 | \nKEYWORD: {keyword}\
55 | \n\nThe following message is saved as the data for the snip, please do NOT delete it !!",
56 | )
57 | msg_o = await event.client.forward_messages(
58 | entity=BOTLOG_CHATID, messages=msg, from_peer=event.chat_id, silent=True
59 | )
60 | msg_id = msg_o.id
61 | else:
62 | await event.edit(
63 | "`Saving snips with media requires the BOTLOG_CHATID to be set.`"
64 | )
65 | return
66 | elif event.reply_to_msg_id and not string:
67 | rep_msg = await event.get_reply_message()
68 | string = rep_msg.text
69 | success = "`Snip {} successfully. Use` **${}** `anywhere to get it`"
70 | if add_snip(keyword, string, msg_id) is False:
71 | await event.edit(success.format("updated", keyword))
72 | else:
73 | await event.edit(success.format("saved", keyword))
74 |
75 |
76 | @register(outgoing=True, pattern="^.snips$")
77 | async def on_snip_list(event):
78 | """ For .snips command, lists snips saved by you. """
79 | try:
80 | from userbot.modules.sql_helper.snips_sql import get_snips
81 | except AttributeError:
82 | await event.edit("`Running on Non-SQL mode!`")
83 | return
84 |
85 | message = "`No snips available right now.`"
86 | all_snips = get_snips()
87 | for a_snip in all_snips:
88 | if message == "`No snips available right now.`":
89 | message = "Available snips:\n"
90 | message += f"`${a_snip.snip}`\n"
91 | else:
92 | message += f"`${a_snip.snip}`\n"
93 |
94 | await event.edit(message)
95 |
96 |
97 | @register(outgoing=True, pattern=r"^.remsnip (\w*)")
98 | async def on_snip_delete(event):
99 | """ For .remsnip command, deletes a snip. """
100 | try:
101 | from userbot.modules.sql_helper.snips_sql import remove_snip
102 | except AttributeError:
103 | await event.edit("`Running on Non-SQL mode!`")
104 | return
105 | name = event.pattern_match.group(1)
106 | if remove_snip(name) is True:
107 | await event.edit(f"`Successfully deleted snip:` **{name}**")
108 | else:
109 | await event.edit(f"`Couldn't find snip:` **{name}**")
110 |
111 |
112 | CMD_HELP.update(
113 | {
114 | "snips": "\
115 | $\
116 | \nUsage: Gets the specified snip, anywhere.\
117 | \n\n.snip or reply to a message with .snip \
118 | \nUsage: Saves the message as a snip (global note) with the name. (Works with pics, docs, and stickers too!)\
119 | \n\n.snips\
120 | \nUsage: Gets all saved snips.\
121 | \n\n.remsnip \
122 | \nUsage: Deletes the specified snip.\
123 | "
124 | }
125 | )
126 |
--------------------------------------------------------------------------------
/userbot/modules/spam.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import asyncio
8 | from asyncio import sleep
9 |
10 | from userbot import BOTLOG, BOTLOG_CHATID, CMD_HELP
11 | from userbot.events import register
12 |
13 |
14 | @register(outgoing=True, pattern="^.cspam (.*)")
15 | async def leter_spam(cspammer):
16 | cspam = str(cspammer.pattern_match.group(1))
17 | message = cspam.replace(" ", "")
18 | await cspammer.delete()
19 | for letter in message:
20 | await cspammer.respond(letter)
21 | if BOTLOG:
22 | await cspammer.client.send_message(
23 | BOTLOG_CHATID, "#CSPAM\n" "TSpam was executed successfully"
24 | )
25 |
26 |
27 | @register(outgoing=True, pattern="^.wspam (.*)")
28 | async def word_spam(wspammer):
29 | wspam = str(wspammer.pattern_match.group(1))
30 | message = wspam.split()
31 | await wspammer.delete()
32 | for word in message:
33 | await wspammer.respond(word)
34 | if BOTLOG:
35 | await wspammer.client.send_message(
36 | BOTLOG_CHATID, "#WSPAM\n" "WSpam was executed successfully"
37 | )
38 |
39 |
40 | @register(outgoing=True, pattern="^.spam (.*)")
41 | async def spammer(spamm):
42 | counter = int(spamm.pattern_match.group(1).split(" ", 1)[0])
43 | spam_message = str(spamm.pattern_match.group(1).split(" ", 1)[1])
44 | await spamm.delete()
45 | await asyncio.wait([spamm.respond(spam_message) for i in range(counter)])
46 | if BOTLOG:
47 | await spamm.client.send_message(
48 | BOTLOG_CHATID, "#SPAM\n" "Spam was executed successfully"
49 | )
50 |
51 |
52 | @register(outgoing=True, pattern="^.picspam")
53 | async def tiny_pic_spam(pspam):
54 | message = pspam.text
55 | text = message.split()
56 | counter = int(text[1])
57 | link = str(text[2])
58 | await pspam.delete()
59 | for _ in range(1, counter):
60 | await pspam.client.send_file(pspam.chat_id, link)
61 | if BOTLOG:
62 | await pspam.client.send_message(
63 | BOTLOG_CHATID, "#PICSPAM\n" "PicSpam was executed successfully"
64 | )
65 |
66 |
67 | @register(outgoing=True, pattern="^.delayspam (.*)")
68 | async def dspammer(dspam):
69 | spamDelay = float(dspam.pattern_match.group(1).split(" ", 2)[0])
70 | counter = int(dspam.pattern_match.group(1).split(" ", 2)[1])
71 | spam_message = str(dspam.pattern_match.group(1).split(" ", 2)[2])
72 | await dspam.delete()
73 | for _ in range(1, counter):
74 | await dspam.respond(spam_message)
75 | await sleep(spamDelay)
76 | if BOTLOG:
77 | await dspam.client.send_message(
78 | BOTLOG_CHATID, "#DelaySPAM\n" "DelaySpam was executed successfully"
79 | )
80 |
81 |
82 | CMD_HELP.update(
83 | {
84 | "spam": ".cspam \
85 | \nUsage: Spam the text letter by letter.\
86 | \n\n.spam \
87 | \nUsage: Floods text in the chat !!\
88 | \n\n.wspam \
89 | \nUsage: Spam the text word by word.\
90 | \n\n.picspam \
91 | \nUsage: As if text spam was not enough !!\
92 | \n\n.delayspam \
93 | \nUsage: .bigspam but with custom delay.\
94 | \n\n\nNOTE : Spam at your own risk !!"
95 | }
96 | )
97 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoveAngel/One4uBot/e153f632feb419bbc93909198e809c513cd0e988/userbot/modules/sql_helper/.DS_Store
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/__init__.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import create_engine
2 | from sqlalchemy.ext.declarative import declarative_base
3 | from sqlalchemy.orm import sessionmaker, scoped_session
4 | from userbot import DB_URI
5 |
6 | BASE = declarative_base()
7 |
8 |
9 | def start() -> scoped_session:
10 | engine = create_engine(DB_URI)
11 | BASE.metadata.bind = engine
12 | BASE.metadata.create_all(engine)
13 | return scoped_session(sessionmaker(bind=engine, autoflush=False))
14 |
15 |
16 | SESSION = start()
17 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/blacklist_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 | from sqlalchemy import Column, String, UnicodeText
6 | import threading
7 |
8 |
9 | class BlackListFilters(BASE):
10 | __tablename__ = "blacklist"
11 | chat_id = Column(String(14), primary_key=True)
12 | trigger = Column(UnicodeText, primary_key=True, nullable=False)
13 |
14 | def __init__(self, chat_id, trigger):
15 | self.chat_id = str(chat_id) # ensure string
16 | self.trigger = trigger
17 |
18 | def __repr__(self):
19 | return "" % (self.trigger, self.chat_id)
20 |
21 | def __eq__(self, other):
22 | return bool(isinstance(other, BlackListFilters)
23 | and self.chat_id == other.chat_id
24 | and self.trigger == other.trigger)
25 |
26 |
27 | BlackListFilters.__table__.create(checkfirst=True)
28 |
29 | BLACKLIST_FILTER_INSERTION_LOCK = threading.RLock()
30 |
31 | CHAT_BLACKLISTS = {}
32 |
33 |
34 | def add_to_blacklist(chat_id, trigger):
35 | with BLACKLIST_FILTER_INSERTION_LOCK:
36 | blacklist_filt = BlackListFilters(str(chat_id), trigger)
37 |
38 | SESSION.merge(blacklist_filt) # merge to avoid duplicate key issues
39 | SESSION.commit()
40 | CHAT_BLACKLISTS.setdefault(str(chat_id), set()).add(trigger)
41 |
42 |
43 | def rm_from_blacklist(chat_id, trigger):
44 | with BLACKLIST_FILTER_INSERTION_LOCK:
45 | blacklist_filt = SESSION.query(
46 | BlackListFilters).get((str(chat_id), trigger))
47 | if blacklist_filt:
48 | if trigger in CHAT_BLACKLISTS.get(
49 | str(chat_id), set()): # sanity check
50 | CHAT_BLACKLISTS.get(str(chat_id), set()).remove(trigger)
51 |
52 | SESSION.delete(blacklist_filt)
53 | SESSION.commit()
54 | return True
55 |
56 | SESSION.close()
57 | return False
58 |
59 |
60 | def get_chat_blacklist(chat_id):
61 | return CHAT_BLACKLISTS.get(str(chat_id), set())
62 |
63 |
64 | def num_blacklist_filters():
65 | try:
66 | return SESSION.query(BlackListFilters).count()
67 | finally:
68 | SESSION.close()
69 |
70 |
71 | def num_blacklist_chat_filters(chat_id):
72 | try:
73 | return SESSION.query(BlackListFilters.chat_id).filter(
74 | BlackListFilters.chat_id == str(chat_id)).count()
75 | finally:
76 | SESSION.close()
77 |
78 |
79 | def num_blacklist_filter_chats():
80 | try:
81 | return SESSION.query(
82 | func.count(
83 | distinct(
84 | BlackListFilters.chat_id))).scalar()
85 | finally:
86 | SESSION.close()
87 |
88 |
89 | def __load_chat_blacklists():
90 | global CHAT_BLACKLISTS
91 | try:
92 | chats = SESSION.query(BlackListFilters.chat_id).distinct().all()
93 | for (chat_id,) in chats: # remove tuple by ( ,)
94 | CHAT_BLACKLISTS[chat_id] = []
95 |
96 | all_filters = SESSION.query(BlackListFilters).all()
97 | for x in all_filters:
98 | CHAT_BLACKLISTS[x.chat_id] += [x.trigger]
99 |
100 | CHAT_BLACKLISTS = {x: set(y) for x, y in CHAT_BLACKLISTS.items()}
101 |
102 | finally:
103 | SESSION.close()
104 |
105 |
106 | __load_chat_blacklists()
107 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/fban_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, String, UnicodeText
7 |
8 |
9 | class Fban(BASE):
10 | __tablename__ = "fban"
11 | chat_id = Column(String(14), primary_key=True)
12 | fed_name = Column(UnicodeText)
13 |
14 | def __init__(self, chat_id, fed_name):
15 | self.chat_id = str(chat_id)
16 | self.fed_name = fed_name
17 |
18 |
19 | Fban.__table__.create(checkfirst=True)
20 |
21 |
22 | def get_flist():
23 | try:
24 | return SESSION.query(Fban).all()
25 | finally:
26 | SESSION.close()
27 |
28 |
29 | def add_flist(chat_id, fed_name):
30 | adder = Fban(str(chat_id), fed_name)
31 | SESSION.add(adder)
32 | SESSION.commit()
33 |
34 |
35 | def del_flist(chat_id):
36 | rem = SESSION.query(Fban).get(str(chat_id))
37 | if rem:
38 | SESSION.delete(rem)
39 | SESSION.commit()
40 |
41 |
42 | def del_flist_all():
43 | SESSION.execute("""TRUNCATE TABLE fban""")
44 | SESSION.commit()
45 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/filter_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 | from sqlalchemy import Column, UnicodeText, Numeric, String
6 |
7 |
8 | class Filters(BASE):
9 | __tablename__ = "filters"
10 | chat_id = Column(String(14), primary_key=True)
11 | keyword = Column(UnicodeText, primary_key=True, nullable=False)
12 | reply = Column(UnicodeText)
13 | f_mesg_id = Column(Numeric)
14 |
15 | def __init__(self, chat_id, keyword, reply, f_mesg_id):
16 | self.chat_id = str(chat_id)
17 | self.keyword = keyword
18 | self.reply = reply
19 | self.f_mesg_id = f_mesg_id
20 |
21 | def __eq__(self, other):
22 | return bool(
23 | isinstance(other, Filters) and self.chat_id == other.chat_id
24 | and self.keyword == other.keyword)
25 |
26 |
27 | Filters.__table__.create(checkfirst=True)
28 |
29 |
30 | def get_filter(chat_id, keyword):
31 | try:
32 | return SESSION.query(Filters).get((str(chat_id), keyword))
33 | finally:
34 | SESSION.close()
35 |
36 |
37 | def get_filters(chat_id):
38 | try:
39 | return SESSION.query(Filters).filter(
40 | Filters.chat_id == str(chat_id)).all()
41 | finally:
42 | SESSION.close()
43 |
44 |
45 | def add_filter(chat_id, keyword, reply, f_mesg_id):
46 | to_check = get_filter(chat_id, keyword)
47 | if not to_check:
48 | adder = Filters(str(chat_id), keyword, reply, f_mesg_id)
49 | SESSION.add(adder)
50 | SESSION.commit()
51 | return True
52 | else:
53 | rem = SESSION.query(Filters).get((str(chat_id), keyword))
54 | SESSION.delete(rem)
55 | SESSION.commit()
56 | adder = Filters(str(chat_id), keyword, reply, f_mesg_id)
57 | SESSION.add(adder)
58 | SESSION.commit()
59 | return False
60 |
61 |
62 | def remove_filter(chat_id, keyword):
63 | to_check = get_filter(chat_id, keyword)
64 | if not to_check:
65 | return False
66 | else:
67 | rem = SESSION.query(Filters).get((str(chat_id), keyword))
68 | SESSION.delete(rem)
69 | SESSION.commit()
70 | return True
71 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/globals.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, String, UnicodeText
7 |
8 |
9 | class Globals(BASE):
10 | __tablename__ = "globals"
11 | variable = Column(String, primary_key=True, nullable=False)
12 | value = Column(UnicodeText, primary_key=True, nullable=False)
13 |
14 | def __init__(self, variable, value):
15 | self.variable = str(variable)
16 | self.value = value
17 |
18 |
19 | Globals.__table__.create(checkfirst=True)
20 |
21 |
22 | def gvarstatus(variable):
23 | try:
24 | return SESSION.query(Globals).filter(
25 | Globals.variable == str(variable)).first().value
26 | except BaseException:
27 | return None
28 | finally:
29 | SESSION.close()
30 |
31 |
32 | def addgvar(variable, value):
33 | if SESSION.query(Globals).filter(
34 | Globals.variable == str(variable)).one_or_none():
35 | delgvar(variable)
36 | adder = Globals(str(variable), value)
37 | SESSION.add(adder)
38 | SESSION.commit()
39 |
40 |
41 | def delgvar(variable):
42 | rem = SESSION.query(Globals).filter(Globals.variable == str(variable))\
43 | .delete(synchronize_session="fetch")
44 | if rem:
45 | SESSION.commit()
46 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/gmute_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, String
7 |
8 |
9 | class GMute(BASE):
10 | __tablename__ = "gmute"
11 | sender = Column(String(14), primary_key=True)
12 |
13 | def __init__(self, sender):
14 | self.sender = str(sender)
15 |
16 |
17 | GMute.__table__.create(checkfirst=True)
18 |
19 |
20 | def is_gmuted(sender_id):
21 | try:
22 | return SESSION.query(GMute).all()
23 | except BaseException:
24 | return None
25 | finally:
26 | SESSION.close()
27 |
28 |
29 | def gmute(sender):
30 | adder = GMute(str(sender))
31 | SESSION.add(adder)
32 | SESSION.commit()
33 |
34 |
35 | def ungmute(sender):
36 | rem = SESSION.query(GMute).get((str(sender)))
37 | if rem:
38 | SESSION.delete(rem)
39 | SESSION.commit()
40 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/google_drive_sql.py:
--------------------------------------------------------------------------------
1 | from userbot.modules.sql_helper import SESSION, BASE
2 | from sqlalchemy import Column, String, Text
3 |
4 |
5 | class GoogleDriveCreds(BASE):
6 | __tablename__ = 'gdrive'
7 | user = Column(String, primary_key=True)
8 | credentials = Column(Text, nullable=False)
9 |
10 | def __init__(self, user):
11 | self.user = user
12 |
13 |
14 | GoogleDriveCreds.__table__.create(checkfirst=True)
15 |
16 |
17 | def save_credentials(user, credentials):
18 | saved_credentials = SESSION.query(GoogleDriveCreds).get(user)
19 | if not saved_credentials:
20 | saved_credentials = GoogleDriveCreds(user)
21 |
22 | saved_credentials.credentials = credentials
23 |
24 | SESSION.add(saved_credentials)
25 | SESSION.commit()
26 | return True
27 |
28 |
29 | def get_credentials(user):
30 | try:
31 | saved_credentials = SESSION.query(GoogleDriveCreds).get(user)
32 | creds = None
33 |
34 | if saved_credentials is not None:
35 | creds = saved_credentials.credentials
36 | return creds
37 | finally:
38 | SESSION.close()
39 |
40 |
41 | def clear_credentials(user):
42 | saved_credentials = SESSION.query(GoogleDriveCreds).get(user)
43 | if saved_credentials:
44 | SESSION.delete(saved_credentials)
45 | SESSION.commit()
46 | return True
47 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/keep_read_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, String
7 |
8 |
9 | class KRead(BASE):
10 | __tablename__ = "kread"
11 | groupid = Column(String(14), primary_key=True)
12 |
13 | def __init__(self, sender):
14 | self.groupid = str(sender)
15 |
16 |
17 | KRead.__table__.create(checkfirst=True)
18 |
19 |
20 | def is_kread():
21 | try:
22 | return SESSION.query(KRead).all()
23 | except BaseException:
24 | return None
25 | finally:
26 | SESSION.close()
27 |
28 |
29 | def kread(chat):
30 | adder = KRead(str(chat))
31 | SESSION.add(adder)
32 | SESSION.commit()
33 |
34 |
35 | def unkread(chat):
36 | rem = SESSION.query(KRead).get((str(chat)))
37 | if rem:
38 | SESSION.delete(rem)
39 | SESSION.commit()
40 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/lydia_sql.py:
--------------------------------------------------------------------------------
1 | from sqlalchemy import Column, Numeric, UnicodeText
2 | from sql_helpers import SESSION, BASE
3 |
4 |
5 | class LydiaAI(BASE):
6 | __tablename__ = "lydia_ai"
7 | user_id = Column(Numeric, primary_key=True)
8 | chat_id = Column(Numeric, primary_key=True)
9 | session_id = Column(UnicodeText)
10 | session_expires = Column(Numeric)
11 |
12 | def __init__(
13 | self,
14 | user_id,
15 | chat_id,
16 | session_id,
17 | session_expires
18 | ):
19 | self.user_id = user_id
20 | self.chat_id = chat_id
21 | self.session_id = session_id
22 | self.session_expires = session_expires
23 |
24 |
25 | LydiaAI.__table__.create(checkfirst=True)
26 |
27 |
28 | def get_s(user_id, chat_id):
29 | try:
30 | return SESSION.query(LydiaAI).get((user_id, chat_id))
31 | except BaseException:
32 | return None
33 | finally:
34 | SESSION.close()
35 |
36 |
37 | def get_all_s():
38 | try:
39 | return SESSION.query(LydiaAI).all()
40 | except BaseException:
41 | return None
42 | finally:
43 | SESSION.close()
44 |
45 |
46 | def add_s(
47 | user_id,
48 | chat_id,
49 | session_id,
50 | session_expires
51 | ):
52 | adder = SESSION.query(LydiaAI).get((user_id, chat_id))
53 | if adder:
54 | adder.session_id = session_id
55 | adder.session_expires = session_expires
56 | else:
57 | adder = LydiaAI(
58 | user_id,
59 | chat_id,
60 | session_id,
61 | session_expires
62 | )
63 | SESSION.add(adder)
64 | SESSION.commit()
65 |
66 |
67 | def remove_s(
68 | user_id,
69 | chat_id
70 | ):
71 | note = SESSION.query(LydiaAI).get((user_id, chat_id))
72 | if note:
73 | SESSION.delete(note)
74 | SESSION.commit()
75 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/notes_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 | from sqlalchemy import Column, UnicodeText, Numeric, String
6 |
7 |
8 | class Notes(BASE):
9 | __tablename__ = "notes"
10 | chat_id = Column(String(14), primary_key=True)
11 | keyword = Column(UnicodeText, primary_key=True, nullable=False)
12 | reply = Column(UnicodeText)
13 | f_mesg_id = Column(Numeric)
14 |
15 | def __init__(self, chat_id, keyword, reply, f_mesg_id):
16 | self.chat_id = str(chat_id)
17 | self.keyword = keyword
18 | self.reply = reply
19 | self.f_mesg_id = f_mesg_id
20 |
21 |
22 | Notes.__table__.create(checkfirst=True)
23 |
24 |
25 | def get_note(chat_id, keyword):
26 | try:
27 | return SESSION.query(Notes).get((str(chat_id), keyword))
28 | finally:
29 | SESSION.close()
30 |
31 |
32 | def get_notes(chat_id):
33 | try:
34 | return SESSION.query(Notes).filter(Notes.chat_id == str(chat_id)).all()
35 | finally:
36 | SESSION.close()
37 |
38 |
39 | def add_note(chat_id, keyword, reply, f_mesg_id):
40 | to_check = get_note(chat_id, keyword)
41 | if not to_check:
42 | adder = Notes(str(chat_id), keyword, reply, f_mesg_id)
43 | SESSION.add(adder)
44 | SESSION.commit()
45 | return True
46 | else:
47 | rem = SESSION.query(Notes).get((str(chat_id), keyword))
48 | SESSION.delete(rem)
49 | SESSION.commit()
50 | adder = Notes(str(chat_id), keyword, reply, f_mesg_id)
51 | SESSION.add(adder)
52 | SESSION.commit()
53 | return False
54 |
55 |
56 | def rm_note(chat_id, keyword):
57 | to_check = get_note(chat_id, keyword)
58 | if not to_check:
59 | return False
60 | else:
61 | rem = SESSION.query(Notes).get((str(chat_id), keyword))
62 | SESSION.delete(rem)
63 | SESSION.commit()
64 | return True
65 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/pm_permit_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 | from sqlalchemy import Column, String
6 |
7 |
8 | class PMPermit(BASE):
9 | __tablename__ = "pmpermit"
10 | chat_id = Column(String(14), primary_key=True)
11 |
12 | def __init__(self, chat_id):
13 | self.chat_id = str(chat_id) # ensure string
14 |
15 |
16 | PMPermit.__table__.create(checkfirst=True)
17 |
18 |
19 | def is_approved(chat_id):
20 | try:
21 | return SESSION.query(PMPermit).filter(
22 | PMPermit.chat_id == str(chat_id)).one()
23 | except BaseException:
24 | return None
25 | finally:
26 | SESSION.close()
27 |
28 |
29 | def approve(chat_id):
30 | adder = PMPermit(str(chat_id))
31 | SESSION.add(adder)
32 | SESSION.commit()
33 |
34 |
35 | def dissprove(chat_id):
36 | rem = SESSION.query(PMPermit).get(str(chat_id))
37 | if rem:
38 | SESSION.delete(rem)
39 | SESSION.commit()
40 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/snips_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, Numeric, UnicodeText
7 |
8 |
9 | class Snips(BASE):
10 | __tablename__ = "snips"
11 | snip = Column(UnicodeText, primary_key=True)
12 | reply = Column(UnicodeText)
13 | f_mesg_id = Column(Numeric)
14 |
15 | def __init__(self, snip, reply, f_mesg_id):
16 | self.snip = snip
17 | self.reply = reply
18 | self.f_mesg_id = f_mesg_id
19 |
20 |
21 | Snips.__table__.create(checkfirst=True)
22 |
23 |
24 | def get_snip(keyword):
25 | try:
26 | return SESSION.query(Snips).get(keyword)
27 | finally:
28 | SESSION.close()
29 |
30 |
31 | def get_snips():
32 | try:
33 | return SESSION.query(Snips).all()
34 | finally:
35 | SESSION.close()
36 |
37 |
38 | def add_snip(keyword, reply, f_mesg_id):
39 | to_check = get_snip(keyword)
40 | if not to_check:
41 | adder = Snips(keyword, reply, f_mesg_id)
42 | SESSION.add(adder)
43 | SESSION.commit()
44 | return True
45 | else:
46 | rem = SESSION.query(Snips).filter(Snips.snip == keyword)
47 | SESSION.delete(rem)
48 | SESSION.commit()
49 | adder = Snips(keyword, reply, f_mesg_id)
50 | SESSION.add(adder)
51 | SESSION.commit()
52 | return False
53 |
54 |
55 | def remove_snip(keyword):
56 | to_check = get_snip(keyword)
57 | if not to_check:
58 | return False
59 | else:
60 | rem = SESSION.query(Snips).filter(Snips.snip == keyword)
61 | rem.delete()
62 | SESSION.commit()
63 | return True
64 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/spam_mute_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import Column, String
7 |
8 |
9 | class Mute(BASE):
10 | __tablename__ = "muted"
11 | chat_id = Column(String(14), primary_key=True)
12 | sender = Column(String(14), primary_key=True)
13 |
14 | def __init__(self, chat_id, sender):
15 | self.chat_id = str(chat_id) # ensure string
16 | self.sender = str(sender)
17 |
18 |
19 | Mute.__table__.create(checkfirst=True)
20 |
21 |
22 | def is_muted(chat_id):
23 | try:
24 | return SESSION.query(Mute).filter(Mute.chat_id == str(chat_id)).all()
25 | except BaseException:
26 | return None
27 | finally:
28 | SESSION.close()
29 |
30 |
31 | def mute(chat_id, sender):
32 | adder = Mute(str(chat_id), str(sender))
33 | SESSION.add(adder)
34 | SESSION.commit()
35 |
36 |
37 | def unmute(chat_id, sender):
38 | rem = SESSION.query(Mute).get(((str(chat_id)), (str(sender))))
39 | if rem:
40 | SESSION.delete(rem)
41 | SESSION.commit()
42 |
--------------------------------------------------------------------------------
/userbot/modules/sql_helper/welcome_sql.py:
--------------------------------------------------------------------------------
1 | try:
2 | from userbot.modules.sql_helper import SESSION, BASE
3 | except ImportError:
4 | raise AttributeError
5 |
6 | from sqlalchemy import BigInteger, Column, Numeric, String, UnicodeText
7 |
8 |
9 | class Welcome(BASE):
10 | __tablename__ = "welcome"
11 | chat_id = Column(String(14), primary_key=True)
12 | previous_welcome = Column(BigInteger)
13 | reply = Column(UnicodeText)
14 | f_mesg_id = Column(Numeric)
15 |
16 | def __init__(self, chat_id, previous_welcome, reply, f_mesg_id):
17 | self.chat_id = str(chat_id)
18 | self.previous_welcome = previous_welcome
19 | self.reply = reply
20 | self.f_mesg_id = f_mesg_id
21 |
22 |
23 | Welcome.__table__.create(checkfirst=True)
24 |
25 |
26 | def get_welcome(chat_id):
27 | try:
28 | return SESSION.query(Welcome).get(str(chat_id))
29 | finally:
30 | SESSION.close()
31 |
32 |
33 | def get_current_welcome_settings(chat_id):
34 | try:
35 | return SESSION.query(Welcome).filter(
36 | Welcome.chat_id == str(chat_id)).one()
37 | except BaseException:
38 | return None
39 | finally:
40 | SESSION.close()
41 |
42 |
43 | def add_welcome_setting(chat_id, previous_welcome, reply, f_mesg_id):
44 | to_check = get_welcome(chat_id)
45 | if not to_check:
46 | adder = Welcome(chat_id, previous_welcome, reply, f_mesg_id)
47 | SESSION.add(adder)
48 | SESSION.commit()
49 | return True
50 | else:
51 | rem = SESSION.query(Welcome).get(str(chat_id))
52 | SESSION.delete(rem)
53 | SESSION.commit()
54 | adder = Welcome(chat_id, previous_welcome, reply, f_mesg_id)
55 | SESSION.commit()
56 | return False
57 |
58 |
59 | def rm_welcome_setting(chat_id):
60 | try:
61 | rem = SESSION.query(Welcome).get(str(chat_id))
62 | if rem:
63 | SESSION.delete(rem)
64 | SESSION.commit()
65 | return True
66 | except BaseException:
67 | return False
68 |
69 |
70 | def update_previous_welcome(chat_id, previous_welcome):
71 | row = SESSION.query(Welcome).get(str(chat_id))
72 | row.previous_welcome = previous_welcome
73 | SESSION.commit()
74 |
--------------------------------------------------------------------------------
/userbot/modules/ssvideo.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 Alfiananda P.A
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import asyncio
8 | import os
9 | import time
10 |
11 | from telethon.tl.types import DocumentAttributeFilename
12 | from userbot import CMD_HELP, bot
13 | from userbot.events import register
14 | from userbot.utils import progress
15 |
16 |
17 | @register(outgoing=True, pattern=r"^\.ssvideo(?: |$)(.*)")
18 | async def ssvideo(framecap):
19 | if not framecap.reply_to_msg_id:
20 | return await framecap.edit("`reply to video!`")
21 | reply_message = await framecap.get_reply_message()
22 | if not reply_message.media:
23 | return await framecap.edit("`reply to a video!`")
24 | try:
25 | frame = int(framecap.pattern_match.group(1))
26 | if frame > 10:
27 | return await framecap.edit("`hey..dont put that much`")
28 | except BaseException:
29 | return await framecap.edit("`Please input number of frame!`")
30 | if (reply_message.photo
31 | or (DocumentAttributeFilename(file_name="AnimatedSticker.tgs")
32 | in reply_message.media.document.attributes)
33 | or (DocumentAttributeFilename(file_name="sticker.webp")
34 | in reply_message.media.document.attributes)
35 | ):
36 | return await framecap.edit("`Unsupported files!`")
37 | c_time = time.time()
38 | await framecap.edit("`Downloading media...`")
39 | ss = await bot.download_media(
40 | reply_message,
41 | "anu.mp4",
42 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
43 | progress(d, t, framecap, c_time, "[DOWNLOAD]")
44 | ),
45 | )
46 | try:
47 | await framecap.edit("`Proccessing...`")
48 | command = f"vcsi -g {frame}x{frame} {ss} -o ss.png "
49 | os.system(command)
50 | await framecap.client.send_file(
51 | framecap.chat_id,
52 | "ss.png",
53 | reply_to=framecap.reply_to_msg_id,
54 | )
55 | await framecap.delete()
56 | except BaseException as e:
57 | await framecap.edit(f"{e}")
58 | os.system("rm -rf *.png *.mp4")
59 |
60 |
61 | CMD_HELP.update(
62 | {
63 | "ssvideo": ".ssvideo \
64 | \nUsage: Capture video frames by x .\
65 | \n*max grid is 10."
66 | }
67 | )
68 |
--------------------------------------------------------------------------------
/userbot/modules/telegraph.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port From UniBorg to UserBot by @afdulfauzan
7 |
8 | import os
9 | from datetime import datetime
10 |
11 | from PIL import Image
12 | from telegraph import Telegraph, exceptions, upload_file
13 |
14 | from userbot import CMD_HELP, TEMP_DOWNLOAD_DIRECTORY, bot
15 | from userbot.events import register
16 |
17 | telegraph = Telegraph()
18 | r = telegraph.create_account(short_name="telegraph")
19 | auth_url = r["auth_url"]
20 |
21 |
22 | @register(outgoing=True, pattern="^.tg (m|t)$")
23 | async def telegraphs(graph):
24 | """For .telegraph command, upload media & text to telegraph site."""
25 | await graph.edit("`Processing...`")
26 | if not graph.text[0].isalpha() and graph.text[0] not in ("/", "#", "@", "!"):
27 | if graph.fwd_from:
28 | return
29 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
30 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
31 | if graph.reply_to_msg_id:
32 | start = datetime.now()
33 | r_message = await graph.get_reply_message()
34 | input_str = graph.pattern_match.group(1)
35 | if input_str == "m":
36 | downloaded_file_name = await bot.download_media(
37 | r_message, TEMP_DOWNLOAD_DIRECTORY
38 | )
39 | end = datetime.now()
40 | ms = (end - start).seconds
41 | await graph.edit(
42 | "Downloaded to {} in {} seconds.".format(downloaded_file_name, ms)
43 | )
44 | try:
45 | if downloaded_file_name.endswith((".webp")):
46 | resize_image(downloaded_file_name)
47 | except AttributeError:
48 | return await graph.edit("`No media provided`")
49 | try:
50 | media_urls = upload_file(downloaded_file_name)
51 | except exceptions.TelegraphException as exc:
52 | await graph.edit("ERROR: " + str(exc))
53 | os.remove(downloaded_file_name)
54 | else:
55 | os.remove(downloaded_file_name)
56 | await graph.edit(
57 | "Successfully Uploaded to [telegra.ph](https://telegra.ph{}).".format(
58 | media_urls[0]
59 | ),
60 | link_preview=True,
61 | )
62 | elif input_str == "t":
63 | user_object = await bot.get_entity(r_message.from_id)
64 | title_of_page = user_object.first_name # + " " + user_object.last_name
65 | # apparently, all Users do not have last_name field
66 | page_content = r_message.message
67 | if r_message.media:
68 | if page_content != "":
69 | title_of_page = page_content
70 | downloaded_file_name = await bot.download_media(
71 | r_message, TEMP_DOWNLOAD_DIRECTORY
72 | )
73 | m_list = None
74 | with open(downloaded_file_name, "rb") as fd:
75 | m_list = fd.readlines()
76 | for m in m_list:
77 | page_content += m.decode("UTF-8") + "\n"
78 | os.remove(downloaded_file_name)
79 | page_content = page_content.replace("\n", " ")
80 | response = telegraph.create_page(
81 | title_of_page, html_content=page_content
82 | )
83 | await graph.edit(
84 | "Successfully uploaded to [telegra.ph](https://telegra.ph/{}).".format(
85 | response["path"]
86 | ),
87 | link_preview=True,
88 | )
89 | else:
90 | await graph.edit("`Reply to a message to get a permanent telegra.ph link.`")
91 |
92 |
93 | def resize_image(image):
94 | im = Image.open(image)
95 | im.save(image, "PNG")
96 |
97 |
98 | CMD_HELP.update(
99 | {
100 | "telegraph": ".tg \
101 | \nUsage: Upload t(text) or m(media) on Telegraph."
102 | }
103 | )
104 |
--------------------------------------------------------------------------------
/userbot/modules/time.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module for getting the date
7 | and time of any country or the userbot server. """
8 |
9 | from datetime import datetime as dt
10 |
11 | from pytz import country_names as c_n
12 | from pytz import country_timezones as c_tz
13 | from pytz import timezone as tz
14 |
15 | from userbot import CMD_HELP, COUNTRY, TZ_NUMBER
16 | from userbot.events import register
17 |
18 |
19 | async def get_tz(con):
20 | """ Get time zone of the given country. """
21 | if "(Uk)" in con:
22 | con = con.replace("Uk", "UK")
23 | if "(Us)" in con:
24 | con = con.replace("Us", "US")
25 | if " Of " in con:
26 | con = con.replace(" Of ", " of ")
27 | if "(Western)" in con:
28 | con = con.replace("(Western)", "(western)")
29 | if "Minor Outlying Islands" in con:
30 | con = con.replace("Minor Outlying Islands", "minor outlying islands")
31 | if "Nl" in con:
32 | con = con.replace("Nl", "NL")
33 |
34 | for c_code in c_n:
35 | if con == c_n[c_code]:
36 | return c_tz[c_code]
37 | try:
38 | if c_n[con]:
39 | return c_tz[con]
40 | except KeyError:
41 | return
42 |
43 |
44 | @register(outgoing=True, pattern="^.time(?: |$)(.*)(? 4:
58 | try:
59 | c_name = c_n[con]
60 | except KeyError:
61 | c_name = con
62 | timezones = await get_tz(con)
63 | elif COUNTRY:
64 | c_name = COUNTRY
65 | tz_num = TZ_NUMBER
66 | timezones = await get_tz(COUNTRY)
67 | else:
68 | await tdata.edit(f"`It's` **{dt.now().strftime(t_form)}** `here.`")
69 | return
70 |
71 | if not timezones:
72 | await tdata.edit("`Invaild country.`")
73 | return
74 |
75 | if len(timezones) == 1:
76 | time_zone = timezones[0]
77 | elif len(timezones) > 1:
78 | if tz_num:
79 | tz_num = int(tz_num)
80 | time_zone = timezones[tz_num - 1]
81 | else:
82 | return_str = f"`{c_name} has multiple timezones:`\n\n"
83 |
84 | for i, item in enumerate(timezones):
85 | return_str += f"`{i+1}. {item}`\n"
86 |
87 | return_str += "\n`Choose one by typing the number "
88 | return_str += "in the command.`\n"
89 | return_str += f"`Example: .time {c_name} 2`"
90 |
91 | await tdata.edit(return_str)
92 | return
93 |
94 | dtnow = dt.now(tz(time_zone)).strftime(t_form)
95 |
96 | if c_name != COUNTRY:
97 | await tdata.edit(f"`It's` **{dtnow}** `in {c_name}({time_zone} timezone).`")
98 | return
99 |
100 | elif COUNTRY:
101 | await tdata.edit(
102 | f"`It's` **{dtnow}** `here, in {COUNTRY}" f"({time_zone} timezone).`"
103 | )
104 | return
105 |
106 |
107 | @register(outgoing=True, pattern="^.date(?: |$)(.*)(? 4:
121 | try:
122 | c_name = c_n[con]
123 | except KeyError:
124 | c_name = con
125 | timezones = await get_tz(con)
126 | elif COUNTRY:
127 | c_name = COUNTRY
128 | tz_num = TZ_NUMBER
129 | timezones = await get_tz(COUNTRY)
130 | else:
131 | await dat.edit(f"`It's` **{dt.now().strftime(d_form)}** `here.`")
132 | return
133 |
134 | if not timezones:
135 | await dat.edit("`Invaild country.`")
136 | return
137 |
138 | if len(timezones) == 1:
139 | time_zone = timezones[0]
140 | elif len(timezones) > 1:
141 | if tz_num:
142 | tz_num = int(tz_num)
143 | time_zone = timezones[tz_num - 1]
144 | else:
145 | return_str = f"`{c_name} has multiple timezones:`\n"
146 |
147 | for i, item in enumerate(timezones):
148 | return_str += f"`{i+1}. {item}`\n"
149 |
150 | return_str += "\n`Choose one by typing the number "
151 | return_str += "in the command.`\n"
152 | return_str += f"Example: .date {c_name} 2"
153 |
154 | await dat.edit(return_str)
155 | return
156 |
157 | dtnow = dt.now(tz(time_zone)).strftime(d_form)
158 |
159 | if c_name != COUNTRY:
160 | await dat.edit(f"`It's` **{dtnow}** `in {c_name}({time_zone} timezone).`")
161 | return
162 |
163 | elif COUNTRY:
164 | await dat.edit(
165 | f"`It's` **{dtnow}** `here, in {COUNTRY}" f"({time_zone} timezone).`"
166 | )
167 | return
168 |
169 |
170 | CMD_HELP.update(
171 | {
172 | "time": ".time "
173 | "\nUsage: Get the time of a country. If a country has "
174 | "multiple timezones, it will list all of them "
175 | "and let you select one."
176 | }
177 | )
178 | CMD_HELP.update(
179 | {
180 | "date": ".date "
181 | "\nUsage: Get the date of a country. If a country has "
182 | "multiple timezones, it will list all of them "
183 | "and let you select one."
184 | }
185 | )
186 |
--------------------------------------------------------------------------------
/userbot/modules/torrent.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 GengKapak and AnggaR96s.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import codecs
8 | import json
9 | import os
10 |
11 | import requests
12 | from bs4 import BeautifulSoup as bs
13 |
14 | from userbot import CMD_HELP, TEMP_DOWNLOAD_DIRECTORY
15 | from userbot.events import register
16 |
17 |
18 | @register(outgoing=True, pattern=r"^\.ts (.*)")
19 | async def gengkapak(e):
20 | await e.edit("`Please wait, fetching results...`")
21 | query = e.pattern_match.group(1)
22 | response = requests.get(
23 | f"https://sjprojectsapi.herokuapp.com/torrent/?query={query}"
24 | )
25 | ts = json.loads(response.text)
26 | if not ts == response.json():
27 | await e.edit("**Some error occured**\n`Try Again Later`")
28 | return
29 | listdata = ""
30 | run = 0
31 | while True:
32 | try:
33 | run += 1
34 | r1 = ts[run]
35 | list1 = "<-----{}----->\nName: {}\nSeeders: {}\nSize: {}\nAge: {}\n<--Magnet Below-->\n{}\n\n\n".format(
36 | run, r1["name"], r1["seeder"], r1["size"], r1["age"], r1["magnet"]
37 | )
38 | listdata = listdata + list1
39 | except BaseException:
40 | break
41 |
42 | if not listdata:
43 | return await e.edit("`Error: No results found`")
44 |
45 | tsfileloc = f"{TEMP_DOWNLOAD_DIRECTORY}/{query}.txt"
46 | with open(tsfileloc, "w+", encoding="utf8") as out_file:
47 | out_file.write(str(listdata))
48 | fd = codecs.open(tsfileloc, "r", encoding="utf-8")
49 | data = fd.read()
50 | key = (
51 | requests.post("https://nekobin.com/api/documents", json={"content": data})
52 | .json()
53 | .get("result")
54 | .get("key")
55 | )
56 | url = f"https://nekobin.com/raw/{key}"
57 | caption = (
58 | f"`Here the results for the query: {query}`\n\nPasted to: [Nekobin]({url})"
59 | )
60 | os.remove(tsfileloc)
61 | await e.edit(caption, link_preview=False)
62 |
63 |
64 | def dogbin(magnets):
65 | counter = 0
66 | urls = []
67 | while counter != len(magnets):
68 | message = magnets[counter]
69 | url = "https://del.dog/documents"
70 | r = requests.post(url, data=message.encode("UTF-8")).json()
71 | url = f"https://del.dog/raw/{r['key']}"
72 | urls.append(url)
73 | counter = counter + 1
74 | return urls
75 |
76 |
77 | @register(outgoing=True, pattern=r"^.tos(?: |$)(.*)")
78 | async def tor_search(event):
79 | if event.fwd_from:
80 | return
81 | headers = {
82 | "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
83 | }
84 |
85 | search_str = event.pattern_match.group(1)
86 |
87 | print(search_str)
88 | await event.edit("Searching for " + search_str + ".....")
89 | if " " in search_str:
90 | search_str = search_str.replace(" ", "+")
91 | print(search_str)
92 | res = requests.get(
93 | "https://www.torrentdownloads.me/search/?new=1&s_cat=0&search="
94 | + search_str,
95 | headers,
96 | )
97 |
98 | else:
99 | res = requests.get(
100 | "https://www.torrentdownloads.me/search/?search=" + search_str, headers
101 | )
102 |
103 | source = bs(res.text, "lxml")
104 | urls = []
105 | magnets = []
106 | titles = []
107 | counter = 0
108 | for div in source.find_all("div", {"class": "grey_bar3 back_none"}):
109 | # print("https://www.torrentdownloads.me"+a['href'])
110 | try:
111 | title = div.p.a["title"]
112 | title = title[20:]
113 | titles.append(title)
114 | urls.append("https://www.torrentdownloads.me" + div.p.a["href"])
115 | except KeyError:
116 | pass
117 | except TypeError:
118 | pass
119 | except AttributeError:
120 | pass
121 | if counter == 11:
122 | break
123 | counter = counter + 1
124 | if not urls:
125 | await event.edit("Either the Keyword was restricted or not found..")
126 | return
127 |
128 | print("Found URLS...")
129 | for url in urls:
130 | res = requests.get(url, headers)
131 | # print("URl: "+url)
132 | source = bs(res.text, "lxml")
133 | for div in source.find_all("div", {"class": "grey_bar1 back_none"}):
134 | try:
135 | mg = div.p.a["href"]
136 | magnets.append(mg)
137 | except Exception:
138 | pass
139 | print("Found Magnets...")
140 | shorted_links = dogbin(magnets)
141 | print("Dogged Magnets to del.dog...")
142 | msg = ""
143 | try:
144 | search_str = search_str.replace("+", " ")
145 | except BaseException:
146 | pass
147 | msg = "**Torrent Search Query**\n`{}`".format(search_str) + "\n**Results**\n"
148 | counter = 0
149 | while counter != len(titles):
150 | msg = (
151 | msg
152 | + "⁍ [{}]".format(titles[counter])
153 | + "({})".format(shorted_links[counter])
154 | + "\n\n"
155 | )
156 | counter = counter + 1
157 | await event.edit(msg, link_preview=False)
158 |
159 |
160 | CMD_HELP.update(
161 | {
162 | "torrent": ".ts Search query.\
163 | \nUsage: Search for torrent query and post to dogbin.\
164 | \n\n.tos Search query.\
165 | \nUsage: Search for torrent magnet from query."
166 | }
167 | )
168 |
--------------------------------------------------------------------------------
/userbot/modules/whois.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # The entire source code is OSSRPL except 'whois' which is MPL
7 | # License: MPL and OSSRPL
8 | """ Userbot module for getiing info about any user on Telegram(including you!). """
9 |
10 | import os
11 |
12 | from telethon.tl.functions.photos import GetUserPhotosRequest
13 | from telethon.tl.functions.users import GetFullUserRequest
14 | from telethon.tl.types import MessageEntityMentionName
15 | from telethon.utils import get_input_location
16 |
17 | from userbot import CMD_HELP, TEMP_DOWNLOAD_DIRECTORY
18 | from userbot.events import register
19 |
20 |
21 | @register(pattern=".whois(?: |$)(.*)", outgoing=True)
22 | async def who(event):
23 |
24 | await event.edit(
25 | "`Sit tight while I steal some data from *Global Network Zone*...`"
26 | )
27 |
28 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
29 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
30 |
31 | replied_user = await get_user(event)
32 | if replied_user is None:
33 | await event.edit("`This is anonymous admin in this group.\nCan't fetch the info`")
34 | return
35 |
36 | try:
37 | photo, caption = await fetch_info(replied_user, event)
38 | except AttributeError:
39 | await event.edit("`Could not fetch info of that user.`")
40 | return
41 |
42 | message_id_to_reply = event.message.reply_to_msg_id
43 |
44 | if not message_id_to_reply:
45 | message_id_to_reply = None
46 |
47 | try:
48 | await event.client.send_file(
49 | event.chat_id,
50 | photo,
51 | caption=caption,
52 | link_preview=False,
53 | force_document=False,
54 | reply_to=message_id_to_reply,
55 | parse_mode="html",
56 | )
57 |
58 | if not photo.startswith("http"):
59 | os.remove(photo)
60 | await event.delete()
61 |
62 | except TypeError:
63 | await event.edit(caption, parse_mode="html")
64 |
65 |
66 | async def get_user(event):
67 | """ Get the user from argument or replied message. """
68 | if event.reply_to_msg_id and not event.pattern_match.group(1):
69 | previous_message = await event.get_reply_message()
70 | if previous_message.from_id is None: # Anonymous admin seems don't have id attr
71 | return None
72 | replied_user = await event.client(
73 | GetFullUserRequest(previous_message.from_id))
74 | else:
75 | user = event.pattern_match.group(1)
76 |
77 | if user.isnumeric():
78 | user = int(user)
79 |
80 | if not user:
81 | self_user = await event.client.get_me()
82 | user = self_user.id
83 |
84 | if event.message.entities is not None:
85 | probable_user_mention_entity = event.message.entities[0]
86 |
87 | if isinstance(probable_user_mention_entity, MessageEntityMentionName):
88 | user_id = probable_user_mention_entity.user_id
89 | replied_user = await event.client(GetFullUserRequest(user_id))
90 | return replied_user
91 | try:
92 | user_object = await event.client.get_entity(user)
93 | replied_user = await event.client(GetFullUserRequest(user_object.id))
94 | except (TypeError, ValueError) as err:
95 | await event.edit(str(err))
96 | return None
97 |
98 | return replied_user
99 |
100 |
101 | async def fetch_info(replied_user, event):
102 | """ Get details from the User object. """
103 | replied_user_profile_photos = await event.client(
104 | GetUserPhotosRequest(
105 | user_id=replied_user.user.id, offset=42, max_id=0, limit=80
106 | )
107 | )
108 | replied_user_profile_photos_count = (
109 | "Person needs help with uploading profile picture."
110 | )
111 | try:
112 | replied_user_profile_photos_count = replied_user_profile_photos.count
113 | except AttributeError:
114 | pass
115 | user_id = replied_user.user.id
116 | first_name = replied_user.user.first_name
117 | last_name = replied_user.user.last_name
118 | try:
119 | dc_id, location = get_input_location(replied_user.profile_photo)
120 | except Exception as e:
121 | dc_id = "Couldn't fetch DC ID!"
122 | str(e)
123 | common_chat = replied_user.common_chats_count
124 | username = replied_user.user.username
125 | user_bio = replied_user.about
126 | is_bot = replied_user.user.bot
127 | restricted = replied_user.user.restricted
128 | verified = replied_user.user.verified
129 | photo = await event.client.download_profile_photo(
130 | user_id, TEMP_DOWNLOAD_DIRECTORY + str(user_id) + ".jpg", download_big=True
131 | )
132 | first_name = (
133 | first_name.replace("\u2060", "")
134 | if first_name
135 | else ("This User has no First Name")
136 | )
137 | last_name = (
138 | last_name.replace("\u2060", "") if last_name else ("This User has no Last Name")
139 | )
140 | username = "@{}".format(username) if username else ("This User has no Username")
141 | user_bio = "This User has no About" if not user_bio else user_bio
142 |
143 | caption = "USER INFO:\n\n"
144 | caption += f"First Name: {first_name}\n"
145 | caption += f"Last Name: {last_name}\n"
146 | caption += f"Username: {username}\n"
147 | caption += f"Data Centre ID: {dc_id}\n"
148 | caption += f"Number of Profile Pics: {replied_user_profile_photos_count}\n"
149 | caption += f"Is Bot: {is_bot}\n"
150 | caption += f"Is Restricted: {restricted}\n"
151 | caption += f"Is Verified by Telegram: {verified}\n"
152 | caption += f"ID: {user_id}\n\n"
153 | caption += f"Bio: \n{user_bio}\n\n"
154 | caption += f"Common Chats with this user: {common_chat}\n"
155 | caption += f"Permanent Link To Profile: "
156 | caption += f'{first_name}'
157 |
158 | return photo, caption
159 |
160 |
161 | CMD_HELP.update(
162 | {
163 | "whois": ".whois or reply to someones text with .whois\
164 | \nUsage: Gets info of an user."
165 | }
166 | )
167 |
--------------------------------------------------------------------------------
/userbot/modules/www.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | """ Userbot module containing commands related to the \
7 | Information Superhighway (yes, Internet). """
8 |
9 | from datetime import datetime
10 |
11 | from speedtest import Speedtest
12 | from telethon import functions
13 |
14 | from userbot import CMD_HELP
15 | from userbot.events import register
16 |
17 |
18 | @register(outgoing=True, pattern="^.speed$")
19 | async def speedtst(spd):
20 | """ For .speed command, use SpeedTest to check server speeds. """
21 | await spd.edit("`Running speed test . . .`")
22 | test = Speedtest()
23 |
24 | test.get_best_server()
25 | test.download()
26 | test.upload()
27 | test.results.share()
28 | result = test.results.dict()
29 |
30 | await spd.edit(
31 | "`"
32 | "Started at "
33 | f"{result['timestamp']} \n\n"
34 | "Download "
35 | f"{speed_convert(result['download'])} \n"
36 | "Upload "
37 | f"{speed_convert(result['upload'])} \n"
38 | "Ping "
39 | f"{result['ping']} \n"
40 | "ISP "
41 | f"{result['client']['isp']}"
42 | "`"
43 | )
44 |
45 |
46 | def speed_convert(size):
47 | """
48 | Hi human, you can't read bytes?
49 | """
50 | power = 2 ** 10
51 | zero = 0
52 | units = {0: "", 1: "Kb/s", 2: "Mb/s", 3: "Gb/s", 4: "Tb/s"}
53 | while size > power:
54 | size /= power
55 | zero += 1
56 | return f"{round(size, 2)} {units[zero]}"
57 |
58 |
59 | @register(outgoing=True, pattern="^.dc$")
60 | async def neardc(event):
61 | """ For .dc command, get the nearest datacenter information. """
62 | result = await event.client(functions.help.GetNearestDcRequest())
63 | await event.edit(
64 | f"Country : `{result.country}`\n"
65 | f"Nearest Datacenter : `{result.nearest_dc}`\n"
66 | f"This Datacenter : `{result.this_dc}`"
67 | )
68 |
69 |
70 | @register(outgoing=True, pattern="^.ping$")
71 | async def pingme(pong):
72 | """ For .ping command, ping the userbot from any chat. """
73 | start = datetime.now()
74 | await pong.edit("`Pong!`")
75 | end = datetime.now()
76 | duration = (end - start).microseconds / 1000
77 | await pong.edit("`Pong!\n%sms`" % (duration))
78 |
79 |
80 | CMD_HELP.update(
81 | {
82 | "speed": ".speed\
83 | \nUsage: Does a speedtest and shows the results."
84 | }
85 | )
86 | CMD_HELP.update(
87 | {
88 | "dc": ".dc\
89 | \nUsage: Finds the nearest datacenter from your server."
90 | }
91 | )
92 | CMD_HELP.update(
93 | {
94 | "ping": ".ping\
95 | \nUsage: Shows how long it takes to ping your bot."
96 | }
97 | )
98 |
--------------------------------------------------------------------------------
/userbot/modules/zipfile.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 The Raphielscape Company LLC.
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 | # Port from UniBorg to Userbot by yincen17
7 |
8 | import asyncio
9 | import os
10 | import time
11 | import zipfile
12 | from datetime import date
13 |
14 | from userbot import CMD_HELP, TEMP_DOWNLOAD_DIRECTORY, ZIP_DOWNLOAD_DIRECTORY, bot
15 | from userbot.events import register
16 | from userbot.utils import progress
17 |
18 | # ====================
19 | today = date.today()
20 | # ====================
21 |
22 |
23 | @register(outgoing=True, pattern=r"^\.compress(?: |$)(.*)")
24 | async def _(event):
25 | # Prevent Channel Bug to use update
26 | if event.is_channel and not event.is_group:
27 | await event.edit("`Compress Command isn't permitted on channels`")
28 | return
29 | if event.fwd_from:
30 | return
31 | if not event.is_reply:
32 | await event.edit("`Reply to a file to compress it.`")
33 | return
34 | mone = await event.edit("`Processing...`")
35 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
36 | os.makedirs(TEMP_DOWNLOAD_DIRECTORY)
37 | if event.reply_to_msg_id:
38 | reply_message = await event.get_reply_message()
39 | try:
40 | c_time = time.time()
41 | downloaded_file_name = await bot.download_media(
42 | reply_message,
43 | TEMP_DOWNLOAD_DIRECTORY,
44 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
45 | progress(d, t, mone, c_time, "[DOWNLOADING]")
46 | ),
47 | )
48 | directory_name = downloaded_file_name
49 | await event.edit(
50 | f"Downloaded to `{directory_name}`" "`\ncompressing file...`"
51 | )
52 | except Exception as e: # pylint:disable=C0103,W0703
53 | await mone.edit(str(e))
54 | zipfile.ZipFile(directory_name + ".zip", "w", zipfile.ZIP_DEFLATED).write(
55 | directory_name
56 | )
57 | c_time = time.time()
58 | await bot.send_file(
59 | event.chat_id,
60 | directory_name + ".zip",
61 | force_document=True,
62 | allow_cache=False,
63 | reply_to=event.message.id,
64 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
65 | progress(d, t, mone, c_time, "[UPLOADING]")
66 | ),
67 | )
68 | await event.edit("`Done!!`")
69 | await asyncio.sleep(7)
70 | await event.delete()
71 |
72 |
73 | @register(outgoing=True, pattern=r"^\.addzip(?: |$)(.*)")
74 | async def addzip(add):
75 | """ Copyright (c) 2020 azrim @github"""
76 | # Prevent Channel Bug to use update
77 | if add.is_channel and not add.is_group:
78 | await add.edit("`Command isn't permitted on channels`")
79 | return
80 | if add.fwd_from:
81 | return
82 | if not add.is_reply:
83 | await add.edit("`Reply to a file to compress it.`")
84 | return
85 | mone = await add.edit("`Processing...`")
86 | if not os.path.isdir(ZIP_DOWNLOAD_DIRECTORY):
87 | os.makedirs(ZIP_DOWNLOAD_DIRECTORY)
88 | if add.reply_to_msg_id:
89 | reply_message = await add.get_reply_message()
90 | try:
91 | c_time = time.time()
92 | downloaded_file_name = await bot.download_media(
93 | reply_message,
94 | ZIP_DOWNLOAD_DIRECTORY,
95 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
96 | progress(d, t, mone, c_time, "[DOWNLOADING]")
97 | ),
98 | )
99 | success = str(downloaded_file_name).replace("./zips/", "")
100 | await add.edit(f"`{success} Successfully added to list`")
101 | except Exception as e: # pylint:disable=C0103,W0703
102 | await mone.edit(str(e))
103 | return
104 |
105 |
106 | @register(outgoing=True, pattern=r"^\.upzip(?: |$)(.*)")
107 | async def upload_zip(up):
108 | if not os.path.isdir(ZIP_DOWNLOAD_DIRECTORY):
109 | await up.edit("`Files not found`")
110 | return
111 | mone = await up.edit("`Zipping File...`")
112 | input_str = up.pattern_match.group(1)
113 | curdate = today.strftime("%m%d%y")
114 | title = str(input_str) if input_str else "zipfile" + f"{curdate}"
115 | zipf = zipfile.ZipFile(title + ".zip", "w", zipfile.ZIP_DEFLATED)
116 | zipdir(ZIP_DOWNLOAD_DIRECTORY, zipf)
117 | zipf.close()
118 | c_time = time.time()
119 | await bot.send_file(
120 | up.chat_id,
121 | title + ".zip",
122 | force_document=True,
123 | allow_cache=False,
124 | reply_to=up.message.id,
125 | progress_callback=lambda d, t: asyncio.get_event_loop().create_task(
126 | progress(d, t, mone, c_time, "[UPLOADING]", input_str)
127 | ),
128 | )
129 | os.rmdir(ZIP_DOWNLOAD_DIRECTORY)
130 | await up.delete()
131 |
132 |
133 | @register(outgoing=True, pattern=r"^\.rmzip(?: |$)(.*)")
134 | async def remove_dir(rm):
135 | if not os.path.isdir(ZIP_DOWNLOAD_DIRECTORY):
136 | await rm.edit("`Directory not found`")
137 | return
138 | os.rmdir(ZIP_DOWNLOAD_DIRECTORY)
139 | await rm.edit("`Zip list removed`")
140 |
141 |
142 | def zipdir(path, ziph):
143 | # ziph is zipfile handle
144 | for root, dirs, files in os.walk(path):
145 | for file in files:
146 | ziph.write(os.path.join(root, file))
147 | os.remove(os.path.join(root, file))
148 |
149 |
150 | CMD_HELP.update(
151 | {
152 | "zipfile": ".compress **[optional: ]**\
153 | \nUsage: make files to zip.\
154 | \n.addzip ****\
155 | \nUsage: add files to zip list.\
156 | \n.upzip **[optional: ]**\
157 | \nUsage: upload zip list.\
158 | \n.rmzip **[optional: ]**\
159 | \nUsage: clear zip list."
160 | }
161 | )
162 |
--------------------------------------------------------------------------------
/userbot/utils/__init__.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 Adek Maulana
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | from .chrome import chrome, options
8 | from .progress import progress
9 | from .google_images_download import googleimagesdownload
10 |
11 | from .tools import (
12 | humanbytes,
13 | time_formatter,
14 | human_to_bytes,
15 | md5,
16 | check_media
17 | )
18 |
--------------------------------------------------------------------------------
/userbot/utils/chrome.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 Adek Maulana
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import os
8 |
9 | from selenium import webdriver
10 | from selenium.webdriver.chrome.options import Options
11 |
12 | from userbot import TEMP_DOWNLOAD_DIRECTORY, GOOGLE_CHROME_BIN, CHROME_DRIVER
13 |
14 |
15 | async def chrome(chrome_options=None):
16 | if chrome_options is None:
17 | chrome_options = await options()
18 | if not os.path.isdir(TEMP_DOWNLOAD_DIRECTORY):
19 | os.mkdir(TEMP_DOWNLOAD_DIRECTORY)
20 | prefs = {'download.default_directory': TEMP_DOWNLOAD_DIRECTORY}
21 | chrome_options.add_experimental_option('prefs', prefs)
22 | driver = webdriver.Chrome(executable_path=CHROME_DRIVER,
23 | options=chrome_options)
24 | return driver
25 |
26 |
27 | async def options():
28 | chrome_options = Options()
29 | chrome_options.binary_location = GOOGLE_CHROME_BIN
30 | chrome_options.add_argument("--headless")
31 | chrome_options.add_argument("--window-size=1920x1080")
32 | chrome_options.add_argument("--disable-dev-shm-usage")
33 | chrome_options.add_argument("--no-sandbox")
34 | chrome_options.add_argument("--disable-gpu")
35 | return chrome_options
36 |
--------------------------------------------------------------------------------
/userbot/utils/exceptions.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 Adek Maulana
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | class CancelProcess(Exception):
8 | """
9 | Cancel Process
10 | """
11 |
--------------------------------------------------------------------------------
/userbot/utils/progress.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2020 Adek Maulana
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import time
8 | import math
9 |
10 | from .tools import humanbytes, time_formatter
11 | from .exceptions import CancelProcess
12 |
13 |
14 | async def progress(
15 | current, total, gdrive, start, prog_type,
16 | file_name=None, is_cancelled=False
17 | ):
18 | now = time.time()
19 | diff = now - start
20 | if is_cancelled is True:
21 | raise CancelProcess
22 |
23 | if round(diff % 10.00) == 0 or current == total:
24 | percentage = current * 100 / total
25 | speed = current / diff
26 | elapsed_time = round(diff)
27 | eta = round((total - current) / speed)
28 | if 'upload' in prog_type.lower():
29 | status = 'Uploading'
30 | elif 'download' in prog_type.lower():
31 | status = 'Downloading'
32 | else:
33 | status = 'Unknown'
34 | progress_str = "`{0}` | [{1}{2}] `{3}%`".format(
35 | status,
36 | ''.join(["■" for i in range(
37 | math.floor(percentage / 10))]),
38 | ''.join(["▨" for i in range(
39 | 10 - math.floor(percentage / 10))]),
40 | round(percentage, 2))
41 | tmp = (
42 | f"{progress_str}\n"
43 | f"`{humanbytes(current)} of {humanbytes(total)}"
44 | f" @ {humanbytes(speed)}`\n"
45 | f"`ETA` -> {time_formatter(eta)}\n"
46 | f"`Duration` -> {time_formatter(elapsed_time)}"
47 | )
48 | await gdrive.edit(f"`{prog_type}`\n\n"
49 | f"`Status`\n{tmp}")
50 |
--------------------------------------------------------------------------------
/userbot/utils/tools.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2019 Adek Maulana
2 | #
3 | # Licensed under the Raphielscape Public License, Version 1.d (the "License");
4 | # you may not use this file except in compliance with the License.
5 | #
6 |
7 | import re
8 | import hashlib
9 |
10 | from telethon.tl.types import DocumentAttributeFilename
11 |
12 |
13 | async def md5(fname: str) -> str:
14 | hash_md5 = hashlib.md5()
15 | with open(fname, "rb") as f:
16 | for chunk in iter(lambda: f.read(4096), b""):
17 | hash_md5.update(chunk)
18 | return hash_md5.hexdigest()
19 |
20 |
21 | def humanbytes(size: int) -> str:
22 | if size is None or isinstance(size, str):
23 | return ""
24 |
25 | power = 2**10
26 | raised_to_pow = 0
27 | dict_power_n = {0: "", 1: "Ki", 2: "Mi", 3: "Gi", 4: "Ti"}
28 | while size > power:
29 | size /= power
30 | raised_to_pow += 1
31 | return str(round(size, 2)) + " " + dict_power_n[raised_to_pow] + "B"
32 |
33 |
34 | def time_formatter(seconds: int) -> str:
35 | minutes, seconds = divmod(seconds, 60)
36 | hours, minutes = divmod(minutes, 60)
37 | days, hours = divmod(hours, 24)
38 | tmp = (
39 | ((str(days) + " day(s), ") if days else "") +
40 | ((str(hours) + " hour(s), ") if hours else "") +
41 | ((str(minutes) + " minute(s), ") if minutes else "") +
42 | ((str(seconds) + " second(s), ") if seconds else "")
43 | )
44 | return tmp[:-2]
45 |
46 |
47 | def human_to_bytes(size: str) -> int:
48 | units = {
49 | "M": 2**20, "MB": 2**20,
50 | "G": 2**30, "GB": 2**30,
51 | "T": 2**40, "TB": 2**40
52 | }
53 |
54 | size = size.upper()
55 | if not re.match(r' ', size):
56 | size = re.sub(r'([KMGT])', r' \1', size)
57 | number, unit = [string.strip() for string in size.split()]
58 | return int(float(number) * units[unit])
59 |
60 |
61 | async def check_media(reply_message):
62 | if reply_message and reply_message.media:
63 | if reply_message.photo:
64 | data = reply_message.photo
65 | elif reply_message.document:
66 | if (
67 | DocumentAttributeFilename(file_name="AnimatedSticker.tgs")
68 | in reply_message.media.document.attributes
69 | ):
70 | return False
71 | if (
72 | reply_message.gif
73 | or reply_message.video
74 | or reply_message.audio
75 | or reply_message.voice
76 | ):
77 | return False
78 | data = reply_message.media.document
79 | else:
80 | return False
81 | else:
82 | return False
83 |
84 | if not data or data is None:
85 | return False
86 | else:
87 | return data
88 |
--------------------------------------------------------------------------------
/windows_startup_script.py:
--------------------------------------------------------------------------------
1 | from telethon import TelegramClient
2 | API_KEY = "Type that here"
3 | API_HASH = "Type that here"
4 | # get it from my.telegram.org
5 | bot = TelegramClient('userbot', API_KEY, API_HASH)
6 | bot.start()
7 |
8 | # This script wont run your bot, it just generates a session.
9 |
--------------------------------------------------------------------------------