Repository: ritheshrkrm/PiroAutoFilterBot
Branch: master
Commit: 0a1472581259
Files: 42
Total size: 283.3 KB
Directory structure:
gitextract_vg1qfr22/
├── .gitignore
├── Dockerfile
├── LICENSE
├── Procfile
├── README.md
├── Script.py
├── app.json
├── bot.py
├── database/
│ ├── connections_mdb.py
│ ├── filters_mdb.py
│ ├── gfilters_mdb.py
│ ├── ia_filterdb.py
│ └── users_chats_db.py
├── docker-compose.yml
├── heroku.yml
├── info.py
├── logging.conf
├── plugins/
│ ├── __init__.py
│ ├── approve.py
│ ├── banned.py
│ ├── broadcast.py
│ ├── channel.py
│ ├── check_alive.py
│ ├── commands.py
│ ├── connection.py
│ ├── delete_files.py
│ ├── filters.py
│ ├── genlink.py
│ ├── gfilters.py
│ ├── index.py
│ ├── inline.py
│ ├── json.py
│ ├── misc.py
│ ├── p_ttishow.py
│ ├── pm_filter.py
│ └── route.py
├── render.yaml
├── requirements.txt
├── runtime.txt
├── sample_info.py
├── start.sh
└── utils.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Personal files
*.session
*.session-journal
.vscode
*test*.py
setup.cfg
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
config.py
.goutputstream-VAFWB1
result.json
================================================
FILE: Dockerfile
================================================
FROM python:3.8-slim-buster
RUN apt update && apt upgrade -y
RUN apt install git -y
COPY requirements.txt /requirements.txt
RUN cd /
RUN pip3 install -U pip && pip3 install -U -r requirements.txt
WORKDIR /PiroAutoFilterBot
COPY . .
CMD ["python3", "bot.py"]
================================================
FILE: LICENSE
================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
PiroAutoFilterBot

Use VPS Branch git clone https://github.com/ritheshrkrm/PiroAutoFilterBot # Install Packages pip3 install -U -r requirements.txt Edit info.py with variables as given below then run bot python3 bot.py
ᴀᴅᴅ ᴀ ꜰɪʟᴛᴇʀ ɪɴ ᴀ ᴄʜᴀᴛ
• /filters - ʟɪꜱᴛ ᴀʟʟ ᴛʜᴇ ꜰɪʟᴛᴇʀꜱ ᴏꜰ ᴀ ᴄʜᴀᴛ
• /del - ᴅᴇʟᴇᴛᴇ ᴀ ꜱᴘᴇᴄɪꜰɪᴄ ꜰɪʟᴛᴇʀ ɪɴ ᴀ ᴄʜᴀᴛ
• /delall - ᴅᴇʟᴇᴛᴇ ᴛʜᴇ ᴡʜᴏʟᴇ ꜰɪʟᴛᴇʀꜱ ɪɴ ᴀ ᴄʜᴀᴛ (ᴄʜᴀᴛ ᴏᴡɴᴇʀ ᴏɴʟʏ)"""
BUTTON_TXT = """ʜᴇʟᴘ: ʙᴜᴛᴛᴏɴꜱ
- ᴛʜɪꜱ ʙᴏᴛ ꜱᴜᴘᴘᴏʀᴛꜱ ʙᴏᴛʜ ᴜʀʟ ᴀɴᴅ ᴀʟᴇʀᴛ ɪɴʟɪɴᴇ ʙᴜᴛᴛᴏɴꜱ.
ɴᴏᴛᴇ:
1. ᴛᴇʟᴇɢʀᴀᴍ ᴡɪʟʟ ɴᴏᴛ ᴀʟʟᴏᴡꜱ ʏᴏᴜ ᴛᴏ ꜱᴇɴᴅ ʙᴜᴛᴛᴏɴꜱ ᴡɪᴛʜᴏᴜᴛ ᴀɴʏ ᴄᴏɴᴛᴇɴᴛ, ꜱᴏ ᴄᴏɴᴛᴇɴᴛ ɪꜱ ᴍᴀɴᴅᴀᴛᴏʀʏ.
2. ᴛʜɪꜱ ʙᴏᴛ ꜱᴜᴘᴘᴏʀᴛꜱ ʙᴜᴛᴛᴏɴꜱ ᴡɪᴛʜ ᴀɴʏ ᴛᴇʟᴇɢʀᴀᴍ ᴍᴇᴅɪᴀ ᴛʏᴘᴇ.
3. ʙᴜᴛᴛᴏɴꜱ ꜱʜᴏᴜʟᴅ ʙᴇ ᴘʀᴏᴘᴇʀʟʏ ᴘᴀʀꜱᴇᴅ ᴀꜱ ᴍᴀʀᴋᴅᴏᴡɴ ꜰᴏʀᴍᴀᴛ
ᴜʀʟ ʙᴜᴛᴛᴏɴꜱ:
[Button Text](buttonurl:https://t.me/piroxbots)
ᴀʟᴇʀᴛ ʙᴜᴛᴛᴏɴꜱ:
[Button Text](buttonalert:ᴛʜɪꜱ ɪꜱ ᴀɴ ᴀʟᴇʀᴛ ᴍᴇꜱꜱᴀɢᴇ)"""
AUTOFILTER_TXT = """ʜᴇʟᴘ: ᴀᴜᴛᴏ ꜰɪʟᴛᴇʀ
ɴᴏᴛᴇ: Fɪʟᴇ Iɴᴅᴇx
1. ᴍᴀᴋᴇ ᴍᴇ ᴛʜᴇ ᴀᴅᴍɪɴ ᴏꜰ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ɪꜰ ɪᴛ'ꜱ ᴘʀɪᴠᴀᴛᴇ.
2. ᴍᴀᴋᴇ ꜱᴜʀᴇ ᴛʜᴀᴛ ʏᴏᴜʀ ᴄʜᴀɴɴᴇʟ ᴅᴏᴇꜱ ɴᴏᴛ ᴄᴏɴᴛᴀɪɴꜱ ᴄᴀᴍʀɪᴘꜱ, ᴘᴏʀɴ ᴀɴᴅ ꜰᴀᴋᴇ ꜰɪʟᴇꜱ.
3. ꜰᴏʀᴡᴀʀᴅ ᴛʜᴇ ʟᴀꜱᴛ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴍᴇ ᴡɪᴛʜ Qᴜᴏᴛᴇꜱ. ɪ'ʟʟ ᴀᴅᴅ ᴀʟʟ ᴛʜᴇ ꜰɪʟᴇꜱ ɪɴ ᴛʜᴀᴛ ᴄʜᴀɴɴᴇʟ ᴛᴏ ᴍʏ ᴅʙ.
Nᴏᴛᴇ: AᴜᴛᴏFɪʟᴛᴇʀ
1. Aᴅᴅ ᴛʜᴇ ʙᴏᴛ ᴀs ᴀᴅᴍɪɴ ᴏɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ.
2. Usᴇ /connect ᴀɴᴅ ᴄᴏɴɴᴇᴄᴛ ʏᴏᴜʀ ɢʀᴏᴜᴘ ᴛᴏ ᴛʜᴇ ʙᴏᴛ.
3. Usᴇ /settings ᴏɴ ʙᴏᴛ's PM ᴀɴᴅ ᴛᴜʀɴ ᴏɴ AᴜᴛᴏFɪʟᴛᴇʀ ᴏɴ ᴛʜᴇ sᴇᴛᴛɪɴɢs ᴍᴇɴᴜ."""
CONNECTION_TXT = """ʜᴇʟᴘ: ᴄᴏɴɴᴇᴄᴛɪᴏɴꜱ
- ᴜꜱᴇᴅ ᴛᴏ ᴄᴏɴɴᴇᴄᴛ ʙᴏᴛ ᴛᴏ ᴘᴍ ꜰᴏʀ ᴍᴀɴᴀɢɪɴɢ ꜰɪʟᴛᴇʀꜱ
- ɪᴛ ʜᴇʟᴘꜱ ᴛᴏ ᴀᴠᴏɪᴅ ꜱᴘᴀᴍᴍɪɴɢ ɪɴ ɢʀᴏᴜᴘꜱ.
ɴᴏᴛᴇ:
1. ᴏɴʟʏ ᴀᴅᴍɪɴꜱ ᴄᴀɴ ᴀᴅᴅ ᴀ ᴄᴏɴɴᴇᴄᴛɪᴏɴ.
2. ꜱᴇɴᴅ /ᴄᴏɴɴᴇᴄᴛ ꜰᴏʀ ᴄᴏɴɴᴇᴄᴛɪɴɢ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ᴘᴍ
Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
• /connect - ᴄᴏɴɴᴇᴄᴛ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ᴄʜᴀᴛ ᴛᴏ ʏᴏᴜʀ ᴘᴍ
• /disconnect - ᴅɪꜱᴄᴏɴɴᴇᴄᴛ ꜰʀᴏᴍ ᴀ ᴄʜᴀᴛ
• /connections - ʟɪꜱᴛ ᴀʟʟ ʏᴏᴜʀ ᴄᴏɴɴᴇᴄᴛɪᴏɴꜱ"""
EXTRAMOD_TXT = """ʜᴇʟᴘ: Exᴛʀᴀ Mᴏᴅᴜʟᴇs
ɴᴏᴛᴇ:
ᴛʜᴇꜱᴇ ᴀʀᴇ ᴛʜᴇ ᴇxᴛʀᴀ ꜰᴇᴀᴛᴜʀᴇꜱ ᴏꜰ ᴛʜɪꜱ ʙᴏᴛ
Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
• /id - ɢᴇᴛ ɪᴅ ᴏꜰ ᴀ ꜱᴘᴇᴄɪꜰɪᴇᴅ ᴜꜱᴇʀ.
• /info - ɢᴇᴛ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ᴀʙᴏᴜᴛ ᴀ ᴜꜱᴇʀ.
• /imdb - ɢᴇᴛ ᴛʜᴇ ꜰɪʟᴍ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ꜰʀᴏᴍ ɪᴍᴅʙ ꜱᴏᴜʀᴄᴇ.
• /search - ɢᴇᴛ ᴛʜᴇ ꜰɪʟᴍ ɪɴꜰᴏʀᴍᴀᴛɪᴏɴ ꜰʀᴏᴍ ᴠᴀʀɪᴏᴜꜱ ꜱᴏᴜʀᴄᴇꜱ."""
ADMIN_TXT = """ʜᴇʟᴘ: Aᴅᴍɪɴ Mᴏᴅs
ɴᴏᴛᴇ:
Tʜɪs Mᴏᴅᴜʟᴇ Oɴʟʏ Wᴏʀᴋs Fᴏʀ Mʏ Aᴅᴍɪɴs
Cᴏᴍᴍᴀɴᴅs Aɴᴅ Usᴀɢᴇ:
• /logs - ᴛᴏ ɢᴇᴛ ᴛʜᴇ ʀᴇᴄᴇɴᴛ ᴇʀʀᴏʀꜱ
• /stats - ᴛᴏ ɢᴇᴛ ꜱᴛᴀᴛᴜꜱ ᴏꜰ ꜰɪʟᴇꜱ ɪɴ ᴅʙ. [Tʜɪs Cᴏᴍᴍᴀɴᴅ Cᴀɴ Bᴇ Usᴇᴅ Bʏ Aɴʏᴏɴᴇ]
• /delete - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀ ꜱᴘᴇᴄɪꜰɪᴄ ꜰɪʟᴇ ꜰʀᴏᴍ ᴅʙ.
• /users - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴍʏ ᴜꜱᴇʀꜱ ᴀɴᴅ ɪᴅꜱ.
• /chats - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴍʏ ᴄʜᴀᴛꜱ ᴀɴᴅ ɪᴅꜱ
• /leave - ᴛᴏ ʟᴇᴀᴠᴇ ꜰʀᴏᴍ ᴀ ᴄʜᴀᴛ.
• /disable - ᴛᴏ ᴅɪꜱᴀʙʟᴇ ᴀ ᴄʜᴀᴛ.
• /ban - ᴛᴏ ʙᴀɴ ᴀ ᴜꜱᴇʀ.
• /unban - ᴛᴏ ᴜɴʙᴀɴ ᴀ ᴜꜱᴇʀ.
• /channel - ᴛᴏ ɢᴇᴛ ʟɪꜱᴛ ᴏꜰ ᴛᴏᴛᴀʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ᴄʜᴀɴɴᴇʟꜱ
• /broadcast - ᴛᴏ ʙʀᴏᴀᴅᴄᴀꜱᴛ ᴀ ᴍᴇꜱꜱᴀɢᴇ ᴛᴏ ᴀʟʟ ᴜꜱᴇʀꜱ
• /group_broadcast - Tᴏ ʙʀᴏᴀᴅᴄᴀsᴛ ᴀ ᴍᴇssᴀɢᴇ ᴛᴏ ᴀʟʟ ᴄᴏɴɴᴇᴄᴛᴇᴅ ɢʀᴏᴜᴘs.
• /gfilter - ᴛᴏ ᴀᴅᴅ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs
• /gfilters - ᴛᴏ ᴠɪᴇᴡ ʟɪsᴛ ᴏғ ᴀʟʟ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs
• /delg - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀ sᴘᴇᴄɪғɪᴄ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ
• /request - Tᴏ sᴇɴᴅ ᴀ Mᴏᴠɪᴇ/Sᴇʀɪᴇs ʀᴇᴏ̨ᴜᴇsᴛ ᴛᴏ ʙᴏᴛ ᴀᴅᴍɪɴs. Oɴʟʏ ᴡᴏʀᴋs ᴏɴ sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ. [Tʜɪs Cᴏᴍᴍᴀɴᴅ Cᴀɴ Bᴇ Usᴇᴅ Bʏ Aɴʏᴏɴᴇ]
• /delallg - Tᴏ ᴅᴇʟᴇᴛᴇ ᴀʟʟ Gғɪʟᴛᴇʀs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ.
• /deletefiles - Tᴏ ᴅᴇʟᴇᴛᴇ CᴀᴍRɪᴘ ᴀɴᴅ PʀᴇDVD Fɪʟᴇs ғʀᴏᴍ ᴛʜᴇ ʙᴏᴛ's ᴅᴀᴛᴀʙᴀsᴇ."""
STATUS_TXT = """𝖳𝗈𝗍𝖺𝗅 𝖥𝗂𝗅𝖾𝗌: {}
𝖳𝗈𝗍𝖺𝗅 𝖬𝖾𝗆𝖻𝖾𝗋𝗌: {}
𝖳𝗈𝗍𝖺𝗅 𝖢𝗁𝖺𝗍𝗌: {}
𝖴𝗌𝖾𝖽 𝖲𝗍𝗈𝗋𝖺𝗀𝖾: {}
😎 𝖯𝗈𝗐𝖾𝗋𝖾𝖽 𝖻𝗒 @piroxbots"""
LOG_TEXT_G = """#NewGroup
𝖦𝗋𝗈𝗎𝗉 = {}({})
𝖳𝗈𝗍𝖺𝗅 𝖬𝖾𝗆𝖻𝖾𝗋𝗌 = {}
𝖠𝖽𝖽𝖾𝖽 𝖡𝗒 - {}"""
LOG_TEXT_P = """#NewUser
𝖨𝖽 - {}
𝖭𝖺𝗆𝖾 - {}"""
REQ_TXT = """𝖧𝖾𝗅𝗅𝗈 {}
𝖸𝗈𝗎𝗋 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 𝖧𝖺𝗌 𝖡𝖾𝖾𝗇 𝖠𝗉𝗉𝗋𝗈𝗏𝖾𝖽...!!!"""
ALRT_TXT = """Hello {},
This is Not your Request
Request Yourself...!!"""
OLD_ALRT_TXT = """Hey {},
You are using one of old message,
Request Again"""
CUDNT_FND = """
𝖨 𝖼𝗈𝗎𝗅𝖽𝗇'𝗍 𝖿𝗂𝗇𝖽 𝖺𝗇𝗒𝗍𝗁𝗂𝗇𝗀 𝗋𝖾𝗅𝖺𝗍𝖾𝖽 𝗍𝗈 𝗍𝗁𝖺𝗍
𝖣𝗂𝖽 𝗒𝗈𝗎 𝗆𝖾𝖺𝗇 𝖺𝗇𝗒 𝗈𝗇𝖾 𝗈𝖿 𝗍𝗁𝖾𝗌𝖾?"""
I_CUDNT = """❌ 𝖨 𝖼𝗈𝗎𝗅𝖽𝗇'𝗍 𝖿𝗂𝗇𝖽 𝖺𝗇𝗒𝗍𝗁𝗂𝗇𝗀 𝗋𝖾𝗅𝖺𝗍𝖾𝖽 𝗍𝗈 𝗍𝗁𝖺𝗍\n\n‼ 𝖱𝖾𝗉𝗈𝗋𝗍 𝗍𝗈 𝖺𝖽𝗆𝗂𝗇 ▶ @raixchat"""
I_CUD_NT = """❌ 𝖨 𝖼𝗈𝗎𝗅𝖽𝗇'𝗍 𝖿𝗂𝗇𝖽 𝖺𝗇𝗒𝗍𝗁𝗂𝗇𝗀 𝗋𝖾𝗅𝖺𝗍𝖾𝖽 𝗍𝗈 𝗍𝗁𝖺𝗍\n\n‼ 𝖱𝖾𝗉𝗈𝗋𝗍 𝗍𝗈 𝖺𝖽𝗆𝗂𝗇 ▶ @raixchat"""
MVE_NT_FND = """❌ 𝖨 𝖼𝗈𝗎𝗅𝖽𝗇'𝗍 𝖿𝗂𝗇𝖽 𝖺𝗇𝗒𝗍𝗁𝗂𝗇𝗀 𝗋𝖾𝗅𝖺𝗍𝖾𝖽 𝗍𝗈 𝗍𝗁𝖺𝗍\n\n‼ 𝖱𝖾𝗉𝗈𝗋𝗍 𝗍𝗈 𝖺𝖽𝗆𝗂𝗇 ▶ @raixchat"""
TOP_ALRT_MSG = """𝖢𝗁𝖾𝖼𝗄𝗂𝗇𝗀 𝖿𝗈𝗋 𝗊𝗎𝖾𝗋𝗒 𝗂𝗇 𝖣𝖺𝗍𝖺𝖻𝖺𝗌𝖾..."""
MELCOW_ENG = """Hey {}, Welcome to {}
• 𝖭𝗈 𝖯𝗋𝗈𝗆𝗈, 𝖭𝗈 𝖯𝗈𝗋𝗇, 𝖭𝗈 𝖮𝗍𝗁𝖾𝗋 𝖠𝖻𝗎𝗌𝖾𝗌
• 𝖠𝗌𝗄 𝖸𝗈𝗎𝗋 𝖬𝗈𝗏𝗂𝖾𝗌 𝖶𝗂𝗍𝗁 𝖢𝗈𝗋𝗋𝖾𝖼𝗍 𝖲𝗉𝖾𝗅𝗅𝗂𝗇𝗀
• 𝖲𝗉𝖺𝗆𝗆𝖾𝗋𝗌 𝖲𝗍𝖺𝗒 𝖠𝗐𝖺𝗒
• 𝖥𝖾𝖾𝗅 𝖥𝗋𝖾𝖾 𝖳𝗈 𝖱𝖾𝗉𝗈𝗋𝗍 𝖠𝗇𝗒 𝖤𝗋𝗋𝗈𝗋𝗌 𝖳𝗈 𝖠𝖽𝗆𝗂𝗇𝗌 𝗎𝗌𝗂𝗇𝗀 @admin
𝗥𝗲𝗾𝘂𝗲𝘀𝘁𝘀 𝗙𝗼𝗿𝗺𝗮𝘁𝘀
• 𝖲𝗈𝗅𝗈 2017
• 𝖣𝗁𝗈𝗈𝗆 3 𝖧𝗂𝗇𝖽𝗂
• 𝖪𝗎𝗋𝗎𝗉 𝖪𝖺𝗇
• 𝖣𝖺𝗋𝗄 𝗌01
• 𝖲𝗁𝖾 𝖧𝗎𝗅𝗄 720𝗉
• 𝖥𝗋𝗂𝖾𝗇𝖽𝗌 𝗌03 1080𝗉
• 𝖬𝗎𝗌𝗍 𝗋𝖾𝖺𝖽 𝗍𝗁𝗂𝗌 https://te.legra.ph/𝖯𝗈𝗐𝖾𝗋𝖾𝖽-𝖡𝗒-𝖯𝖨𝖱𝖮-12-11-2
‼️𝗗𝗼𝗻𝘁 𝗮𝗱𝗱 𝘄𝗼𝗿𝗱𝘀 & 𝘀𝘆𝗺𝗯𝗼𝗹𝘀 𝗹𝗶𝗸𝗲 , . - send link movie series 𝗲𝘁𝗰‼️"""
OWNER_INFO = """
○ 𝖢𝗋𝖾𝖺𝗍𝗈𝗋 : 𝖳𝗁𝗂𝗌 𝖯𝖾𝗋𝗌𝗈𝗇
○ 𝖲𝗎𝗉𝗉𝗈𝗋𝗍 𝖦𝗋𝗈𝗎𝗉 : 𝖳𝖺𝗉 𝖧𝖾𝗋𝖾
"""
NORSLTS = """
#NoResults
ID : {}
Name : {}
Message : {}"""
CAPTION = """
📂 File Name: {file_name}
❤️🔥 Join [𝗕𝗟𝗔𝗦𝗧𝗘𝗥 𝗟𝗜𝗡𝗞𝗭](https://t.me/blaster_linkz)
"""
IMDB_TEMPLATE_TXT = """
🏷 𝖳𝗂𝗍𝗅𝖾: {title}
🔮 𝖸𝖾𝖺𝗋: {year} \n⭐️ 𝖱𝖺𝗍𝗂𝗇𝗀𝗌: {rating}/ 10
🎭 𝖦𝖾𝗇𝖾𝗋𝗌: {genres}
🎊 𝖯𝗈𝗐𝖾𝗋𝖾𝖽 𝖡𝗒 [[𝖯𝖨𝖱𝖮]](t.me/piroxbots)"""
ALL_FILTERS = """
Hᴇʏ {}, Tʜᴇsᴇ ᴀʀᴇ ᴍʏ ᴛʜʀᴇᴇ ᴛʏᴘᴇs ᴏғ ғɪʟᴛᴇʀs."""
GFILTER_TXT = """
Wᴇʟᴄᴏᴍᴇ ᴛᴏ Gʟᴏʙᴀʟ Fɪʟᴛᴇʀs. Gʟᴏʙᴀʟ Fɪʟᴛᴇʀs ᴀʀᴇ ᴛʜᴇ ғɪʟᴛᴇʀs sᴇᴛ ʙʏ ʙᴏᴛ ᴀᴅᴍɪɴs ᴡʜɪᴄʜ ᴡɪʟʟ ᴡᴏʀᴋ ᴏɴ ᴀʟʟ ɢʀᴏᴜᴘs.
Aᴠᴀɪʟᴀʙʟᴇ ᴄᴏᴍᴍᴀɴᴅs:
• /gfilter - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ.
• /gfilters - Tᴏ ᴠɪᴇᴡ ᴀʟʟ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀs.
• /delg - Tᴏ ᴅᴇʟᴇᴛᴇ ᴀ ᴘᴀʀᴛɪᴄᴜʟᴀʀ ɢʟᴏʙᴀʟ ғɪʟᴛᴇʀ.
• /delallg - ᴛᴏ ᴅᴇʟᴇᴛᴇ ᴀʟʟ ɢʟᴏʙᴀʟ ꜰɪʟᴛᴇʀꜱ."""
FILE_STORE_TXT = """
Fɪʟᴇ sᴛᴏʀᴇ ɪs ᴛʜᴇ ғᴇᴀᴛᴜʀᴇ ᴡʜɪᴄʜ ᴡɪʟʟ ᴄʀᴇᴀᴛᴇ ᴀ sʜᴀʀᴇᴀʙʟᴇ ʟɪɴᴋ ᴏғ ᴀ sɪɴɢʟᴇ ᴏʀ ᴍᴜʟᴛɪᴘʟᴇ ғɪʟᴇs.
Aᴠᴀɪʟᴀʙʟᴇ ᴄᴏᴍᴍᴀɴᴅs:
• /batch - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ ʙᴀᴛᴄʜ ʟɪɴᴋ ᴏғ ᴍᴜʟᴛɪᴘʟᴇ ғɪʟᴇs.
• /link - Tᴏ ᴄʀᴇᴀᴛᴇ ᴀ sɪɴɢʟᴇ ғɪʟᴇ sᴛᴏʀᴇ ʟɪɴᴋ.
• /pbatch - Jᴜsᴛ ʟɪᴋᴇ /batch, ʙᴜᴛ ᴛʜᴇ ғɪʟᴇs ᴡɪʟʟ ʙᴇ sᴇɴᴅ ᴡɪᴛʜ ғᴏʀᴡᴀʀᴅ ʀᴇsᴛʀɪᴄᴛɪᴏɴs.
• /plink - Jᴜsᴛ ʟɪᴋᴇ /link, ʙᴜᴛ ᴛʜᴇ ғɪʟᴇ ᴡɪʟʟ ʙᴇ sᴇɴᴅ ᴡɪᴛʜ ғᴏʀᴡᴀʀᴅ ʀᴇsᴛʀɪᴄᴛɪᴏɴ."""
RESTART_TXT = """
𝖡𝗈𝗍 𝖱𝖾𝗌𝗍𝖺𝗋𝗍𝖾𝖽 !
📅 𝖣𝖺𝗍𝖾 : {}
⏰ 𝖳𝗂𝗆𝖾 : {}
🌐 𝖳𝗂𝗆𝖾𝗓𝗈𝗇𝖾 : Asia/Kolkata
🛠️ 𝖡𝗎𝗂𝗅𝖽 𝖲𝗍𝖺𝗍𝗎𝗌 : 𝗏2.7.3 [ 𝖲𝗍𝖺𝖻𝗅𝖾 ]"""
RESTART_GC_TXT = """
𝖡𝗈𝗍 𝖱𝖾𝗌𝗍𝖺𝗋𝗍𝖾𝖽 ✅"""
LOGO = """
PIRO BOTS"""
================================================
FILE: app.json
================================================
{
"name": "PiroAutoFilterBot",
"description": "When you going to send file on telegram channel this bot will save that in database, So you can search that easily in inline mode",
"stack": "container",
"keywords": [
"telegram",
"auto-filter",
"filter",
"best",
"indian",
"pyrogram",
"media",
"search",
"channel",
"index",
"inline"
],
"website": "https://github.com/ritheshrkrm/PiroAutoFilterBot",
"repository": "https://github.com/ritheshrkrm/PiroAutoFilterBot",
"env": {
"BOT_TOKEN": {
"description": "Your bot token.",
"required": true
},
"API_ID": {
"description": "Get this value from https://my.telegram.org",
"required": true
},
"API_HASH": {
"description": "Get this value from https://my.telegram.org",
"required": true
},
"CHANNELS": {
"description": "Username or ID of channel or group. Separate multiple IDs by space.",
"required": false
},
"ADMINS": {
"description": "Username or ID of Admin. Separate multiple Admins by space.",
"required": true
},
"PICS": {
"description": "Add some telegraph link of pictures .",
"required": false
},
"LOG_CHANNEL": {
"description": "Bot Logs,Give a channel id with -100xxxxxxx",
"required": true
},
"AUTH_USERS": {
"description": "Username or ID of users to give access of inline search. Separate multiple users by space.\nLeave it empty if you don't want to restrict bot usage.",
"required": false
},
"AUTH_CHANNEL": {
"description": "ID of channel.Make sure bot is admin in this channel. Without subscribing this channel users cannot use bot.",
"required": false
},
"DATABASE_URI": {
"description": "mongoDB URI. Get this value from https://www.mongodb.com. For more help watch this video - https://youtu.be/dsuTn4qV2GA",
"required": true
},
"DATABASE_NAME": {
"description": "Name of the database in mongoDB. For more help watch this video - https://youtu.be/dsuTn4qV2GA",
"required": false
},
"COLLECTION_NAME": {
"description": "Name of the collections. Defaults to Telegram_files. If you are using the same database, then use different collection name for each bot",
"value": "Telegram_files",
"required": false
}
},
"addons": [],
"buildpacks": [{
"url": "heroku/python"
}],
"formation": {
"worker": {
"quantity": 1,
"size": "free"
}
}
}
================================================
FILE: bot.py
================================================
import logging
import logging.config
# Get logging configurations
logging.config.fileConfig('logging.conf')
logging.getLogger().setLevel(logging.INFO)
logging.getLogger("pyrogram").setLevel(logging.ERROR)
logging.getLogger("imdbpy").setLevel(logging.ERROR)
from pyrogram import Client, __version__
from pyrogram.raw.all import layer
from database.ia_filterdb import Media
from database.users_chats_db import db
from info import SESSION, API_ID, API_HASH, BOT_TOKEN, LOG_STR, LOG_CHANNEL, PORT ,SUPPORT_CHAT_ID
from utils import temp
from typing import Union, Optional, AsyncGenerator
from pyrogram import types
from Script import script
from datetime import date, datetime
import pytz
from aiohttp import web
from plugins import web_server
class Bot(Client):
def __init__(self):
super().__init__(
name=SESSION,
api_id=API_ID,
api_hash=API_HASH,
bot_token=BOT_TOKEN,
workers=50,
plugins={"root": "plugins"},
sleep_threshold=5,
)
async def start(self):
b_users, b_chats = await db.get_banned()
temp.BANNED_USERS = b_users
temp.BANNED_CHATS = b_chats
await super().start()
await Media.ensure_indexes()
me = await self.get_me()
temp.ME = me.id
temp.U_NAME = me.username
temp.B_NAME = me.first_name
self.username = '@' + me.username
logging.info(f"{me.first_name} with for Pyrogram v{__version__} (Layer {layer}) started on {me.username}.")
logging.info(LOG_STR)
logging.info(script.LOGO)
tz = pytz.timezone('Asia/Kolkata')
today = date.today()
now = datetime.now(tz)
time = now.strftime("%H:%M:%S %p")
await self.send_message(chat_id=LOG_CHANNEL, text=script.RESTART_TXT.format(today, time))
await self.send_message(chat_id=SUPPORT_CHAT_ID, text=script.RESTART_GC_TXT.format(today, time))
app = web.AppRunner(await web_server())
await app.setup()
bind_address = "0.0.0.0"
await web.TCPSite(app, bind_address, PORT).start()
async def stop(self, *args):
await super().stop()
logging.info("Bot stopped. Bye.")
async def iter_messages(
self,
chat_id: Union[int, str],
limit: int,
offset: int = 0,
) -> Optional[AsyncGenerator["types.Message", None]]:
"""Iterate through a chat sequentially.
This convenience method does the same as repeatedly calling :meth:`~pyrogram.Client.get_messages` in a loop, thus saving
you from the hassle of setting up boilerplate code. It is useful for getting the whole chat messages with a
single call.
Parameters:
chat_id (``int`` | ``str``):
Unique identifier (int) or username (str) of the target chat.
For your personal cloud (Saved Messages) you can simply use "me" or "self".
For a contact that exists in your Telegram address book you can use his phone number (str).
limit (``int``):
Identifier of the last message to be returned.
offset (``int``, *optional*):
Identifier of the first message to be returned.
Defaults to 0.
Returns:
``Generator``: A generator yielding :obj:`~pyrogram.types.Message` objects.
Example:
.. code-block:: python
for message in app.iter_messages("pyrogram", 1, 15000):
print(message.text)
"""
current = offset
while True:
new_diff = min(200, limit - current)
if new_diff <= 0:
return
messages = await self.get_messages(chat_id, list(range(current, current+new_diff+1)))
for message in messages:
yield message
current += 1
app = Bot()
app.run()
================================================
FILE: database/connections_mdb.py
================================================
import pymongo
from info import DATABASE_URI, DATABASE_NAME
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
myclient = pymongo.MongoClient(DATABASE_URI)
mydb = myclient[DATABASE_NAME]
mycol = mydb['CONNECTION']
async def add_connection(group_id, user_id):
query = mycol.find_one(
{ "_id": user_id },
{ "_id": 0, "active_group": 0 }
)
if query is not None:
group_ids = [x["group_id"] for x in query["group_details"]]
if group_id in group_ids:
return False
group_details = {
"group_id" : group_id
}
data = {
'_id': user_id,
'group_details' : [group_details],
'active_group' : group_id,
}
if mycol.count_documents( {"_id": user_id} ) == 0:
try:
mycol.insert_one(data)
return True
except:
logger.exception('Some error occurred!', exc_info=True)
else:
try:
mycol.update_one(
{'_id': user_id},
{
"$push": {"group_details": group_details},
"$set": {"active_group" : group_id}
}
)
return True
except:
logger.exception('Some error occurred!', exc_info=True)
async def active_connection(user_id):
query = mycol.find_one(
{ "_id": user_id },
{ "_id": 0, "group_details": 0 }
)
if not query:
return None
group_id = query['active_group']
return int(group_id) if group_id != None else None
async def all_connections(user_id):
query = mycol.find_one(
{ "_id": user_id },
{ "_id": 0, "active_group": 0 }
)
if query is not None:
return [x["group_id"] for x in query["group_details"]]
else:
return None
async def if_active(user_id, group_id):
query = mycol.find_one(
{ "_id": user_id },
{ "_id": 0, "group_details": 0 }
)
return query is not None and query['active_group'] == group_id
async def make_active(user_id, group_id):
update = mycol.update_one(
{'_id': user_id},
{"$set": {"active_group" : group_id}}
)
return update.modified_count != 0
async def make_inactive(user_id):
update = mycol.update_one(
{'_id': user_id},
{"$set": {"active_group" : None}}
)
return update.modified_count != 0
async def delete_connection(user_id, group_id):
try:
update = mycol.update_one(
{"_id": user_id},
{"$pull" : { "group_details" : {"group_id":group_id} } }
)
if update.modified_count == 0:
return False
query = mycol.find_one(
{ "_id": user_id },
{ "_id": 0 }
)
if len(query["group_details"]) >= 1:
if query['active_group'] == group_id:
prvs_group_id = query["group_details"][len(query["group_details"]) - 1]["group_id"]
mycol.update_one(
{'_id': user_id},
{"$set": {"active_group" : prvs_group_id}}
)
else:
mycol.update_one(
{'_id': user_id},
{"$set": {"active_group" : None}}
)
return True
except Exception as e:
logger.exception(f'Some error occurred! {e}', exc_info=True)
return False
================================================
FILE: database/filters_mdb.py
================================================
import pymongo
from info import DATABASE_URI, DATABASE_NAME
from pyrogram import enums
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
myclient = pymongo.MongoClient(DATABASE_URI)
mydb = myclient[DATABASE_NAME]
async def add_filter(grp_id, text, reply_text, btn, file, alert):
mycol = mydb[str(grp_id)]
# mycol.create_index([('text', 'text')])
data = {
'text':str(text),
'reply':str(reply_text),
'btn':str(btn),
'file':str(file),
'alert':str(alert)
}
try:
mycol.update_one({'text': str(text)}, {"$set": data}, upsert=True)
except:
logger.exception('Some error occured!', exc_info=True)
async def find_filter(group_id, name):
mycol = mydb[str(group_id)]
query = mycol.find( {"text":name})
# query = mycol.find( { "$text": {"$search": name}})
try:
for file in query:
reply_text = file['reply']
btn = file['btn']
fileid = file['file']
try:
alert = file['alert']
except:
alert = None
return reply_text, btn, alert, fileid
except:
return None, None, None, None
async def get_filters(group_id):
mycol = mydb[str(group_id)]
texts = []
query = mycol.find()
try:
for file in query:
text = file['text']
texts.append(text)
except:
pass
return texts
async def delete_filter(message, text, group_id):
mycol = mydb[str(group_id)]
myquery = {'text':text }
query = mycol.count_documents(myquery)
if query == 1:
mycol.delete_one(myquery)
await message.reply_text(
f"'`{text}`' deleted. I'll not respond to that filter anymore.",
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
else:
await message.reply_text("Couldn't find that filter!", quote=True)
async def del_all(message, group_id, title):
if str(group_id) not in mydb.list_collection_names():
await message.edit_text(f"Nothing to remove in {title}!")
return
mycol = mydb[str(group_id)]
try:
mycol.drop()
await message.edit_text(f"All filters from {title} has been removed")
except:
await message.edit_text("Couldn't remove all filters from group!")
return
async def count_filters(group_id):
mycol = mydb[str(group_id)]
count = mycol.count()
return False if count == 0 else count
async def filter_stats():
collections = mydb.list_collection_names()
if "CONNECTION" in collections:
collections.remove("CONNECTION")
totalcount = 0
for collection in collections:
mycol = mydb[collection]
count = mycol.count()
totalcount += count
totalcollections = len(collections)
return totalcollections, totalcount
================================================
FILE: database/gfilters_mdb.py
================================================
import pymongo
from info import DATABASE_URI, DATABASE_NAME
from pyrogram import enums
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
myclient = pymongo.MongoClient(DATABASE_URI)
mydb = myclient[DATABASE_NAME]
async def add_gfilter(gfilters, text, reply_text, btn, file, alert):
mycol = mydb[str(gfilters)]
data = {
'text':str(text),
'reply':str(reply_text),
'btn':str(btn),
'file':str(file),
'alert':str(alert)
}
try:
mycol.update_one({'text': str(text)}, {"$set": data}, upsert=True)
except:
logger.exception('Some error occured!', exc_info=True)
async def find_gfilter(gfilters, name):
mycol = mydb[str(gfilters)]
query = mycol.find( {"text":name})
# query = mycol.find( { "$text": {"$search": name}})
try:
for file in query:
reply_text = file['reply']
btn = file['btn']
fileid = file['file']
try:
alert = file['alert']
except:
alert = None
return reply_text, btn, alert, fileid
except:
return None, None, None, None
async def get_gfilters(gfilters):
mycol = mydb[str(gfilters)]
texts = []
query = mycol.find()
try:
for file in query:
text = file['text']
texts.append(text)
except:
pass
return texts
async def delete_gfilter(message, text, gfilters):
mycol = mydb[str(gfilters)]
myquery = {'text':text }
query = mycol.count_documents(myquery)
if query == 1:
mycol.delete_one(myquery)
await message.reply_text(
f"'`{text}`' deleted. I'll not respond to that gfilter anymore.",
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
else:
await message.reply_text("Couldn't find that gfilter!", quote=True)
async def del_allg(message, gfilters):
if str(gfilters) not in mydb.list_collection_names():
await message.edit_text("Nothing to Remove !")
return
mycol = mydb[str(gfilters)]
try:
mycol.drop()
await message.edit_text(f"All gfilters has been removed !")
except:
await message.edit_text("Couldn't remove all gfilters !")
return
async def count_gfilters(gfilters):
mycol = mydb[str(gfilters)]
count = mycol.count()
return False if count == 0 else count
async def gfilter_stats():
collections = mydb.list_collection_names()
if "CONNECTION" in collections:
collections.remove("CONNECTION")
totalcount = 0
for collection in collections:
mycol = mydb[collection]
count = mycol.count()
totalcount += count
totalcollections = len(collections)
return totalcollections, totalcount
================================================
FILE: database/ia_filterdb.py
================================================
import logging
from struct import pack
import re
import base64
from pyrogram.file_id import FileId
from pymongo.errors import DuplicateKeyError
from umongo import Instance, Document, fields
from motor.motor_asyncio import AsyncIOMotorClient
from marshmallow.exceptions import ValidationError
from info import DATABASE_URI, DATABASE_NAME, COLLECTION_NAME, USE_CAPTION_FILTER, MAX_B_TN
from utils import get_settings, save_group_settings
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
client = AsyncIOMotorClient(DATABASE_URI)
db = client[DATABASE_NAME]
instance = Instance.from_db(db)
@instance.register
class Media(Document):
file_id = fields.StrField(attribute='_id')
file_ref = fields.StrField(allow_none=True)
file_name = fields.StrField(required=True)
file_size = fields.IntField(required=True)
file_type = fields.StrField(allow_none=True)
mime_type = fields.StrField(allow_none=True)
caption = fields.StrField(allow_none=True)
class Meta:
indexes = ('$file_name', )
collection_name = COLLECTION_NAME
async def save_file(media):
"""Save file in database"""
# TODO: Find better way to get same file_id for same media to avoid duplicates
file_id, file_ref = unpack_new_file_id(media.file_id)
file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
try:
file = Media(
file_id=file_id,
file_ref=file_ref,
file_name=file_name,
file_size=media.file_size,
file_type=media.file_type,
mime_type=media.mime_type,
caption=media.caption.html if media.caption else None,
)
except ValidationError:
logger.exception('Error occurred while saving file in database')
return False, 2
else:
try:
await file.commit()
except DuplicateKeyError:
logger.warning(
f'{getattr(media, "file_size", "NO_FILE")} is already saved in database'
)
return False, 0
else:
logger.info(f'{getattr(media, "file_size", "NO_FILE")} is saved to database')
return True, 1
async def get_search_results(chat_id, query, file_type=None, max_results=10, offset=0, filter=False):
"""For given query return (results, next_offset)"""
if chat_id is not None:
settings = await get_settings(int(chat_id))
try:
if settings['max_btn']:
max_results = 10
else:
max_results = int(MAX_B_TN)
except KeyError:
await save_group_settings(int(chat_id), 'max_btn', False)
settings = await get_settings(int(chat_id))
if settings['max_btn']:
max_results = 10
else:
max_results = int(MAX_B_TN)
query = query.strip()
#if filter:
#better ?
#query = query.replace(' ', r'(\s|\.|\+|\-|_)')
#raw_pattern = r'(\s|_|\-|\.|\+)' + query + r'(\s|_|\-|\.|\+)'
if not query:
raw_pattern = '.'
elif ' ' not in query:
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')
try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
return []
if USE_CAPTION_FILTER:
filter = {'$or': [{'file_name': regex}, {'caption': regex}]}
else:
filter = {'file_name': regex}
if file_type:
filter['file_type'] = file_type
total_results = await Media.count_documents(filter)
next_offset = offset + max_results
if next_offset > total_results:
next_offset = ''
cursor = Media.find(filter)
# Sort by recent
cursor.sort('$natural', -1)
# Slice files according to offset and max results
cursor.skip(offset).limit(max_results)
# Get list of files
files = await cursor.to_list(length=max_results)
return files, next_offset, total_results
async def get_bad_files(query, file_type=None, filter=False):
"""For given query return (results, next_offset)"""
query = query.strip()
#if filter:
#better ?
#query = query.replace(' ', r'(\s|\.|\+|\-|_)')
#raw_pattern = r'(\s|_|\-|\.|\+)' + query + r'(\s|_|\-|\.|\+)'
if not query:
raw_pattern = '.'
elif ' ' not in query:
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')
try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
return []
if USE_CAPTION_FILTER:
filter = {'$or': [{'file_name': regex}, {'caption': regex}]}
else:
filter = {'file_name': regex}
if file_type:
filter['file_type'] = file_type
total_results = await Media.count_documents(filter)
cursor = Media.find(filter)
# Sort by recent
cursor.sort('$natural', -1)
# Get list of files
files = await cursor.to_list(length=total_results)
return files, total_results
async def get_file_details(query):
filter = {'file_id': query}
cursor = Media.find(filter)
filedetails = await cursor.to_list(length=1)
return filedetails
def encode_file_id(s: bytes) -> str:
r = b""
n = 0
for i in s + bytes([22]) + bytes([4]):
if i == 0:
n += 1
else:
if n:
r += b"\x00" + bytes([n])
n = 0
r += bytes([i])
return base64.urlsafe_b64encode(r).decode().rstrip("=")
def encode_file_ref(file_ref: bytes) -> str:
return base64.urlsafe_b64encode(file_ref).decode().rstrip("=")
def unpack_new_file_id(new_file_id):
"""Return file_id, file_ref"""
decoded = FileId.decode(new_file_id)
file_id = encode_file_id(
pack(
"{file_name} \n\n❤️🔥 Join [𝗕𝗟𝗔𝗦𝗧𝗘𝗥 𝗟𝗜𝗡𝗞𝗭](https://t.me/blaster_linkz)')
BATCH_FILE_CAPTION = environ.get("BATCH_FILE_CAPTION", '')
IMDB_TEMPLATE = environ.get("IMDB_TEMPLATE", '🏷 𝖳𝗂𝗍𝗅𝖾: {title} \n🔮 𝖸𝖾𝖺𝗋: {year} \n⭐️ 𝖱𝖺𝗍𝗂𝗇𝗀𝗌: {rating}/ 10 \n🎭 𝖦𝖾𝗇𝖾𝗋𝗌: {genres} \n\n🎊 𝖯𝗈𝗐𝖾𝗋𝖾𝖽 𝖡𝗒 [[𝖯𝖨𝖱𝖮]](t.me/piroxbots)')
LONG_IMDB_DESCRIPTION = is_enabled(environ.get("LONG_IMDB_DESCRIPTION", "False"), False)
SPELL_CHECK_REPLY = is_enabled(environ.get("SPELL_CHECK_REPLY", "True"), True)
MAX_LIST_ELM = environ.get("MAX_LIST_ELM", None)
INDEX_REQ_CHANNEL = int(environ.get('INDEX_REQ_CHANNEL', LOG_CHANNEL))
FILE_STORE_CHANNEL = [int(ch) for ch in (environ.get('FILE_STORE_CHANNEL', '')).split()]
MELCOW_NEW_USERS = is_enabled((environ.get('MELCOW_NEW_USERS', "True")), True)
PROTECT_CONTENT = is_enabled((environ.get('PROTECT_CONTENT', "False")), False)
PUBLIC_FILE_STORE = is_enabled((environ.get('PUBLIC_FILE_STORE', "False")), True)
LOG_STR = "Current Cusomized Configurations are:-\n"
LOG_STR += ("IMDB Results are enabled, Bot will be showing imdb details for you queries.\n" if IMDB else "IMBD Results are disabled.\n")
LOG_STR += ("P_TTI_SHOW_OFF found , Users will be redirected to send /start to Bot PM instead of sending file file directly\n" if P_TTI_SHOW_OFF else "P_TTI_SHOW_OFF is disabled files will be send in PM, instead of sending start.\n")
LOG_STR += ("SINGLE_BUTTON is Found, filename and files size will be shown in a single button instead of two separate buttons\n" if SINGLE_BUTTON else "SINGLE_BUTTON is disabled , filename and file_sixe will be shown as different buttons\n")
LOG_STR += (f"CUSTOM_FILE_CAPTION enabled with value {CUSTOM_FILE_CAPTION}, your files will be send along with this customized caption.\n" if CUSTOM_FILE_CAPTION else "No CUSTOM_FILE_CAPTION Found, Default captions of file will be used.\n")
LOG_STR += ("Long IMDB storyline enabled." if LONG_IMDB_DESCRIPTION else "LONG_IMDB_DESCRIPTION is disabled , Plot will be shorter.\n")
LOG_STR += ("Spell Check Mode Is Enabled, bot will be suggesting related movies if movie not found\n" if SPELL_CHECK_REPLY else "SPELL_CHECK_REPLY Mode disabled\n")
LOG_STR += (f"MAX_LIST_ELM Found, long list will be shortened to first {MAX_LIST_ELM} elements\n" if MAX_LIST_ELM else "Full List of casts and crew will be shown in imdb template, restrict them by adding a value to MAX_LIST_ELM\n")
LOG_STR += f"Your current IMDB template is {IMDB_TEMPLATE}"
================================================
FILE: logging.conf
================================================
[loggers]
keys=root
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=consoleFormatter,fileFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler,fileHandler
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=consoleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=ERROR
formatter=fileFormatter
args=('Logs.txt','w',)
[formatter_consoleFormatter]
format=%(asctime)s - %(lineno)d - %(name)s - %(module)s - %(levelname)s - %(message)s
datefmt=%I:%M:%S %p
[formatter_fileFormatter]
format=[%(asctime)s:%(name)s:%(lineno)d:%(levelname)s] %(message)s
datefmt=%m/%d/%Y %I:%M:%S %p
================================================
FILE: plugins/__init__.py
================================================
from aiohttp import web
from .route import routes
async def web_server():
web_app = web.Application(client_max_size=30000000)
web_app.add_routes(routes)
return web_app
================================================
FILE: plugins/approve.py
================================================
from pyrogram import Client
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from pyrogram.errors import UserIsBlocked, PeerIdInvalid
@Client.on_chat_join_request()
async def accept_request(client, r):
rm = InlineKeyboardMarkup([[
InlineKeyboardButton("❤️🔥 𝖡𝖫𝖠𝖲𝖳𝖤𝖱 𝖧𝖴𝖡 ❤️🔥", url=f"https://t.me/blaster_hub"),
InlineKeyboardButton("⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡", url=f"https://t.me/piroxbots")
]])
try:
await client.send_photo(
r.from_user.id,
'https://graph.org/file/5cb80fa6096997b7226b3.jpg',
f"**𝖧𝖾𝗅𝗅𝗈 {r.from_user.mention} 👻, 𝖶𝖾𝗅𝖼𝗈𝗆𝖾 𝖳𝗈 {r.chat.title}\n𝖸𝗈𝗎𝗋 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 𝖧𝖺𝗌 𝖡𝖾𝖾𝗇 𝖠𝗉𝗉𝗋𝗈𝗏𝖾𝖽...!!!**",
reply_markup=rm)
except UserIsBlocked:
print("User blocked the bot")
except PeerIdInvalid:
print("Err")
except Exception as e:
print(f"#Error\n{str(e)}")
await r.approve()
================================================
FILE: plugins/banned.py
================================================
from pyrogram import Client, filters
from utils import temp
from pyrogram.types import Message
from database.users_chats_db import db
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from info import SUPPORT_CHAT
async def banned_users(_, client, message: Message):
return (
message.from_user is not None or not message.sender_chat
) and message.from_user.id in temp.BANNED_USERS
banned_user = filters.create(banned_users)
async def disabled_chat(_, client, message: Message):
return message.chat.id in temp.BANNED_CHATS
disabled_group=filters.create(disabled_chat)
@Client.on_message(filters.private & banned_user & filters.incoming)
async def ban_reply(bot, message):
ban = await db.get_ban_status(message.from_user.id)
await message.reply(f'‼️Sorry Dude, You are Banned to use Me.‼️ \n\nBan Reason: {ban["ban_reason"]}')
@Client.on_message(filters.group & disabled_group & filters.incoming)
async def grp_bd(bot, message):
buttons = [[
InlineKeyboardButton('🧩 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 🧩', url=f"https://t.me/{SUPPORT_CHAT}")
]]
reply_markup=InlineKeyboardMarkup(buttons)
vazha = await db.get_chat(message.chat.id)
k = await message.reply(
text=f"CHAT NOT ALLOWED 🐞\n\nMy admins has restricted me from working here ! If you want to know more about it contact 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 GROUP..\nReason : {vazha['reason']}.",
reply_markup=reply_markup)
try:
await k.pin()
except:
pass
await bot.leave_chat(message.chat.id)
================================================
FILE: plugins/broadcast.py
================================================
from pyrogram import Client, filters
import datetime
import time
from database.users_chats_db import db
from info import ADMINS
from utils import broadcast_messages, broadcast_messages_group
import asyncio
@Client.on_message(filters.command("broadcast") & filters.user(ADMINS) & filters.reply)
async def verupikkals(bot, message):
users = await db.get_all_users()
b_msg = message.reply_to_message
sts = await message.reply_text(
text='🔊 Broadcasting your messages...'
)
start_time = time.time()
total_users = await db.total_users_count()
done = 0
blocked = 0
deleted = 0
failed =0
success = 0
async for user in users:
pti, sh = await broadcast_messages(int(user['id']), b_msg)
if pti:
success += 1
elif pti == False:
if sh == "Blocked":
blocked+=1
elif sh == "Deleted":
deleted += 1
elif sh == "Error":
failed += 1
done += 1
await asyncio.sleep(2)
if not done % 20:
await sts.edit(f"Broadcast in progress:\n\nTotal Users {total_users}\nCompleted: {done} / {total_users}\nSuccess: {success}\nBlocked: {blocked}\nDeleted: {deleted}")
time_taken = datetime.timedelta(seconds=int(time.time()-start_time))
await sts.edit(f"Broadcast Completed:\nCompleted in {time_taken} seconds.\n\nTotal Users {total_users}\nCompleted: {done} / {total_users}\nSuccess: {success}\nBlocked: {blocked}\nDeleted: {deleted}")
@Client.on_message(filters.command("group_broadcast") & filters.user(ADMINS) & filters.reply)
async def broadcast_group(bot, message):
groups = await db.get_all_chats()
b_msg = message.reply_to_message
sts = await message.reply_text(
text='🔊 Broadcasting your messages To Groups...'
)
start_time = time.time()
total_groups = await db.total_chat_count()
done = 0
failed =0
success = 0
async for group in groups:
pti, sh = await broadcast_messages_group(int(group['id']), b_msg)
if pti:
success += 1
elif sh == "Error":
failed += 1
done += 1
if not done % 20:
await sts.edit(f"Broadcast in progress:\n\nTotal Groups {total_groups}\nCompleted: {done} / {total_groups}\nSuccess: {success}")
time_taken = datetime.timedelta(seconds=int(time.time()-start_time))
await sts.edit(f"Broadcast Completed:\nCompleted in {time_taken} seconds.\n\nTotal Groups {total_groups}\nCompleted: {done} / {total_groups}\nSuccess: {success}")
================================================
FILE: plugins/channel.py
================================================
from pyrogram import Client, filters
from info import CHANNELS
from database.ia_filterdb import save_file
media_filter = filters.document | filters.video
@Client.on_message(filters.chat(CHANNELS) & media_filter)
async def media(bot, message):
"""Media Handler"""
for file_type in ("document", "video"):
media = getattr(message, file_type, None)
if media is not None:
break
else:
return
media.file_type = file_type
media.caption = message.caption
await save_file(media)
================================================
FILE: plugins/check_alive.py
================================================
import random
import re, asyncio, time, shutil, psutil, os, sys
from pyrogram import Client, filters, enums
from pyrogram.types import *
from info import BOT_START_TIME, ADMINS
from utils import humanbytes
CMD = ["/", "."]
@Client.on_message(filters.command("alive", CMD))
async def check_alive(_, message):
await message.reply_text("𝖡𝗎𝖽𝖽𝗒 𝖨𝖺𝗆 𝖠𝗅𝗂𝗏𝖾 :) 𝖧𝗂𝗍 /start \n\n𝖧𝗂𝗍 /help 𝖥𝗈𝗋 𝖧𝖾𝗅𝗉 ;)\n\n\n𝖧𝗂𝗍 /ping 𝖳𝗈 𝖢𝗁𝖾𝖼𝗄 𝖡𝗈𝗍 𝖯𝗂𝗇𝗀 😁")
@Client.on_message(filters.command("help", CMD))
async def help(_, message):
await message.reply_text("𝖧𝗂𝗍 /movie 𝖥𝗈𝗋 𝖬𝗈𝗏𝗂𝖾 𝖲𝖾𝖺𝗋𝖼𝗁 𝖱𝗎𝗅𝖾𝗌 📃\n\n𝖧𝗂𝗍 /series 𝖥𝗈𝗋 𝖲𝖾𝗋𝗂𝖾𝗌 𝖲𝖾𝖺𝗋𝖼𝗁 𝖱𝗎𝗅𝖾𝗌 📃\n\n\n𝖧𝗂𝗍 /tutorial 𝖥𝗈𝗋 𝖯𝗋𝗈𝗉𝖾𝗋 𝖳𝗎𝗍𝗈𝗋𝗂𝖺𝗅 𝖵𝗂𝖽𝖾𝗈𝗌 🤗")
@Client.on_message(filters.command("movie", CMD))
async def movie(_, message):
await message.reply_text("⚠️❗️ 𝗠𝗼𝘃𝗶𝗲 𝗥𝗲𝗾𝘂𝗲𝘀𝘁 𝗙𝗼𝗿𝗺𝗮𝘁 ❗️⚠️\n\n📝 𝖬𝗈𝗏𝗂𝖾 𝖭𝖺𝗆𝖾, 𝖸𝖾𝖺𝗋,(𝖨𝖿 𝗒𝗈𝗎 𝖪𝗇𝗈𝗐) 𝖶𝗂𝗍𝗁 𝖢𝗈𝗋𝗋𝖾𝖼𝗍 𝖲𝗉𝖾𝗅𝗅𝗂𝗇𝗀 📚\n\n🗣 𝖨𝖿 𝖨𝗍 𝗂𝗌 𝖺 𝖥𝗂𝗅𝗆 𝖲𝖾𝗋𝗂𝖾𝗌. 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 𝖮𝗇𝖾 𝖡𝗒 𝖮𝗇𝖾 𝖶𝗂𝗍𝗁 𝖯𝗋𝗈𝗉𝖾𝗋 𝖭𝖺𝗆𝖾 🧠\n\n🖇𝐄𝐱𝐚𝐦𝐩𝐥𝐞:\n\n• Robin Hood ✅\n• Robin Hood 2010✅\n• Kurup 2021 Kan✅ \n• Harry Potter and the Philosophers Stone✅\n• Harry Potter and the Prisoner of Azkaban✅\n\n🥱 𝖥𝗈𝗋 𝖫𝖺𝗇𝗀𝗎𝖺𝗀𝖾 𝖠𝗎𝖽𝗂𝗈𝗌 - 𝖪𝖺𝗇 𝖿𝗈𝗋 𝖪𝖺𝗇𝗇𝖺𝖽𝖺, 𝖬𝖺𝗅 - 𝖬𝖺𝗅𝖺𝗒𝖺𝗅𝖺𝗆, 𝖳𝖺𝗆 - 𝖳𝖺𝗆𝗂𝗅\n\n🔎 𝖴𝗌𝖾 𝖥𝗂𝗋𝗌𝗍 3 𝖫𝖾𝗍𝗍𝖾𝗋𝗌 𝖮𝖿 𝖫𝖺𝗇𝗀𝗎𝖺𝗀𝖾 𝖥𝗈𝗋 𝖠𝗎𝖽𝗂𝗈𝗌 [𝖪𝖺𝗇 𝖳𝖺𝗆 𝖳𝖾𝗅 𝖬𝖺𝗅 𝖧𝗂𝗇 𝖲𝗉𝖺 𝖤𝗇𝗀 𝖪𝗈𝗋 𝖾𝗍𝖼...]\n\n❌ [𝗗𝗼𝗻𝘁 𝗨𝘀𝗲 𝘄𝗼𝗿𝗱𝘀 𝗟𝗶𝗸𝗲 𝗗𝘂𝗯𝗯𝗲𝗱/𝗠𝗼𝘃𝗶𝗲𝘀/𝗦𝗲𝗻𝗱/𝗛𝗗 , . : - 𝗲𝘁𝗰] ❌")
@Client.on_message(filters.command("series", CMD))
async def series(_, message):
await message.reply_text("⚠️❗️ 𝗦𝗲𝗿𝗶𝗲𝘀 𝗥𝗲𝗾𝘂𝗲𝘀𝘁 𝗙𝗼𝗿𝗺𝗮𝘁 ❗️⚠️\n\n🗣 𝖲𝖾𝗋𝗂𝖾𝗌 𝖭𝖺𝗆𝖾,𝖲𝖾𝖺𝗌𝗈𝗇 (𝖶𝗁𝗂𝖼𝗁 𝖲𝖾𝖺𝗌𝗈𝗇 𝗒𝗈𝗎 𝗐𝖺𝗇𝗍) 🧠\n\n🖇𝐄𝐱𝐚𝐦𝐩𝐥𝐞: \n\n• Game Of Thrones S03𝖤02 720𝗉✅\n• Sex Education S02 720p✅ \n• Breaking Bad S01E05✅ \n• Prison Break 1080p✅ \n• Witcher S02✅\n\n🥱 𝖥𝗈𝗋 𝖲𝖾𝖺𝗌𝗈𝗇 𝖬𝖾𝗇𝗍𝗂𝗈𝗇 𝖠𝗌 𝖲01 𝖥𝗈𝗋 𝖲𝖾𝖺𝗌𝗈𝗇 1, 𝖲02 𝖥𝗈𝗋 𝖲𝖾𝖺𝗌𝗈𝗇 2 𝖾𝗍𝖼 [𝖲03,𝖲04 ,𝖲06,𝖲10,𝖲17] 𝖦𝗈𝖾𝗌 𝖫𝗂𝗄𝖾 𝖳𝗁𝖺𝗍\n\n🔎 𝖥𝗈𝗋 𝖤𝗉𝗂𝗌𝗈𝖽𝖾 𝖬𝖾𝗇𝗍𝗂𝗈𝗇 𝖠𝗌 𝖤𝗉01 𝖥𝗈𝗋 𝖤𝗉𝗂𝗌𝗈𝖽𝖾 1, 𝖤𝗉02 𝖥𝗈𝗋 𝖤𝗉𝗂𝗌𝗈𝖽𝖾 2 𝖾𝗍𝖼 [𝖤𝗉03,𝖤𝗉07,𝖤𝗉17,𝖤𝗉21] 𝖦𝗈'𝗌 𝖫𝗂𝗄𝖾 𝖳𝗁𝖺𝗍 \n\n❌ [𝗗𝗼𝗻𝘁 𝗨𝘀𝗲 𝘄𝗼𝗿𝗱𝘀 𝗟𝗶𝗸𝗲 𝗦𝗲𝗮𝘀𝗼𝗻/𝗘𝗽𝗶𝘀𝗼𝗱𝗲/𝗦𝗲𝗿𝗶𝗲𝘀 , . : - 𝗲𝘁𝗰] ❌")
@Client.on_message(filters.command("tutorial", CMD))
async def tutorial(_, message):
await message.reply_text("𝖢𝗁𝖾𝖼𝗄𝗈𝗎𝗍 @piro_tuts 𝖥𝗈𝗋 𝖳𝗎𝗍𝗈𝗋𝗂𝖺𝗅𝗌 😎")
@Client.on_message(filters.command("ping", CMD))
async def ping(_, message):
start_t = time.time()
rm = await message.reply_text("...........")
end_t = time.time()
time_taken_s = (end_t - start_t) * 1000
await rm.edit(f"𝖯𝗂𝗇𝗀!\n{time_taken_s:.3f} ms")
@Client.on_message(filters.command("status"))
async def stats(bot, update):
currentTime = time.strftime("%Hh%Mm%Ss", time.gmtime(time.time() - BOT_START_TIME))
total, used, free = shutil.disk_usage(".")
total = humanbytes(total)
used = humanbytes(used)
free = humanbytes(free)
cpu_usage = psutil.cpu_percent()
ram_usage = psutil.virtual_memory().percent
disk_usage = psutil.disk_usage('/').percent
ms_g = f"""⚙️ 𝖡𝗈𝗍 𝖲𝗍𝖺𝗍𝗎𝗌
🕔 𝖴𝗉𝗍𝗂𝗆𝖾: {currentTime}
🛠 𝖢𝖯𝖴 𝖴𝗌𝖺𝗀𝖾: {cpu_usage}%
🗜 𝖱𝖠𝖬 𝖴𝗌𝖺𝗀𝖾: {ram_usage}%
🗂 𝖳𝗈𝗍𝖺𝗅 𝖣𝗂𝗌𝗄 𝖲𝗉𝖺𝖼𝖾: {total}
🗳 𝖴𝗌𝖾𝖽 𝖲𝗉𝖺𝖼𝖾: {used} ({disk_usage}%)
📝 𝖥𝗋𝖾𝖾 𝖲𝗉𝖺𝖼𝖾: {free} """
msg = await bot.send_message(chat_id=update.chat.id, text="__𝖯𝗋𝗈𝖼𝖾𝗌𝗌𝗂𝗇𝗀...__", parse_mode=enums.ParseMode.MARKDOWN)
await msg.edit_text(text=ms_g, parse_mode=enums.ParseMode.HTML)
@Client.on_message(filters.command("restart") & filters.user(ADMINS))
async def stop_button(bot, message):
msg = await bot.send_message(text="**𝖡𝗈𝗍 𝖨𝗌 𝖱𝖾𝗌𝗍𝖺𝗋𝗍𝗂𝗇𝗀...🪄**", chat_id=message.chat.id)
await asyncio.sleep(3)
await msg.edit("**𝖡𝗈𝗍 𝖱𝖾𝗌𝗍𝖺𝗋𝗍𝖾𝖽 𝖲𝗎𝖼𝖼𝖾𝗌𝗌𝖿𝗎𝗅𝗅𝗒 ! 𝖱𝖾𝖺𝖽𝗒 𝖳𝗈 𝖬𝗈𝗏𝖾 𝖮𝗇 💯**")
os.execl(sys.executable, sys.executable, *sys.argv)
================================================
FILE: plugins/commands.py
================================================
import os
import logging
import random
import asyncio
from Script import script
from pyrogram import Client, filters, enums
from pyrogram.errors import ChatAdminRequired, FloodWait
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.ia_filterdb import Media, get_file_details, unpack_new_file_id, get_bad_files
from database.users_chats_db import db
from info import CHANNELS, ADMINS, AUTH_CHANNEL, LOG_CHANNEL, PICS, BATCH_FILE_CAPTION, CUSTOM_FILE_CAPTION, SUPPORT_CHAT, PROTECT_CONTENT, REQST_CHANNEL, SUPPORT_CHAT_ID, MAX_B_TN
from utils import get_settings, get_size, is_subscribed, save_group_settings, temp
from database.connections_mdb import active_connection
import re
import json
import base64
logger = logging.getLogger(__name__)
BATCH_FILES = {}
@Client.on_message(filters.command("start") & filters.incoming)
async def start(client, message):
if message.chat.type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
buttons = [[
InlineKeyboardButton('➕ 𝖠𝖽𝖽 𝖬𝖾 𝖳𝗈 𝖸𝗈𝗎𝗋 𝖦𝗋𝗈𝗎𝗉 ➕', url=f"http://t.me/{temp.U_NAME}?startgroup=true")
],[
InlineKeyboardButton('🛡 𝖮𝗐𝗇𝖾𝗋', callback_data="owner_info"),
InlineKeyboardButton('🧩 𝖲𝗎𝗉𝗉𝗈𝗋𝗍 𝖦𝗋𝗈𝗎𝗉', url=f"https://t.me/{SUPPORT_CHAT}")
],[
InlineKeyboardButton('ℹ️ 𝖧𝖾𝗅𝗉', callback_data='help'),
InlineKeyboardButton('😊 𝖠𝖻𝗈𝗎𝗍', callback_data='about')
],[
InlineKeyboardButton('🔎 𝖨𝗇𝗅𝗂𝗇𝖾 𝖲𝖾𝖺𝗋𝖼𝗁', switch_inline_query_current_chat='')
]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply(script.START_TXT.format(message.from_user.mention if message.from_user else message.chat.title, temp.U_NAME, temp.B_NAME), reply_markup=reply_markup)
await asyncio.sleep(2)
if not await db.get_chat(message.chat.id):
total=await client.get_chat_members_count(message.chat.id)
await client.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, "Unknown"))
await db.add_chat(message.chat.id, message.chat.title)
return
if not await db.is_user_exist(message.from_user.id):
await db.add_user(message.from_user.id, message.from_user.first_name)
await client.send_message(LOG_CHANNEL, script.LOG_TEXT_P.format(message.from_user.id, message.from_user.mention))
if len(message.command) != 2:
buttons = [[
InlineKeyboardButton('➕ 𝖠𝖽𝖽 𝖬𝖾 𝖳𝗈 𝖸𝗈𝗎𝗋 𝖦𝗋𝗈𝗎𝗉 ➕', url=f"http://t.me/{temp.U_NAME}?startgroup=true")
],[
InlineKeyboardButton('🛡 𝖮𝗐𝗇𝖾𝗋', callback_data="owner_info"),
InlineKeyboardButton('🧩 𝖲𝗎𝗉𝗉𝗈𝗋𝗍 𝖦𝗋𝗈𝗎𝗉', url=f"https://t.me/{SUPPORT_CHAT}")
],[
InlineKeyboardButton('ℹ️ 𝖧𝖾𝗅𝗉', callback_data='help'),
InlineKeyboardButton('😊 𝖠𝖻𝗈𝗎𝗍', callback_data='about'),
],[
InlineKeyboardButton('🔎 𝖨𝗇𝗅𝗂𝗇𝖾 𝖲𝖾𝖺𝗋𝖼𝗁', switch_inline_query_current_chat='')
]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_photo(
photo=random.choice(PICS),
caption=script.START_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
reply_markup=reply_markup,
parse_mode=enums.ParseMode.HTML
)
return
if AUTH_CHANNEL and not await is_subscribed(client, message):
try:
invite_link = await client.create_chat_invite_link(int(AUTH_CHANNEL))
except ChatAdminRequired:
logger.error("Make sure Bot is admin in Forcesub channel")
return
btn = [
[
InlineKeyboardButton(
"🤖 𝖩𝗈𝗂𝗇 𝖴𝗉𝖽𝖺𝗍𝖾𝗌 𝖢𝗁𝖺𝗇𝗇𝖾𝗅 🤖", url=invite_link.invite_link
)
]
]
if message.command[1] != "subscribe" or message.command[1] != "send_all":
try:
kk, file_id = message.command[1].split("_", 1)
pre = 'checksubp' if kk == 'filep' else 'checksub'
btn.append([InlineKeyboardButton("🔄 𝖳𝗋𝗒 𝖠𝗀𝖺𝗂𝗇 🔄", callback_data=f"{pre}#{file_id}")])
except (IndexError, ValueError):
btn.append([InlineKeyboardButton("🔄 𝖳𝗋𝗒 𝖠𝗀𝖺𝗂𝗇 🔄", url=f"https://t.me/{temp.U_NAME}?start={message.command[1]}")])
await client.send_message(
chat_id=message.from_user.id,
text="**Please Join My Updates Channel to use this Bot!**",
reply_markup=InlineKeyboardMarkup(btn),
parse_mode=enums.ParseMode.MARKDOWN
)
return
if len(message.command) == 2 and message.command[1] in ["subscribe", "error", "okay", "help"]:
buttons = [[
InlineKeyboardButton('➕ 𝖠𝖽𝖽 𝖬𝖾 𝖳𝗈 𝖸𝗈𝗎𝗋 𝖦𝗋𝗈𝗎𝗉 ➕', url=f"http://t.me/{temp.U_NAME}?startgroup=true")
],[
InlineKeyboardButton('🛡 𝖮𝗐𝗇𝖾𝗋', callback_data="owner_info"),
InlineKeyboardButton('🧩 𝖲𝗎𝗉𝗉𝗈𝗋𝗍 𝖦𝗋𝗈𝗎𝗉', url=f"https://t.me/{SUPPORT_CHAT}")
],[
InlineKeyboardButton('ℹ️ 𝖧𝖾𝗅𝗉', callback_data='help'),
InlineKeyboardButton('😊 𝖠𝖻𝗈𝗎𝗍', callback_data='about')
],[
InlineKeyboardButton('🔎 𝖨𝗇𝗅𝗂𝗇𝖾 𝖲𝖾𝖺𝗋𝖼𝗁', switch_inline_query_current_chat='')
]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_photo(
photo=random.choice(PICS),
caption=script.START_TXT.format(message.from_user.mention, temp.U_NAME, temp.B_NAME),
reply_markup=reply_markup,
parse_mode=enums.ParseMode.HTML
)
return
data = message.command[1]
try:
pre, file_id = data.split('_', 1)
except:
file_id = data
pre = ""
if data.startswith("all"):
_, key, pre = data.split("_", 2)
files = temp.FILES_IDS.get(key)
if not files:
return await message.reply('No such file exist.')
for file in files:
title = file.file_name
size=get_size(file.file_size)
f_caption=file.caption
if CUSTOM_FILE_CAPTION:
try:
f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
except:
f_caption=f_caption
if f_caption is None:
f_caption = f"{file.file_name}"
await client.send_cached_media(
chat_id=message.from_user.id,
file_id=file.file_id,
caption=f_caption,
protect_content=True if pre == 'filep' else False,
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url=f"https://t.me/piroxbots") ] ] ),
)
return
if data.split("-", 1)[0] == "BATCH":
sts = await message.reply("Please wait...")
file_id = data.split("-", 1)[1]
msgs = BATCH_FILES.get(file_id)
if not msgs:
file = await client.download_media(file_id)
try:
with open(file) as file_data:
msgs=json.loads(file_data.read())
except:
await sts.edit("FAILED")
return await client.send_message(LOG_CHANNEL, "UNABLE TO OPEN FILE.")
os.remove(file)
BATCH_FILES[file_id] = msgs
for msg in msgs:
title = msg.get("title")
size=get_size(int(msg.get("size", 0)))
f_caption=msg.get("caption", "")
if BATCH_FILE_CAPTION:
try:
f_caption=BATCH_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
except Exception as e:
logger.exception(e)
f_caption=f_caption
if f_caption is None:
f_caption = f"{title}"
try:
await client.send_cached_media(
chat_id=message.from_user.id,
file_id=msg.get("file_id"),
caption=f_caption,
protect_content=msg.get('protect', False),
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url=f"https://t.me/piroxbots") ] ] ),
)
except FloodWait as e:
await asyncio.sleep(e.x)
logger.warning(f"Floodwait of {e.x} sec.")
await client.send_cached_media(
chat_id=message.from_user.id,
file_id=msg.get("file_id"),
caption=f_caption,
protect_content=msg.get('protect', False),
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url=f"https://t.me/piroxbots") ] ] ),
)
except Exception as e:
logger.warning(e, exc_info=True)
continue
await asyncio.sleep(1)
await sts.delete()
return
elif data.split("-", 1)[0] == "DSTORE":
sts = await message.reply("Please wait...")
b_string = data.split("-", 1)[1]
decoded = (base64.urlsafe_b64decode(b_string + "=" * (-len(b_string) % 4))).decode("ascii")
try:
f_msg_id, l_msg_id, f_chat_id, protect = decoded.split("_", 3)
except:
f_msg_id, l_msg_id, f_chat_id = decoded.split("_", 2)
protect = "/pbatch" if PROTECT_CONTENT else "batch"
diff = int(l_msg_id) - int(f_msg_id)
async for msg in client.iter_messages(int(f_chat_id), int(l_msg_id), int(f_msg_id)):
if msg.media:
media = getattr(msg, msg.media.value)
if BATCH_FILE_CAPTION:
try:
f_caption=BATCH_FILE_CAPTION.format(file_name=getattr(media, 'file_name', ''), file_size=getattr(media, 'file_size', ''), file_caption=getattr(msg, 'caption', ''))
except Exception as e:
logger.exception(e)
f_caption = getattr(msg, 'caption', '')
else:
media = getattr(msg, msg.media.value)
file_name = getattr(media, 'file_name', '')
f_caption = getattr(msg, 'caption', file_name)
try:
await msg.copy(message.chat.id, caption=f_caption, protect_content=True if protect == "/pbatch" else False)
except FloodWait as e:
await asyncio.sleep(e.x)
await msg.copy(message.chat.id, caption=f_caption, protect_content=True if protect == "/pbatch" else False)
except Exception as e:
logger.exception(e)
continue
elif msg.empty:
continue
else:
try:
await msg.copy(message.chat.id, protect_content=True if protect == "/pbatch" else False)
except FloodWait as e:
await asyncio.sleep(e.x)
await msg.copy(message.chat.id, protect_content=True if protect == "/pbatch" else False)
except Exception as e:
logger.exception(e)
continue
await asyncio.sleep(1)
return await sts.delete()
files_ = await get_file_details(file_id)
if not files_:
pre, file_id = ((base64.urlsafe_b64decode(data + "=" * (-len(data) % 4))).decode("ascii")).split("_", 1)
try:
msg = await client.send_cached_media(
chat_id=message.from_user.id,
file_id=file_id,
protect_content=True if pre == 'filep' else False,
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url="https://t.me/piroxbots") ] ] ),
)
filetype = msg.media
file = getattr(msg, filetype.value)
title = file.file_name
size=get_size(file.file_size)
f_caption = f"{title}"
if CUSTOM_FILE_CAPTION:
try:
f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='')
except:
return
await msg.edit_caption(f_caption)
return
except:
pass
return await message.reply('No such file exist.')
files = files_[0]
title = files.file_name
size=get_size(files.file_size)
f_caption=files.caption
if CUSTOM_FILE_CAPTION:
try:
f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
except Exception as e:
logger.exception(e)
f_caption=f_caption
if f_caption is None:
f_caption = f"{files.file_name}"
await client.send_cached_media(
chat_id=message.from_user.id,
file_id=file_id,
caption=f_caption,
protect_content=True if pre == 'filep' else False,
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url="https://t.me/piroxbots") ] ] ),
)
@Client.on_message(filters.command('channel') & filters.user(ADMINS))
async def channel_info(bot, message):
"""Send basic information of channel"""
if isinstance(CHANNELS, (int, str)):
channels = [CHANNELS]
elif isinstance(CHANNELS, list):
channels = CHANNELS
else:
raise ValueError("Unexpected type of CHANNELS")
text = '📑 **Indexed channels/groups**\n'
for channel in channels:
chat = await bot.get_chat(channel)
if chat.username:
text += '\n@' + chat.username
else:
text += '\n' + chat.title or chat.first_name
text += f'\n\n**Total:** {len(CHANNELS)}'
if len(text) < 4096:
await message.reply(text)
else:
file = 'Indexed channels.txt'
with open(file, 'w') as f:
f.write(text)
await message.reply_document(file)
os.remove(file)
@Client.on_message(filters.command('logs') & filters.user(ADMINS))
async def log_file(bot, message):
"""Send log file"""
try:
await message.reply_document('Logs.txt')
except Exception as e:
await message.reply(str(e))
@Client.on_message(filters.command('delete') & filters.user(ADMINS))
async def delete(bot, message):
"""Delete file from database"""
reply = message.reply_to_message
if reply and reply.media:
msg = await message.reply("Processing...⏳", quote=True)
else:
await message.reply('Reply to file with /delete which you want to delete', quote=True)
return
for file_type in ("document", "video", "audio"):
media = getattr(reply, file_type, None)
if media is not None:
break
else:
await msg.edit('This is not supported file format')
return
file_id, file_ref = unpack_new_file_id(media.file_id)
result = await Media.collection.delete_one({
'_id': file_id,
})
if result.deleted_count:
await msg.edit('File is successfully deleted from database')
else:
file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
result = await Media.collection.delete_many({
'file_name': file_name,
'file_size': media.file_size,
'mime_type': media.mime_type
})
if result.deleted_count:
await msg.edit('File is successfully deleted from database')
else:
result = await Media.collection.delete_many({
'file_name': media.file_name,
'file_size': media.file_size,
'mime_type': media.mime_type
})
if result.deleted_count:
await msg.edit('File is successfully deleted from database')
else:
await msg.edit('File not found in database')
@Client.on_message(filters.command('deleteall') & filters.user(ADMINS))
async def delete_all_index(bot, message):
await message.reply_text(
'This will delete all indexed files.\nDo you want to continue??',
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="YES", callback_data="autofilter_delete"
)
],
[
InlineKeyboardButton(
text="CANCEL", callback_data="close_data"
)
],
]
),
quote=True,
)
@Client.on_callback_query(filters.regex(r'^autofilter_delete'))
async def delete_all_index_confirm(bot, message):
await Media.collection.drop()
await message.answer('Piracy Is Crime')
await message.message.edit('Succesfully Deleted All The Indexed Files.')
@Client.on_message(filters.command('settings'))
async def settings(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
settings = await get_settings(grp_id)
try:
if settings['max_btn']:
settings = await get_settings(grp_id)
except KeyError:
await save_group_settings(grp_id, 'max_btn', False)
settings = await get_settings(grp_id)
if settings is not None:
buttons = [
[
InlineKeyboardButton(
'𝖥𝗂𝗅𝗍𝖾𝗋 𝖡𝗎𝗍𝗍𝗈𝗇',
callback_data=f'setgs#button#{settings["button"]}#{grp_id}',
),
InlineKeyboardButton(
'𝖲𝗂𝗇𝗀𝗅𝖾 𝖡𝗎𝗍𝗍𝗈𝗇' if settings["button"] else '𝖣𝗈𝗎𝖻𝗅𝖾',
callback_data=f'setgs#button#{settings["button"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖥𝗂𝗅𝖾 𝖲𝖾𝗇𝖽 𝖬𝗈𝖽𝖾',
callback_data=f'setgs#botpm#{settings["botpm"]}#{grp_id}',
),
InlineKeyboardButton(
'𝖬𝖺𝗇𝗎𝖺𝗅 𝖲𝗍𝖺𝗋𝗍' if settings["botpm"] else '𝖠𝗎𝗍𝗈 𝖲𝖾𝗇𝖽',
callback_data=f'setgs#botpm#{settings["botpm"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖯𝗋𝗈𝗍𝖾𝖼𝗍 𝖢𝗈𝗇𝗍𝖾𝗇𝗍',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{grp_id}',
),
InlineKeyboardButton(
'✅ 𝖮𝗇' if settings["file_secure"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖨𝖬𝖣𝖻',
callback_data=f'setgs#imdb#{settings["imdb"]}#{grp_id}',
),
InlineKeyboardButton(
'✅ 𝖮𝗇' if settings["imdb"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#imdb#{settings["imdb"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖲𝗉𝖾𝗅𝗅 𝖢𝗁𝖾𝖼𝗄',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{grp_id}',
),
InlineKeyboardButton(
'✅ 𝖮𝗇' if settings["spell_check"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖶𝖾𝗅𝖼𝗈𝗆𝖾 𝖬𝖾𝗌𝗌𝖺𝗀𝖾',
callback_data=f'setgs#welcome#{settings["welcome"]}#{grp_id}',
),
InlineKeyboardButton(
'✅ 𝖮𝗇' if settings["welcome"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#welcome#{settings["welcome"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖠𝗎𝗍𝗈 𝖣𝖾𝗅𝖾𝗍𝖾',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{grp_id}',
),
InlineKeyboardButton(
'5 𝖬𝗂𝗇' if settings["auto_delete"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖠𝗎𝗍𝗈-𝖥𝗂𝗅𝗍𝖾𝗋',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{grp_id}',
),
InlineKeyboardButton(
'✅ 𝖮𝗇' if settings["auto_ffilter"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{grp_id}',
),
],
[
InlineKeyboardButton(
'𝖬𝖺𝗑 𝖡𝗎𝗍𝗍𝗈𝗇𝗌',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{grp_id}',
),
InlineKeyboardButton(
'10' if settings["max_btn"] else f'{MAX_B_TN}',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{grp_id}',
),
],
]
btn = [[
InlineKeyboardButton("⬇ 𝖮𝗉𝖾𝗇 𝖧𝖾𝗋𝖾 ⬇", callback_data=f"opnsetgrp#{grp_id}"),
InlineKeyboardButton("➡ 𝖮𝗉𝖾𝗇 𝗂𝗇 𝖯𝖬 ➡", callback_data=f"opnsetpm#{grp_id}")
]]
reply_markup = InlineKeyboardMarkup(buttons)
if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
await message.reply_text(
text="𝖣𝗈 𝖸𝗈𝗎 𝖶𝖺𝗇𝗍 𝖳𝗈 𝖮𝗉𝖾𝗇 𝖲𝖾𝗍𝗍𝗂𝗇𝗀𝗌 𝖧𝖾𝗋𝖾 ?",
reply_markup=InlineKeyboardMarkup(btn),
disable_web_page_preview=True,
parse_mode=enums.ParseMode.HTML,
reply_to_message_id=message.id
)
else:
await message.reply_text(
text=f"𝖢𝗁𝖺𝗇𝗀𝖾 𝖸𝗈𝗎𝗋 𝖲𝖾𝗍𝗍𝗂𝗇𝗀𝗌 𝖥𝗈𝗋 {title} 𝖠𝗌 𝖸𝗈𝗎𝗋 𝖶𝗂𝗌𝗁",
reply_markup=reply_markup,
disable_web_page_preview=True,
parse_mode=enums.ParseMode.HTML,
reply_to_message_id=message.id
)
@Client.on_message(filters.command("send") & filters.user(ADMINS))
async def send_msg(bot, message):
if message.reply_to_message:
target_id = message.text
command = ["/send"]
out = "Users Saved In DB Are:\n\n"
for cmd in command:
if cmd in target_id:
target_id = target_id.replace(cmd, "")
success = False
try:
user = await bot.get_users(target_id)
users = await db.get_all_users()
async for usr in users:
out += f"{usr['id']}"
out += '\n'
if str(user.id) in str(out):
await message.reply_to_message.copy(int(user.id))
success = True
else:
success = False
if success:
await message.reply_text(f"Your message has been successfully send to {user.mention}.")
else:
await message.reply_text("This user didn't started this bot yet !")
except Exception as e:
await message.reply_text(f"Error: {e}")
else:
await message.reply_text("Use this command as a reply to any message using the target chat id. For eg: /send userid")
@Client.on_message(filters.command('set_template'))
async def save_template(client, message):
sts = await message.reply("Checking template")
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
if len(message.command) < 2:
return await sts.edit("No Input!!")
template = message.text.split(" ", 1)[1]
await save_group_settings(grp_id, 'template', template)
await sts.edit(f"Successfully changed template for {title} to\n\n{template}")
@Client.on_message((filters.command(["request", "Request"]) | filters.regex("#request") | filters.regex("#Request")) & filters.group)
async def requests(bot, message):
if REQST_CHANNEL is None or SUPPORT_CHAT_ID is None: return # Must add REQST_CHANNEL and SUPPORT_CHAT_ID to use this feature
if message.reply_to_message and SUPPORT_CHAT_ID == message.chat.id:
chat_id = message.chat.id
reporter = str(message.from_user.id)
mention = message.from_user.mention
success = True
content = message.reply_to_message.text
try:
if REQST_CHANNEL is not None:
btn = [[
InlineKeyboardButton('📥 𝖵𝗂𝖾𝗐 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 📥', url=f"{message.reply_to_message.link}"),
InlineKeyboardButton('📝 𝖲𝗁𝗈𝗐 𝖮𝗉𝗍𝗂𝗈𝗇𝗌 📝', callback_data=f'show_option#{reporter}')
]]
reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
success = True
elif len(content) >= 3:
for admin in ADMINS:
btn = [[
InlineKeyboardButton('📥 𝖵𝗂𝖾𝗐 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 📥', url=f"{message.reply_to_message.link}"),
InlineKeyboardButton('📝 𝖲𝗁𝗈𝗐 𝖮𝗉𝗍𝗂𝗈𝗇𝗌 📝', callback_data=f'show_option#{reporter}')
]]
reported_post = await bot.send_message(chat_id=admin, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
success = True
else:
if len(content) < 3:
await message.reply_text("You must type about your request [Minimum 3 Characters]. Requests can't be empty.")
if len(content) < 3:
success = False
except Exception as e:
await message.reply_text(f"Error: {e}")
pass
elif SUPPORT_CHAT_ID == message.chat.id:
chat_id = message.chat.id
reporter = str(message.from_user.id)
mention = message.from_user.mention
success = True
content = message.text
keywords = ["#request", "/request", "#Request", "/Request"]
for keyword in keywords:
if keyword in content:
content = content.replace(keyword, "")
try:
if REQST_CHANNEL is not None and len(content) >= 3:
btn = [[
InlineKeyboardButton('📥 𝖵𝗂𝖾𝗐 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 📥', url=f"{message.link}"),
InlineKeyboardButton('📝 𝖲𝗁𝗈𝗐 𝖮𝗉𝗍𝗂𝗈𝗇𝗌 📝', callback_data=f'show_option#{reporter}')
]]
reported_post = await bot.send_message(chat_id=REQST_CHANNEL, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
success = True
elif len(content) >= 3:
for admin in ADMINS:
btn = [[
InlineKeyboardButton('📥 𝖵𝗂𝖾𝗐 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 📥', url=f"{message.link}"),
InlineKeyboardButton('📝 𝖲𝗁𝗈𝗐 𝖮𝗉𝗍𝗂𝗈𝗇𝗌 📝', callback_data=f'show_option#{reporter}')
]]
reported_post = await bot.send_message(chat_id=admin, text=f"𝖱𝖾𝗉𝗈𝗋𝗍𝖾𝗋 : {mention} ({reporter})\n\n𝖬𝖾𝗌𝗌𝖺𝗀𝖾 : {content}", reply_markup=InlineKeyboardMarkup(btn))
success = True
else:
if len(content) < 3:
await message.reply_text("You must type about your request [Minimum 3 Characters]. Requests can't be empty.")
if len(content) < 3:
success = False
except Exception as e:
await message.reply_text(f"Error: {e}")
pass
else:
success = False
if success:
btn = [[
InlineKeyboardButton('📥 𝖵𝗂𝖾𝗐 𝖱𝖾𝗊𝗎𝖾𝗌𝗍 📥', url=f"{reported_post.link}")
]]
await message.reply_text("Your request has been added! Please wait for some time.", reply_markup=InlineKeyboardMarkup(btn))
@Client.on_message(filters.command("usend") & filters.user(ADMINS))
async def send_msg(bot, message):
if message.reply_to_message:
target_id = message.text.split(" ", 1)[1]
out = "Users Saved In DB Are:\n\n"
success = False
try:
user = await bot.get_users(target_id)
users = await db.get_all_users()
async for usr in users:
out += f"{usr['id']}"
out += '\n'
if str(user.id) in str(out):
await message.reply_to_message.copy(int(user.id))
success = True
else:
success = False
if success:
await message.reply_text(f"𝖸𝗈𝗎𝗋 𝖬𝖾𝗌𝗌𝖺𝗀𝖾 𝖧𝖺𝗌 𝖲𝗎𝖼𝖼𝖾𝗌𝗌𝖿𝗎𝗅𝗅𝗒 𝖲𝖾𝗇𝗍 𝖳𝗈 {user.mention}.")
else:
await message.reply_text("An Error Occured !")
except Exception as e:
await message.reply_text(f"Error :- {e}")
else:
await message.reply_text("Error𝖢𝗈𝗆𝗆𝖺𝗇𝖽 𝖨𝗇𝖼𝗈𝗆𝗉𝗅𝖾𝗍𝖾 !")
@Client.on_message(filters.command("send") & filters.user(ADMINS))
async def send_msg(bot, message):
if message.reply_to_message:
target_id = message.text.split(" ", 1)[1]
out = "Users Saved In DB Are:\n\n"
success = False
try:
user = await bot.get_users(target_id)
users = await db.get_all_users()
async for usr in users:
out += f"{usr['id']}"
out += '\n'
if str(user.id) in str(out):
await message.reply_to_message.copy(int(user.id))
success = True
else:
success = False
if success:
await message.reply_text(f"Your message has been successfully send to {user.mention}.")
else:
await message.reply_text("This user didn't started this bot yet !")
except Exception as e:
await message.reply_text(f"Error: {e}")
else:
await message.reply_text("Use this command as a reply to any message using the target chat id. For eg: /send userid")
@Client.on_message(filters.command("gsend") & filters.user(ADMINS))
async def send_chatmsg(bot, message):
if message.reply_to_message:
target_id = message.text.split(" ", 1)[1]
out = "Chats Saved In DB Are:\n\n"
success = False
try:
chat = await bot.get_chat(target_id)
chats = await db.get_all_chats()
async for cht in chats:
out += f"{cht['id']}"
out += '\n'
if str(chat.id) in str(out):
await message.reply_to_message.copy(int(chat.id))
success = True
else:
success = False
if success:
await message.reply_text(f"Your message has been successfully send to {chat.id}.")
else:
await message.reply_text("An Error Occured !")
except Exception as e:
await message.reply_text(f"Error :- {e}")
else:
await message.reply_text("Error𝖢𝗈𝗆𝗆𝖺𝗇𝖽 𝖨𝗇𝖼𝗈𝗆𝗉𝗅𝖾𝗍𝖾 !")
@Client.on_message(filters.command("deletefiles") & filters.user(ADMINS))
async def deletemultiplefiles(bot, message):
chat_type = message.chat.type
if chat_type != enums.ChatType.PRIVATE:
return await message.reply_text(f"Hey {message.from_user.mention}, This command won't work in groups. It only works on my PM !")
else:
pass
try:
keyword = message.text.split(" ", 1)[1]
except:
return await message.reply_text(f"Hey {message.from_user.mention}, Give me a keyword along with the command to delete files.")
k = await bot.send_message(chat_id=message.chat.id, text=f"Fetching Files for your query {keyword} on DB... Please wait...")
files, total = await get_bad_files(keyword)
await k.edit_text(f"Found {total} files for your query {keyword} !\n\nFile deletion process will start in 5 seconds !")
await asyncio.sleep(5)
deleted = 0
for file in files:
await k.edit_text(f"Process started for deleting files from DB. Successfully deleted {str(deleted)} files from DB for your query {keyword} !\n\nPlease wait...")
file_ids = file.file_id
file_name = file.file_name
result = await Media.collection.delete_one({
'_id': file_ids,
})
if result.deleted_count:
logger.info(f'File Found for your query {keyword}! Successfully deleted {file_name} from database.')
deleted += 1
await k.edit_text(text=f"Process Completed for file deletion !\n\nSuccessfully deleted {str(deleted)} files from database for your query {keyword}.")
================================================
FILE: plugins/connection.py
================================================
from pyrogram import filters, Client, enums
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.connections_mdb import add_connection, all_connections, if_active, delete_connection
from info import ADMINS
from utils import temp
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
@Client.on_message((filters.private | filters.group) & filters.command('connect'))
async def addconnection(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
try:
cmd, group_id = message.text.split(" ", 1)
except:
await message.reply_text(
"Enter in correct format!\n\n"
"/connect groupid\n\n"
"Get your Group id by adding this bot to your group and use /id",
quote=True
)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
group_id = message.chat.id
try:
st = await client.get_chat_member(group_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and userid not in ADMINS
):
await message.reply_text("You should be an admin in Given group!", quote=True)
return
except Exception as e:
logger.exception(e)
await message.reply_text(
"Invalid Group ID!\n\nIf correct, Make sure I'm present in your group!!",
quote=True,
)
return
try:
st = await client.get_chat_member(group_id, "me")
if st.status == enums.ChatMemberStatus.ADMINISTRATOR:
ttl = await client.get_chat(group_id)
title = ttl.title
addcon = await add_connection(str(group_id), str(userid))
if addcon:
await message.reply_text(
f"Successfully connected to **{title}**\nNow manage your group from my pm !",
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
if chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
await client.send_message(
userid,
f"Connected to **{title}** !",
parse_mode=enums.ParseMode.MARKDOWN
)
else:
await message.reply_text(
"You're already connected to this chat!",
quote=True
)
else:
await message.reply_text("Add me as an admin in group", quote=True)
except Exception as e:
logger.exception(e)
await message.reply_text('Some error occurred! Try again later.', quote=True)
return
@Client.on_message((filters.private | filters.group) & filters.command('disconnect'))
async def deleteconnection(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
await message.reply_text("Run /connections to view or disconnect from groups!", quote=True)
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
group_id = message.chat.id
st = await client.get_chat_member(group_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
delcon = await delete_connection(str(userid), str(group_id))
if delcon:
await message.reply_text("Successfully disconnected from this chat", quote=True)
else:
await message.reply_text("This chat isn't connected to me!\nDo /connect to connect.", quote=True)
@Client.on_message(filters.private & filters.command(["connections"]))
async def connections(client, message):
userid = message.from_user.id
groupids = await all_connections(str(userid))
if groupids is None:
await message.reply_text(
"There are no active connections!! Connect to some groups first.",
quote=True
)
return
buttons = []
for groupid in groupids:
try:
ttl = await client.get_chat(int(groupid))
title = ttl.title
active = await if_active(str(userid), str(groupid))
act = " - ACTIVE" if active else ""
buttons.append(
[
InlineKeyboardButton(
text=f"{title}{act}", callback_data=f"groupcb:{groupid}:{act}"
)
]
)
except:
pass
if buttons:
await message.reply_text(
"Your connected group details ;\n\n",
reply_markup=InlineKeyboardMarkup(buttons),
quote=True
)
else:
await message.reply_text(
"There are no active connections!! Connect to some groups first.",
quote=True
)
================================================
FILE: plugins/delete_files.py
================================================
import re
import logging
from pyrogram import Client, filters
from info import DELETE_CHANNELS
from database.ia_filterdb import Media, unpack_new_file_id
logger = logging.getLogger(__name__)
media_filter = filters.document | filters.video | filters.audio
@Client.on_message(filters.chat(DELETE_CHANNELS) & media_filter)
async def deletemultiplemedia(bot, message):
"""Delete Multiple files from database"""
for file_type in ("document", "video", "audio"):
media = getattr(message, file_type, None)
if media is not None:
break
else:
return
file_id, file_ref = unpack_new_file_id(media.file_id)
result = await Media.collection.delete_one({
'_id': file_id,
})
if result.deleted_count:
logger.info('File is successfully deleted from database.')
else:
file_name = re.sub(r"(_|\-|\.|\+)", " ", str(media.file_name))
result = await Media.collection.delete_many({
'file_name': file_name,
'file_size': media.file_size,
'mime_type': media.mime_type
})
if result.deleted_count:
logger.info('File is successfully deleted from database.')
else:
result = await Media.collection.delete_many({
'file_name': media.file_name,
'file_size': media.file_size,
'mime_type': media.mime_type
})
if result.deleted_count:
logger.info('File is successfully deleted from database.')
else:
logger.info('File not found in database.')
================================================
FILE: plugins/filters.py
================================================
import io
from pyrogram import filters, Client, enums
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.filters_mdb import(
add_filter,
get_filters,
delete_filter,
count_filters
)
from database.connections_mdb import active_connection
from utils import get_file_id, parser, split_quotes
from info import ADMINS
@Client.on_message(filters.command(['filter', 'addf']) & filters.incoming)
async def addfilter(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
args = message.text.html.split(None, 1)
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
if len(args) < 2:
await message.reply_text("Command Incomplete :(", quote=True)
return
extracted = split_quotes(args[1])
text = extracted[0].lower()
if not message.reply_to_message and len(extracted) < 2:
await message.reply_text("Add some content to save your filter!", quote=True)
return
if (len(extracted) >= 2) and not message.reply_to_message:
reply_text, btn, alert = parser(extracted[1], text)
fileid = None
if not reply_text:
await message.reply_text("You cannot have buttons alone, give some text to go with it!", quote=True)
return
elif message.reply_to_message and message.reply_to_message.reply_markup:
try:
rm = message.reply_to_message.reply_markup
btn = rm.inline_keyboard
msg = get_file_id(message.reply_to_message)
if msg:
fileid = msg.file_id
reply_text = message.reply_to_message.caption.html
else:
reply_text = message.reply_to_message.text.html
fileid = None
alert = None
except:
reply_text = ""
btn = "[]"
fileid = None
alert = None
elif message.reply_to_message and message.reply_to_message.media:
try:
msg = get_file_id(message.reply_to_message)
fileid = msg.file_id if msg else None
reply_text, btn, alert = parser(extracted[1], text) if message.reply_to_message.sticker else parser(message.reply_to_message.caption.html, text)
except:
reply_text = ""
btn = "[]"
alert = None
elif message.reply_to_message and message.reply_to_message.text:
try:
fileid = None
reply_text, btn, alert = parser(message.reply_to_message.text.html, text)
except:
reply_text = ""
btn = "[]"
alert = None
else:
return
await add_filter(grp_id, text, reply_text, btn, fileid, alert)
await message.reply_text(
f"Filter for `{text}` added in **{title}**",
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
@Client.on_message(filters.command(['viewfilters', 'filters']) & filters.incoming)
async def get_all(client, message):
chat_type = message.chat.type
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
if chat_type == enums.ChatType.PRIVATE:
userid = message.from_user.id
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
texts = await get_filters(grp_id)
count = await count_filters(grp_id)
if count:
filterlist = f"Total number of filters in **{title}** : {count}\n\n"
for text in texts:
keywords = " × `{}`\n".format(text)
filterlist += keywords
if len(filterlist) > 4096:
with io.BytesIO(str.encode(filterlist.replace("`", ""))) as keyword_file:
keyword_file.name = "keywords.txt"
await message.reply_document(
document=keyword_file,
quote=True
)
return
else:
filterlist = f"There are no active filters in **{title}**"
await message.reply_text(
text=filterlist,
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
@Client.on_message(filters.command('del') & filters.incoming)
async def deletefilter(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
return
try:
cmd, text = message.text.split(" ", 1)
except:
await message.reply_text(
"Mention the filtername which you wanna delete!\n\n"
"/del filtername\n\n"
"Use /viewfilters to view all available filters",
quote=True
)
return
query = text.lower()
await delete_filter(message, query, grp_id)
@Client.on_message(filters.command('delall') & filters.incoming)
async def delallconfirm(client, message):
userid = message.from_user.id if message.from_user else None
if not userid:
return await message.reply(f"You are anonymous admin. Use /connect {message.chat.id} in PM")
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await message.reply_text("Make sure I'm present in your group!!", quote=True)
return
else:
await message.reply_text("I'm not connected to any groups!", quote=True)
return
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = message.chat.id
title = message.chat.title
else:
return
st = await client.get_chat_member(grp_id, userid)
if (st.status == enums.ChatMemberStatus.OWNER) or (str(userid) in ADMINS):
await message.reply_text(
f"This will delete all filters from '{title}'.\nDo you want to continue??",
reply_markup=InlineKeyboardMarkup([
[InlineKeyboardButton(text="YES",callback_data="delallconfirm")],
[InlineKeyboardButton(text="CANCEL",callback_data="delallcancel")]
]),
quote=True
)
================================================
FILE: plugins/genlink.py
================================================
import re
from pyrogram import filters, Client, enums
from pyrogram.errors.exceptions.bad_request_400 import ChannelInvalid, UsernameInvalid, UsernameNotModified
from info import ADMINS, LOG_CHANNEL, FILE_STORE_CHANNEL, PUBLIC_FILE_STORE
from database.ia_filterdb import unpack_new_file_id
from utils import temp
import re
import os
import json
import base64
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
async def allowed(_, __, message):
if PUBLIC_FILE_STORE:
return True
if message.from_user and message.from_user.id in ADMINS:
return True
return False
@Client.on_message(filters.command(['link', 'plink']) & filters.create(allowed))
async def gen_link_s(bot, message):
replied = message.reply_to_message
if not replied:
return await message.reply('Reply to a message to get a shareable link.')
file_type = replied.media
if file_type not in [enums.MessageMediaType.VIDEO, enums.MessageMediaType.AUDIO, enums.MessageMediaType.DOCUMENT]:
return await message.reply("Reply to a supported media")
if message.has_protected_content and message.chat.id not in ADMINS:
return await message.reply("okDa")
file_id, ref = unpack_new_file_id((getattr(replied, file_type.value)).file_id)
string = 'filep_' if message.text.lower().strip() == "/plink" else 'file_'
string += file_id
outstr = base64.urlsafe_b64encode(string.encode("ascii")).decode().strip("=")
await message.reply(f"Here is your Link:\nhttps://t.me/{temp.U_NAME}?start={outstr}")
@Client.on_message(filters.command(['batch', 'pbatch']) & filters.create(allowed))
async def gen_link_batch(bot, message):
if " " not in message.text:
return await message.reply("Use correct format.\nExample /batch https://t.me/piroxbots/10 https://t.me/piroxbots/20.")
links = message.text.strip().split(" ")
if len(links) != 3:
return await message.reply("Use correct format.\nExample /batch https://t.me/piroxbots/10 https://t.me/piroxbots/20.")
cmd, first, last = links
regex = re.compile("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")
match = regex.match(first)
if not match:
return await message.reply('Invalid link')
f_chat_id = match.group(4)
f_msg_id = int(match.group(5))
if f_chat_id.isnumeric():
f_chat_id = int(("-100" + f_chat_id))
match = regex.match(last)
if not match:
return await message.reply('Invalid link')
l_chat_id = match.group(4)
l_msg_id = int(match.group(5))
if l_chat_id.isnumeric():
l_chat_id = int(("-100" + l_chat_id))
if f_chat_id != l_chat_id:
return await message.reply("Chat ids not matched.")
try:
chat_id = (await bot.get_chat(f_chat_id)).id
except ChannelInvalid:
return await message.reply('This may be a private channel / group. Make me an admin over there to index the files.')
except (UsernameInvalid, UsernameNotModified):
return await message.reply('Invalid Link specified.')
except Exception as e:
return await message.reply(f'Errors - {e}')
sts = await message.reply("Generating link for your message.\nThis may take time depending upon number of messages")
if chat_id in FILE_STORE_CHANNEL:
string = f"{f_msg_id}_{l_msg_id}_{chat_id}_{cmd.lower().strip()}"
b_64 = base64.urlsafe_b64encode(string.encode("ascii")).decode().strip("=")
return await sts.edit(f"Here is your link https://t.me/{temp.U_NAME}?start=DSTORE-{b_64}")
FRMT = "Generating Link...\nTotal Messages: `{total}`\nDone: `{current}`\nRemaining: `{rem}`\nStatus: `{sts}`"
outlist = []
# file store without db channel
og_msg = 0
tot = 0
async for msg in bot.iter_messages(f_chat_id, l_msg_id, f_msg_id):
tot += 1
if msg.empty or msg.service:
continue
if not msg.media:
# only media messages supported.
continue
try:
file_type = msg.media
file = getattr(msg, file_type.value)
caption = getattr(msg, 'caption', '')
if caption:
caption = caption.html
if file:
file = {
"file_id": file.file_id,
"caption": caption,
"title": getattr(file, "file_name", ""),
"size": file.file_size,
"protect": cmd.lower().strip() == "/pbatch",
}
og_msg +=1
outlist.append(file)
except:
pass
if not og_msg % 20:
try:
await sts.edit(FRMT.format(total=l_msg_id-f_msg_id, current=tot, rem=((l_msg_id-f_msg_id) - tot), sts="Saving Messages"))
except:
pass
with open(f"batchmode_{message.from_user.id}.json", "w+") as out:
json.dump(outlist, out)
post = await bot.send_document(LOG_CHANNEL, f"batchmode_{message.from_user.id}.json", file_name="Batch.json", caption="⚠️Generated for filestore.")
os.remove(f"batchmode_{message.from_user.id}.json")
file_id, ref = unpack_new_file_id(post.document.file_id)
await sts.edit(f"Here is your link\nContains `{og_msg}` files.\n https://t.me/{temp.U_NAME}?start=BATCH-{file_id}")
================================================
FILE: plugins/gfilters.py
================================================
import io
from pyrogram import filters, Client, enums
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.gfilters_mdb import(
add_gfilter,
get_gfilters,
delete_gfilter,
count_gfilters
)
from database.connections_mdb import active_connection
from utils import get_file_id, gfilterparser, split_quotes
from info import ADMINS
@Client.on_message(filters.command(['gfilter', 'addg']) & filters.incoming & filters.user(ADMINS))
async def addgfilter(client, message):
args = message.text.html.split(None, 1)
if len(args) < 2:
await message.reply_text("Command Incomplete :(", quote=True)
return
extracted = split_quotes(args[1])
text = extracted[0].lower()
if not message.reply_to_message and len(extracted) < 2:
await message.reply_text("Add some content to save your filter!", quote=True)
return
if (len(extracted) >= 2) and not message.reply_to_message:
reply_text, btn, alert = gfilterparser(extracted[1], text)
fileid = None
if not reply_text:
await message.reply_text("You cannot have buttons alone, give some text to go with it!", quote=True)
return
elif message.reply_to_message and message.reply_to_message.reply_markup:
try:
rm = message.reply_to_message.reply_markup
btn = rm.inline_keyboard
msg = get_file_id(message.reply_to_message)
if msg:
fileid = msg.file_id
reply_text = message.reply_to_message.caption.html
else:
reply_text = message.reply_to_message.text.html
fileid = None
alert = None
except:
reply_text = ""
btn = "[]"
fileid = None
alert = None
elif message.reply_to_message and message.reply_to_message.media:
try:
msg = get_file_id(message.reply_to_message)
fileid = msg.file_id if msg else None
reply_text, btn, alert = gfilterparser(extracted[1], text) if message.reply_to_message.sticker else gfilterparser(message.reply_to_message.caption.html, text)
except:
reply_text = ""
btn = "[]"
alert = None
elif message.reply_to_message and message.reply_to_message.text:
try:
fileid = None
reply_text, btn, alert = gfilterparser(message.reply_to_message.text.html, text)
except:
reply_text = ""
btn = "[]"
alert = None
else:
return
await add_gfilter('gfilters', text, reply_text, btn, fileid, alert)
await message.reply_text(
f"GFilter for `{text}` added",
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
@Client.on_message(filters.command(['viewgfilters', 'gfilters']) & filters.incoming & filters.user(ADMINS))
async def get_all_gfilters(client, message):
texts = await get_gfilters('gfilters')
count = await count_gfilters('gfilters')
if count:
gfilterlist = f"Total number of gfilters : {count}\n\n"
for text in texts:
keywords = " × `{}`\n".format(text)
gfilterlist += keywords
if len(gfilterlist) > 4096:
with io.BytesIO(str.encode(gfilterlist.replace("`", ""))) as keyword_file:
keyword_file.name = "keywords.txt"
await message.reply_document(
document=keyword_file,
quote=True
)
return
else:
gfilterlist = f"There are no active gfilters."
await message.reply_text(
text=gfilterlist,
quote=True,
parse_mode=enums.ParseMode.MARKDOWN
)
@Client.on_message(filters.command('delg') & filters.incoming & filters.user(ADMINS))
async def deletegfilter(client, message):
try:
cmd, text = message.text.split(" ", 1)
except:
await message.reply_text(
"Mention the gfiltername which you wanna delete!\n\n"
"/delg gfiltername\n\n"
"Use /viewgfilters to view all available gfilters",
quote=True
)
return
query = text.lower()
await delete_gfilter(message, query, 'gfilters')
@Client.on_message(filters.command('delallg') & filters.user(ADMINS))
async def delallgfilters(client, message):
await message.reply_text(
f"Do you want to continue??",
reply_markup=InlineKeyboardMarkup([
[InlineKeyboardButton(text="YES",callback_data="gfiltersdeleteallconfirm")],
[InlineKeyboardButton(text="CANCEL",callback_data="gfiltersdeleteallcancel")]
]),
quote=True
)
================================================
FILE: plugins/index.py
================================================
import logging
import asyncio
from pyrogram import Client, filters, enums
from pyrogram.errors import FloodWait
from pyrogram.errors.exceptions.bad_request_400 import ChannelInvalid, ChatAdminRequired, UsernameInvalid, UsernameNotModified
from info import ADMINS
from info import INDEX_REQ_CHANNEL as LOG_CHANNEL
from database.ia_filterdb import save_file
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from utils import temp
import re
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
lock = asyncio.Lock()
@Client.on_callback_query(filters.regex(r'^index'))
async def index_files(bot, query):
if query.data.startswith('index_cancel'):
temp.CANCEL = True
return await query.answer("Cancelling Indexing")
_, raju, chat, lst_msg_id, from_user = query.data.split("#")
if raju == 'reject':
await query.message.delete()
await bot.send_message(int(from_user),
f'Your Submission for indexing {chat} has been decliened by our moderators.',
reply_to_message_id=int(lst_msg_id))
return
if lock.locked():
return await query.answer('Wait until previous process complete.', show_alert=True)
msg = query.message
await query.answer('Processing...⏳', show_alert=True)
if int(from_user) not in ADMINS:
await bot.send_message(int(from_user),
f'Your Submission for indexing {chat} has been accepted by our moderators and will be added soon.',
reply_to_message_id=int(lst_msg_id))
await msg.edit(
"Starting Indexing",
reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton('Cancel', callback_data='index_cancel')]]
)
)
try:
chat = int(chat)
except:
chat = chat
await index_files_to_db(int(lst_msg_id), chat, msg, bot)
@Client.on_message((filters.forwarded | (filters.regex("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")) & filters.text ) & filters.private & filters.incoming)
async def send_for_index(bot, message):
if message.text:
regex = re.compile("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")
match = regex.match(message.text)
if not match:
return await message.reply('Invalid link')
chat_id = match.group(4)
last_msg_id = int(match.group(5))
if chat_id.isnumeric():
chat_id = int(("-100" + chat_id))
elif message.forward_from_chat.type == enums.ChatType.CHANNEL:
last_msg_id = message.forward_from_message_id
chat_id = message.forward_from_chat.username or message.forward_from_chat.id
else:
return
try:
await bot.get_chat(chat_id)
except ChannelInvalid:
return await message.reply('This may be a private channel / group. Make me an admin over there to index the files.')
except (UsernameInvalid, UsernameNotModified):
return await message.reply('Invalid Link specified.')
except Exception as e:
logger.exception(e)
return await message.reply(f'Errors - {e}')
try:
k = await bot.get_messages(chat_id, last_msg_id)
except:
return await message.reply('Make Sure That Iam An Admin In The Channel, if channel is private')
if k.empty:
return await message.reply('This may be group and iam not a admin of the group.')
if message.from_user.id in ADMINS:
buttons = [
[
InlineKeyboardButton('Yes',
callback_data=f'index#accept#{chat_id}#{last_msg_id}#{message.from_user.id}')
],
[
InlineKeyboardButton('close', callback_data='close_data'),
]
]
reply_markup = InlineKeyboardMarkup(buttons)
return await message.reply(
f'Do you Want To Index This Channel/ Group ?\n\nChat ID/ Username: {chat_id}\nLast Message ID: {last_msg_id}',
reply_markup=reply_markup)
if type(chat_id) is int:
try:
link = (await bot.create_chat_invite_link(chat_id)).invite_link
except ChatAdminRequired:
return await message.reply('Make sure iam an admin in the chat and have permission to invite users.')
else:
link = f"@{message.forward_from_chat.username}"
buttons = [
[
InlineKeyboardButton('Accept Index',
callback_data=f'index#accept#{chat_id}#{last_msg_id}#{message.from_user.id}')
],
[
InlineKeyboardButton('Reject Index',
callback_data=f'index#reject#{chat_id}#{message.id}#{message.from_user.id}'),
]
]
reply_markup = InlineKeyboardMarkup(buttons)
await bot.send_message(LOG_CHANNEL,
f'#IndexRequest\n\nBy : {message.from_user.mention} ({message.from_user.id})\nChat ID/ Username - {chat_id}\nLast Message ID - {last_msg_id}\nInviteLink - {link}',
reply_markup=reply_markup)
await message.reply('ThankYou For the Contribution, Wait For My Moderators to verify the files.')
@Client.on_message(filters.command('setskip') & filters.user(ADMINS))
async def set_skip_number(bot, message):
if ' ' in message.text:
_, skip = message.text.split(" ")
try:
skip = int(skip)
except:
return await message.reply("Skip number should be an integer.")
await message.reply(f"Successfully set SKIP number as {skip}")
temp.CURRENT = int(skip)
else:
await message.reply("Give me a skip number")
async def index_files_to_db(lst_msg_id, chat, msg, bot):
total_files = 0
duplicate = 0
errors = 0
deleted = 0
no_media = 0
unsupported = 0
async with lock:
try:
current = temp.CURRENT
temp.CANCEL = False
async for message in bot.iter_messages(chat, lst_msg_id, temp.CURRENT):
if temp.CANCEL:
await msg.edit(f"Successfully Cancelled!!\n\nSaved {total_files} files to dataBase!\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}")
break
current += 1
if current % 20 == 0:
can = [[InlineKeyboardButton('Cancel', callback_data='index_cancel')]]
reply = InlineKeyboardMarkup(can)
await asyncio.sleep(2)
await msg.edit_text(
text=f"Total messages fetched: {current}\nTotal messages saved: {total_files}\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}",
reply_markup=reply)
if message.empty:
deleted += 1
continue
elif not message.media:
no_media += 1
continue
elif message.media not in [enums.MessageMediaType.VIDEO, enums.MessageMediaType.AUDIO, enums.MessageMediaType.DOCUMENT]:
unsupported += 1
continue
media = getattr(message, message.media.value, None)
if not media:
unsupported += 1
continue
media.file_type = message.media.value
media.caption = message.caption
aynav, vnay = await save_file(media)
if aynav:
total_files += 1
elif vnay == 0:
duplicate += 1
elif vnay == 2:
errors += 1
except Exception as e:
logger.exception(e)
await msg.edit(f'Error: {e}')
else:
await msg.edit(f'Succesfully saved {total_files} to dataBase!\nDuplicate Files Skipped: {duplicate}\nDeleted Messages Skipped: {deleted}\nNon-Media messages skipped: {no_media + unsupported}(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}')
================================================
FILE: plugins/inline.py
================================================
import logging
from pyrogram import Client, emoji, filters
from pyrogram.errors.exceptions.bad_request_400 import QueryIdInvalid
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, InlineQueryResultCachedDocument, InlineQuery
from database.ia_filterdb import get_search_results
from utils import is_subscribed, get_size, temp
from info import CACHE_TIME, AUTH_USERS, AUTH_CHANNEL, CUSTOM_FILE_CAPTION
from database.connections_mdb import active_connection
logger = logging.getLogger(__name__)
cache_time = 0 if AUTH_USERS or AUTH_CHANNEL else CACHE_TIME
async def inline_users(query: InlineQuery):
if AUTH_USERS:
if query.from_user and query.from_user.id in AUTH_USERS:
return True
else:
return False
if query.from_user and query.from_user.id not in temp.BANNED_USERS:
return True
return False
@Client.on_inline_query()
async def answer(bot, query):
"""𝖲𝗁𝗈𝗐 𝖲𝖾𝖺𝗋𝖼𝗁 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖥𝗈𝗋 𝖦𝗂𝗏𝖾𝗇 𝖨𝗇𝗅𝗂𝗇𝖾 𝖰𝗎𝖾𝗋𝗒"""
chat_id = await active_connection(str(query.from_user.id))
if not await inline_users(query):
await query.answer(results=[],
cache_time=0,
switch_pm_text='okDa',
switch_pm_parameter="hehe")
return
if AUTH_CHANNEL and not await is_subscribed(bot, query):
await query.answer(results=[],
cache_time=0,
switch_pm_text='𝖸𝗈𝗎 𝖧𝖺𝗏𝖾 𝖳𝗈 𝖲𝗎𝖻𝗌𝖼𝗋𝗂𝖻𝖾 𝖬𝗒 𝖢𝗁𝖺𝗇𝗇𝖾𝗅 𝖳𝗈 𝖴𝗌𝖾 𝖬𝖾 :)',
switch_pm_parameter="subscribe")
return
results = []
if '|' in query.query:
string, file_type = query.query.split('|', maxsplit=1)
string = string.strip()
file_type = file_type.strip().lower()
else:
string = query.query.strip()
file_type = None
offset = int(query.offset or 0)
reply_markup = get_reply_markup(query=string)
files, next_offset, total = await get_search_results(
chat_id,
string,
file_type=file_type,
max_results=10,
offset=offset)
for file in files:
title=file.file_name
size=get_size(file.file_size)
f_caption=file.caption
if CUSTOM_FILE_CAPTION:
try:
f_caption=CUSTOM_FILE_CAPTION.format(file_name= '' if title is None else title, file_size='' if size is None else size, file_caption='' if f_caption is None else f_caption)
except Exception as e:
logger.exception(e)
f_caption=f_caption
if f_caption is None:
f_caption = f"{file.file_name}"
results.append(
InlineQueryResultCachedDocument(
title=file.file_name,
document_file_id=file.file_id,
caption=f_caption,
description=f'Size: {get_size(file.file_size)}\nType: {file.file_type}',
reply_markup=reply_markup))
if results:
switch_pm_text = f"{emoji.FILE_FOLDER} 𝖧𝖾𝗋𝖾 𝖨𝗌 𝖳𝗁𝖾 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 "
if string:
switch_pm_text += f" for {string}"
try:
await query.answer(results=results,
is_personal = True,
cache_time=cache_time,
switch_pm_text=switch_pm_text,
switch_pm_parameter="start",
next_offset=str(next_offset))
except QueryIdInvalid:
pass
except Exception as e:
logging.exception(str(e))
else:
switch_pm_text = f'{emoji.CROSS_MARK} 𝖭𝗈 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖥𝗈𝗎𝗇𝖽'
if string:
switch_pm_text += f' for "{string}"'
await query.answer(results=[],
is_personal = True,
cache_time=cache_time,
switch_pm_text=switch_pm_text,
switch_pm_parameter="okay")
def get_reply_markup(query):
buttons = [
[
InlineKeyboardButton('🔎 𝖲𝖾𝖺𝗋𝖼𝗁 𝖠𝗀𝖺𝗂𝗇', switch_inline_query_current_chat=query),
InlineKeyboardButton('⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡', url="https://t.me/piroxbots")
]
]
return InlineKeyboardMarkup(buttons)
================================================
FILE: plugins/json.py
================================================
import os
from pyrogram import Client, filters
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, Message, CallbackQuery
@Client.on_message(filters.command(["json", 'js', 'showjson']))
async def jsonify(_, message):
the_real_message = None
reply_to_id = None
if message.reply_to_message:
the_real_message = message.reply_to_message
else:
the_real_message = message
try:
pk = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="🔐 𝖢𝗅𝗈𝗌𝖾",
callback_data="close_data"
)
]
]
)
await message.reply_text(f"{the_real_message}", reply_markup=pk, quote=True)
except Exception as e:
with open("json.text", "w+", encoding="utf8") as out_file:
out_file.write(str(the_real_message))
reply_markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="🔐 𝖢𝗅𝗈𝗌𝖾",
callback_data="close_data"
)
]
]
)
await message.reply_document(
document="json.text",
caption=str(e),
disable_notification=True,
quote=True,
reply_markup=reply_markup
)
os.remove("json.text")
================================================
FILE: plugins/misc.py
================================================
import os
from pyrogram import Client, filters, enums
from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty
from info import IMDB_TEMPLATE
from utils import extract_user, get_file_id, get_poster, last_online
import time
from datetime import datetime
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
@Client.on_message(filters.command('id'))
async def showid(client, message):
chat_type = message.chat.type
if chat_type == enums.ChatType.PRIVATE:
user_id = message.chat.id
first = message.from_user.first_name
last = message.from_user.last_name or ""
username = message.from_user.username
dc_id = message.from_user.dc_id or ""
await message.reply_text(
f"➲ First Name: {first}\n➲ Last Name: {last}\n➲ Username: {username}\n➲ Telegram ID: {user_id}\n➲ Data Centre: {dc_id}",
quote=True
)
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
_id = ""
_id += (
"➲ Chat ID: "
f"{message.chat.id}\n"
)
if message.reply_to_message:
_id += (
"➲ User ID: "
f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
"➲ Replied User ID: "
f"{message.reply_to_message.from_user.id if message.reply_to_message.from_user else 'Anonymous'}\n"
)
file_info = get_file_id(message.reply_to_message)
else:
_id += (
"➲ User ID: "
f"{message.from_user.id if message.from_user else 'Anonymous'}\n"
)
file_info = get_file_id(message)
if file_info:
_id += (
f"{file_info.message_type}: "
f"{file_info.file_id}\n"
)
await message.reply_text(
_id,
quote=True
)
@Client.on_message(filters.command(["info"]))
async def who_is(client, message):
status_message = await message.reply_text(
"`Fetching user info...`"
)
await status_message.edit(
"`Processing user info...`"
)
from_user = None
from_user_id, _ = extract_user(message)
try:
from_user = await client.get_users(from_user_id)
except Exception as error:
await status_message.edit(str(error))
return
if from_user is None:
return await status_message.edit("no valid user_id / message specified")
message_out_str = ""
message_out_str += f"➲First Name: {from_user.first_name}\n"
last_name = from_user.last_name or "None"
message_out_str += f"➲Last Name: {last_name}\n"
message_out_str += f"➲Telegram ID: {from_user.id}\n"
username = from_user.username or "None"
dc_id = from_user.dc_id or "[User Doesn't Have A Valid DP]"
message_out_str += f"➲Data Centre: {dc_id}\n"
message_out_str += f"➲User Name: @{username}\n"
message_out_str += f"➲User 𝖫𝗂𝗇𝗄: Click Here\n"
if message.chat.type in ((enums.ChatType.SUPERGROUP, enums.ChatType.CHANNEL)):
try:
chat_member_p = await message.chat.get_member(from_user.id)
joined_date = (
chat_member_p.joined_date or datetime.now()
).strftime("%Y.%m.%d %H:%M:%S")
message_out_str += (
"➲Joined this Chat on: "
f"{joined_date}"
"\n"
)
except UserNotParticipant:
pass
chat_photo = from_user.photo
if chat_photo:
local_user_photo = await client.download_media(
message=chat_photo.big_file_id
)
buttons = [[
InlineKeyboardButton('🔐 𝖢𝗅𝗈𝗌𝖾', callback_data='close_data')
]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_photo(
photo=local_user_photo,
quote=True,
reply_markup=reply_markup,
caption=message_out_str,
parse_mode=enums.ParseMode.HTML,
disable_notification=True
)
os.remove(local_user_photo)
else:
buttons = [[
InlineKeyboardButton('🔐 𝖢𝗅𝗈𝗌𝖾', callback_data='close_data')
]]
reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_text(
text=message_out_str,
reply_markup=reply_markup,
quote=True,
parse_mode=enums.ParseMode.HTML,
disable_notification=True
)
await status_message.delete()
@Client.on_message(filters.command(["imdb", 'search']))
async def imdb_search(client, message):
if ' ' in message.text:
k = await message.reply('Searching IMDb....')
r, title = message.text.split(None, 1)
movies = await get_poster(title, bulk=True)
if not movies:
return await message.reply("No results Found")
btn = [
[
InlineKeyboardButton(
text=f"{movie.get('title')} - {movie.get('year')}",
callback_data=f"imdb#{movie.movieID}",
)
]
for movie in movies
]
await k.edit('𝖧𝖾𝗋𝖾 𝗂𝗌 𝗐𝗁𝖺𝗍 𝗂 𝖿𝗈𝗎𝗇𝖽 𝗈𝗇 𝖨𝖬𝖣𝖻', reply_markup=InlineKeyboardMarkup(btn))
else:
await message.reply('Give me a movie / series Name')
@Client.on_callback_query(filters.regex('^imdb'))
async def imdb_callback(bot: Client, quer_y: CallbackQuery):
i, movie = quer_y.data.split('#')
imdb = await get_poster(query=movie, id=True)
btn = [
[
InlineKeyboardButton(
text=f"{imdb.get('title')}",
url=imdb['url'],
)
]
]
message = quer_y.message.reply_to_message or quer_y.message
if imdb:
caption = IMDB_TEMPLATE.format(
query = imdb['title'],
title = imdb['title'],
votes = imdb['votes'],
aka = imdb["aka"],
seasons = imdb["seasons"],
box_office = imdb['box_office'],
localized_title = imdb['localized_title'],
kind = imdb['kind'],
imdb_id = imdb["imdb_id"],
cast = imdb["cast"],
runtime = imdb["runtime"],
countries = imdb["countries"],
certificates = imdb["certificates"],
languages = imdb["languages"],
director = imdb["director"],
writer = imdb["writer"],
producer = imdb["producer"],
composer = imdb["composer"],
cinematographer = imdb["cinematographer"],
music_team = imdb["music_team"],
distributors = imdb["distributors"],
release_date = imdb['release_date'],
year = imdb['year'],
genres = imdb['genres'],
poster = imdb['poster'],
plot = imdb['plot'],
rating = imdb['rating'],
url = imdb['url'],
**locals()
)
else:
caption = "No Results"
if imdb.get('poster'):
try:
await quer_y.message.reply_photo(photo=imdb['poster'], caption=caption, reply_markup=InlineKeyboardMarkup(btn))
except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
pic = imdb.get('poster')
poster = pic.replace('.jpg', "._V1_UX360.jpg")
await quer_y.message.reply_photo(photo=poster, caption=caption, reply_markup=InlineKeyboardMarkup(btn))
except Exception as e:
logger.exception(e)
await quer_y.message.reply(caption, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=False)
await quer_y.message.delete()
else:
await quer_y.message.edit(caption, reply_markup=InlineKeyboardMarkup(btn), disable_web_page_preview=False)
await quer_y.answer()
================================================
FILE: plugins/p_ttishow.py
================================================
from pyrogram import Client, filters, enums
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, CallbackQuery
from pyrogram.errors.exceptions.bad_request_400 import MessageTooLong, PeerIdInvalid
from info import ADMINS, LOG_CHANNEL, SUPPORT_CHAT, MELCOW_VID
from database.users_chats_db import db
from database.ia_filterdb import Media
from utils import get_size, temp, get_settings
from Script import script
from pyrogram.errors import ChatAdminRequired
import asyncio
@Client.on_message(filters.new_chat_members & filters.group)
async def save_group(bot, message):
r_j_check = [u.id for u in message.new_chat_members]
if temp.ME in r_j_check:
if not await db.get_chat(message.chat.id):
total=await bot.get_chat_members_count(message.chat.id)
r_j = message.from_user.mention if message.from_user else "Anonymous"
await bot.send_message(LOG_CHANNEL, script.LOG_TEXT_G.format(message.chat.title, message.chat.id, total, r_j))
await db.add_chat(message.chat.id, message.chat.title)
if message.chat.id in temp.BANNED_CHATS:
buttons = [[
InlineKeyboardButton('🌐 𝖲𝗎𝗉𝗉𝗈𝗋𝗍 🌐', url=f"https://t.me/{SUPPORT_CHAT}")
]]
reply_markup=InlineKeyboardMarkup(buttons)
k = await message.reply(
text='CHAT NOT ALLOWED 🐞\n\nMy admins has restricted me from working here ! If you want to know more about it contact support..',
reply_markup=reply_markup,
)
try:
await k.pin()
except:
pass
await bot.leave_chat(message.chat.id)
return
buttons = [[
InlineKeyboardButton('🧩 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 🧩', url=f"https://t.me/{SUPPORT_CHAT}"),
InlineKeyboardButton('⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡', url=f"https://t.me/piroxbots")
]]
reply_markup=InlineKeyboardMarkup(buttons)
await message.reply_text(
text=f"Thankyou For Adding Me In {message.chat.title} ❣️\n\nIf you have any questions & doubts about using me contact 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 GROUP.",
reply_markup=reply_markup)
else:
settings = await get_settings(message.chat.id)
if settings["welcome"]:
for u in message.new_chat_members:
if (temp.MELCOW).get('welcome') is not None:
try:
await (temp.MELCOW['welcome']).delete()
except:
pass
temp.MELCOW['welcome'] = await message.reply_video(
video=(MELCOW_VID),
caption=(script.MELCOW_ENG.format(u.mention, message.chat.title)),
reply_markup=InlineKeyboardMarkup(
[[
InlineKeyboardButton('🧩 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 🧩', url=f"https://t.me/{SUPPORT_CHAT}"),
InlineKeyboardButton('⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡', url=f"https://t.me/piroxbots")
]]
),
parse_mode=enums.ParseMode.HTML
)
if settings["auto_delete"]:
await asyncio.sleep(300)
await (temp.MELCOW['welcome']).delete()
@Client.on_message(filters.command('leave') & filters.user(ADMINS))
async def leave_a_chat(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a chat id')
chat = message.command[1]
try:
chat = int(chat)
except:
chat = chat
try:
buttons = [[
InlineKeyboardButton('🧩 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 🧩', url=f"https://t.me/{SUPPORT_CHAT}"),
InlineKeyboardButton('⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡', url=f"https://t.me/piroxbots")
]]
reply_markup=InlineKeyboardMarkup(buttons)
await bot.send_message(
chat_id=chat,
text='Hello Friends, \nMy admin has told me to leave from group so i go! If you wanna add me again contact my 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 GROUP.',
reply_markup=reply_markup,
)
await bot.leave_chat(chat)
await message.reply(f"left the chat `{chat}`")
except Exception as e:
await message.reply(f'Error - {e}')
@Client.on_message(filters.command('disable') & filters.user(ADMINS))
async def disable_chat(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a chat id')
r = message.text.split(None)
if len(r) > 2:
reason = message.text.split(None, 2)[2]
chat = message.text.split(None, 2)[1]
else:
chat = message.command[1]
reason = "No reason Provided"
try:
chat_ = int(chat)
except:
return await message.reply('Give Me A Valid Chat ID')
cha_t = await db.get_chat(int(chat_))
if not cha_t:
return await message.reply("Chat Not Found In DB")
if cha_t['is_disabled']:
return await message.reply(f"This chat is already disabled:\nReason- {cha_t['reason']} ")
await db.disable_chat(int(chat_), reason)
temp.BANNED_CHATS.append(int(chat_))
await message.reply('Chat Successfully Disabled')
try:
buttons = [[
InlineKeyboardButton('🧩 𝖲𝖴𝖯𝖯𝖮𝖱𝖳 🧩', url=f"https://t.me/{SUPPORT_CHAT}"),
InlineKeyboardButton('⚡𝖴𝗉𝖽𝖺𝗍𝖾𝗌 ⚡', url=f"https://t.me/piroxbots")
]]
reply_markup=InlineKeyboardMarkup(buttons)
await bot.send_message(
chat_id=chat_,
text=f'𝖧𝖾𝗅𝗅𝗈 𝖥𝗋𝗂𝖾𝗇𝖽𝗌, \n𝖬𝗒 𝖺𝖽𝗆𝗂𝗇 𝗁𝖺𝗌 𝗍𝗈𝗅𝖽 𝗆𝖾 𝗍𝗈 𝗅𝖾𝖺𝗏𝖾 𝖿𝗋𝗈𝗆 𝗀𝗋𝗈𝗎𝗉 𝗌𝗈 𝗂 𝗀𝗈! 𝖨𝖿 𝗒𝗈𝗎 𝗐𝖺𝗇𝗇𝖺 𝖺𝖽𝖽 𝗆𝖾 𝖺𝗀𝖺𝗂𝗇 𝖼𝗈𝗇𝗍𝖺𝖼𝗍 𝗆𝗒 𝗌𝗎𝗉𝗉𝗈𝗋𝗍 𝗀𝗋𝗈𝗎𝗉. \nReason : {reason}',
reply_markup=reply_markup)
await bot.leave_chat(chat_)
except Exception as e:
await message.reply(f"Error - {e}")
@Client.on_message(filters.command('enable') & filters.user(ADMINS))
async def re_enable_chat(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a chat id')
chat = message.command[1]
try:
chat_ = int(chat)
except:
return await message.reply('Give Me A Valid Chat ID')
sts = await db.get_chat(int(chat))
if not sts:
return await message.reply("Chat Not Found In DB !")
if not sts.get('is_disabled'):
return await message.reply('This chat is not yet disabled.')
await db.re_enable_chat(int(chat_))
temp.BANNED_CHATS.remove(int(chat_))
await message.reply("Chat Successfully re-enabled")
@Client.on_message(filters.command('stats') & filters.incoming)
async def get_ststs(bot, message):
rju = await message.reply('Fetching stats...')
total_users = await db.total_users_count()
totl_chats = await db.total_chat_count()
files = await Media.count_documents()
size = await db.get_db_size()
free = 536870912 - size
size = get_size(size)
free = get_size(free)
await rju.edit(script.STATUS_TXT.format(files, total_users, totl_chats, size, free))
@Client.on_message(filters.command('invite') & filters.user(ADMINS))
async def gen_invite(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a chat id')
chat = message.command[1]
try:
chat = int(chat)
except:
return await message.reply('Give Me A Valid Chat ID')
try:
link = await bot.create_chat_invite_link(chat)
except ChatAdminRequired:
return await message.reply("Invite Link Generation Failed, Iam Not Having Sufficient Rights")
except Exception as e:
return await message.reply(f'Error {e}')
await message.reply(f'Here is your Invite Link {link.invite_link}')
@Client.on_message(filters.command('ban') & filters.user(ADMINS))
async def ban_a_user(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a user id / username')
r = message.text.split(None)
if len(r) > 2:
reason = message.text.split(None, 2)[2]
chat = message.text.split(None, 2)[1]
else:
chat = message.command[1]
reason = "No reason Provided"
try:
chat = int(chat)
except:
pass
try:
k = await bot.get_users(chat)
except PeerIdInvalid:
return await message.reply("This is an invalid user, make sure ia have met him before.")
except IndexError:
return await message.reply("This might be a channel, make sure its a user.")
except Exception as e:
return await message.reply(f'Error - {e}')
else:
jar = await db.get_ban_status(k.id)
if jar['is_banned']:
return await message.reply(f"{k.mention} is already banned\nReason: {jar['ban_reason']}")
await db.ban_user(k.id, reason)
temp.BANNED_USERS.append(k.id)
await message.reply(f"Successfully banned {k.mention}")
@Client.on_message(filters.command('unban') & filters.user(ADMINS))
async def unban_a_user(bot, message):
if len(message.command) == 1:
return await message.reply('Give me a user id / username')
r = message.text.split(None)
if len(r) > 2:
reason = message.text.split(None, 2)[2]
chat = message.text.split(None, 2)[1]
else:
chat = message.command[1]
reason = "No reason Provided"
try:
chat = int(chat)
except:
pass
try:
k = await bot.get_users(chat)
except PeerIdInvalid:
return await message.reply("This is an invalid user, make sure ia have met him before.")
except IndexError:
return await message.reply("Thismight be a channel, make sure its a user.")
except Exception as e:
return await message.reply(f'Error - {e}')
else:
jar = await db.get_ban_status(k.id)
if not jar['is_banned']:
return await message.reply(f"{k.mention} is not yet banned.")
await db.remove_ban(k.id)
temp.BANNED_USERS.remove(k.id)
await message.reply(f"Successfully unbanned {k.mention}")
@Client.on_message(filters.command('users') & filters.user(ADMINS))
async def list_users(bot, message):
raju = await message.reply('Getting List Of Users')
users = await db.get_all_users()
out = "Users Saved In DB Are:\n\n"
async for user in users:
out += f"{user['name']}"
if user['ban_status']['is_banned']:
out += '( Banned User )'
out += '\n'
try:
await raju.edit_text(out)
except MessageTooLong:
with open('users.txt', 'w+') as outfile:
outfile.write(out)
await message.reply_document('users.txt', caption="List Of Users")
@Client.on_message(filters.command('chats') & filters.user(ADMINS))
async def list_chats(bot, message):
raju = await message.reply('Getting List Of chats')
chats = await db.get_all_chats()
out = "Chats Saved In DB Are:\n\n"
async for chat in chats:
out += f"**Title:** `{chat['title']}`\n**- ID:** `{chat['id']}`"
if chat['chat_status']['is_disabled']:
out += '( Disabled Chat )'
out += '\n'
try:
await raju.edit_text(out)
except MessageTooLong:
with open('chats.txt', 'w+') as outfile:
outfile.write(out)
await message.reply_document('chats.txt', caption="List Of Chats")
================================================
FILE: plugins/pm_filter.py
================================================
import asyncio
import re
import ast
import math
import random
lock = asyncio.Lock()
from pyrogram.errors.exceptions.bad_request_400 import MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty
from Script import script
import pyrogram
from database.connections_mdb import active_connection, all_connections, delete_connection, if_active, make_active, \
make_inactive
from info import ADMINS, AUTH_CHANNEL, AUTH_USERS, SUPPORT_CHAT_ID, SUPPORT_CHAT, CUSTOM_FILE_CAPTION, PICS, AUTH_GROUPS, P_TTI_SHOW_OFF, NOR_IMG, LOG_CHANNEL, SPELL_IMG, MAX_B_TN, IMDB, \
SINGLE_BUTTON, SPELL_CHECK_REPLY, IMDB_TEMPLATE, NO_RESULTS_MSG
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery, InputMediaPhoto
from pyrogram import Client, filters, enums
from pyrogram.errors import FloodWait, UserIsBlocked, MessageNotModified, PeerIdInvalid
from utils import get_size, is_subscribed, get_poster, search_gagala, temp, get_settings, save_group_settings, send_all
from database.users_chats_db import db
from database.ia_filterdb import Media, get_file_details, get_search_results, get_bad_files
from database.filters_mdb import (
del_all,
find_filter,
get_filters,
)
from database.gfilters_mdb import (
find_gfilter,
get_gfilters,
del_allg
)
import logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.ERROR)
BUTTONS = {}
SPELL_CHECK = {}
@Client.on_message(filters.group & filters.text & filters.incoming)
async def give_filter(client, message):
if message.chat.id != SUPPORT_CHAT_ID:
glob = await global_filters(client, message)
if glob == False:
manual = await manual_filters(client, message)
if manual == False:
settings = await get_settings(message.chat.id)
try:
if settings['auto_ffilter']:
await auto_filter(client, message)
except KeyError:
grpid = await active_connection(str(message.from_user.id))
await save_group_settings(grpid, 'auto_ffilter', True)
settings = await get_settings(message.chat.id)
if settings['auto_ffilter']:
await auto_filter(client, message)
else: #a better logic to avoid repeated lines of code in auto_filter function
search = message.text
temp_files, temp_offset, total_results = await get_search_results(chat_id=message.chat.id, query=search.lower(), offset=0, filter=True)
if total_results == 0:
return
else:
return await message.reply_text(f"👋 𝖧𝖾𝗒 {message.from_user.mention} \n📁 {str(total_results)} 𝖱𝖾𝗌𝗎𝗅𝗍𝗌 𝖺𝗋𝖾 𝖿𝗈𝗎𝗇𝖽 𝖿𝗈𝗋 𝗒𝗈𝗎𝗋 𝗊𝗎𝖾𝗋𝗒 {search}.\n\nKindly ask movies and series here ⬇\n@blaster_arena & @blaster_movies")
@Client.on_message(filters.private & filters.text & filters.incoming)
async def pv_filter(client, message):
kd = await global_filters(client, message)
if kd == False:
await auto_filter(client, message)
@Client.on_callback_query(filters.regex(r"^next"))
async def next_page(bot, query):
ident, req, key, offset = query.data.split("_")
if int(req) not in [query.from_user.id, 0]:
return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True)
try:
offset = int(offset)
except:
offset = 0
search = BUTTONS.get(key)
if not search:
await query.answer(script.OLD_ALRT_TXT.format(query.from_user.first_name),show_alert=True)
return
files, n_offset, total = await get_search_results(query.message.chat.id, search, offset=offset, filter=True)
try:
n_offset = int(n_offset)
except:
n_offset = 0
if not files:
return
settings = await get_settings(query.message.chat.id)
pre = 'filep' if settings['file_secure'] else 'file'
temp.FILES_IDS[key] = files
if settings['button']:
btn = [
[
InlineKeyboardButton(
text=f"🔖{get_size(file.file_size)}🔮{file.file_name}", callback_data=f'{pre}#{file.file_id}'
),
]
for file in files
]
else:
btn = [
[
InlineKeyboardButton(
text=f"{file.file_name}", callback_data=f'{pre}#{file.file_id}'
),
InlineKeyboardButton(
text=f"{get_size(file.file_size)}",
callback_data=f'{pre}#{file.file_id}',
),
]
for file in files
]
try:
if settings['auto_delete']:
btn.insert(0,
[
InlineKeyboardButton(f'😇 Info', 'tips'),
InlineKeyboardButton(f'📝 𝖳𝗂𝗉𝗌', 'info')
]
)
else:
btn.insert(0,
[
InlineKeyboardButton(f'😇 Info', 'tips'),
InlineKeyboardButton(f'📝 𝖳𝗂𝗉𝗌', 'info')
]
)
except KeyError:
grpid = await active_connection(str(query.message.from_user.id))
await save_group_settings(grpid, 'auto_delete', True)
settings = await get_settings(query.message.chat.id)
if settings['auto_delete']:
btn.insert(0,
[
InlineKeyboardButton(f'😇 Info', 'tips'),
InlineKeyboardButton(f'📝 𝖳𝗂𝗉𝗌', 'info')
]
)
else:
btn.insert(0,
[
InlineKeyboardButton(f'😇 Info', 'tips'),
InlineKeyboardButton(f'📝 𝖳𝗂𝗉𝗌', 'info')
]
)
try:
settings = await get_settings(query.message.chat.id)
if settings['max_btn']:
if 0 < offset <= 10:
off_set = 0
elif offset == 0:
off_set = None
else:
off_set = offset - 10
if n_offset == 0:
btn.append(
[InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")]
)
elif off_set is None:
btn.append([InlineKeyboardButton("📃", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")])
else:
btn.append(
[
InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"),
InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"),
InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")
],
)
else:
if 0 < offset <= int(MAX_B_TN):
off_set = 0
elif offset == 0:
off_set = None
else:
off_set = offset - int(MAX_B_TN)
if n_offset == 0:
btn.append(
[InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages")]
)
elif off_set is None:
btn.append([InlineKeyboardButton("📃", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")])
else:
btn.append(
[
InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"),
InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"),
InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")
],
)
except KeyError:
await save_group_settings(query.message.chat.id, 'max_btn', False)
settings = await get_settings(query.message.chat.id)
if settings['max_btn']:
if 0 < offset <= 10:
off_set = 0
elif offset == 0:
off_set = None
else:
off_set = offset - 10
if n_offset == 0:
btn.append(
[InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages")]
)
elif off_set is None:
btn.append([InlineKeyboardButton("📃", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"), InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")])
else:
btn.append(
[
InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"),
InlineKeyboardButton(f"{math.ceil(int(offset)/10)+1} / {math.ceil(total/10)}", callback_data="pages"),
InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")
],
)
else:
if 0 < offset <= int(MAX_B_TN):
off_set = 0
elif offset == 0:
off_set = None
else:
off_set = offset - int(MAX_B_TN)
if n_offset == 0:
btn.append(
[InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"), InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages")]
)
elif off_set is None:
btn.append([InlineKeyboardButton("📃", callback_data="pages"), InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"), InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")])
else:
btn.append(
[
InlineKeyboardButton("◀️ 𝖡𝖠𝖢𝖪", callback_data=f"next_{req}_{key}_{off_set}"),
InlineKeyboardButton(f"{math.ceil(int(offset)/int(MAX_B_TN))+1} / {math.ceil(total/int(MAX_B_TN))}", callback_data="pages"),
InlineKeyboardButton("𝖭𝖤𝖷𝖳 ▶️", callback_data=f"next_{req}_{key}_{n_offset}")
],
)
btn.insert(0, [
InlineKeyboardButton(f'🎬 {search} 🎬', 'rkbtn')
])
btn.insert(2, [
InlineKeyboardButton("📤 𝖲𝖾𝗇𝖽 𝖠𝗅𝗅 𝖥𝗂𝗅𝖾𝗌 📤", callback_data=f"send_all#{req}#{key}#{pre}")
])
try:
await query.edit_message_reply_markup(
reply_markup=InlineKeyboardMarkup(btn)
)
except MessageNotModified:
pass
await query.answer()
@Client.on_callback_query(filters.regex(r"^spol"))
async def advantage_spoll_choker(bot, query):
_, user, movie_, key = query.data.split('#')
movies = temp.SPELL_CHECK.get(key)
if not movies:
return await query.answer(script.OLD_ALRT_TXT.format(query.from_user.first_name), show_alert=True)
if int(user) != 0 and query.from_user.id != int(user):
return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True)
if movie_ == "close_spellcheck":
return await query.message.delete()
movie = movies[(int(movie_))]
await query.answer(script.TOP_ALRT_MSG)
gl = await global_filters(bot, query.message, text=movie)
if gl == False:
k = await manual_filters(bot, query.message, text=movie)
if k == False:
files, offset, total_results = await get_search_results(query.message.chat.id, movie, offset=0, filter=True)
if files:
k = (movie, files, offset, total_results)
await auto_filter(bot, query, k)
else:
reqstr1 = query.from_user.id if query.from_user else 0
reqstr = await bot.get_users(reqstr1)
if NO_RESULTS_MSG:
await bot.send_message(chat_id=LOG_CHANNEL, text=(script.NORSLTS.format(reqstr.id, reqstr.mention, movie)))
k = await query.message.edit(script.MVE_NT_FND)
await asyncio.sleep(10)
await k.delete()
@Client.on_callback_query()
async def cb_handler(client: Client, query: CallbackQuery):
if query.data == "close_data":
await query.message.delete()
elif query.data == "gfiltersdeleteallconfirm":
await del_allg(query.message, 'gfilters')
await query.answer("Done !")
return
elif query.data == "gfiltersdeleteallcancel":
await query.message.reply_to_message.delete()
await query.message.delete()
await query.answer("Process Cancelled !")
return
elif query.data == "delallconfirm":
userid = query.from_user.id
chat_type = query.message.chat.type
if chat_type == enums.ChatType.PRIVATE:
grpid = await active_connection(str(userid))
if grpid is not None:
grp_id = grpid
try:
chat = await client.get_chat(grpid)
title = chat.title
except:
await query.message.edit_text("Make sure I'm present in your group!!", quote=True)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
else:
await query.message.edit_text(
"I'm not connected to any groups!\nCheck /connections or connect to any groups",
quote=True
)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = query.message.chat.id
title = query.message.chat.title
else:
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
st = await client.get_chat_member(grp_id, userid)
if (st.status == enums.ChatMemberStatus.OWNER) or (str(userid) in ADMINS):
await del_all(query.message, grp_id, title)
else:
await query.answer("You need to be Group Owner or an Auth User to do that!", show_alert=True)
elif query.data == "delallcancel":
userid = query.from_user.id
chat_type = query.message.chat.type
if chat_type == enums.ChatType.PRIVATE:
await query.message.reply_to_message.delete()
await query.message.delete()
elif chat_type in [enums.ChatType.GROUP, enums.ChatType.SUPERGROUP]:
grp_id = query.message.chat.id
st = await client.get_chat_member(grp_id, userid)
if (st.status == enums.ChatMemberStatus.OWNER) or (str(userid) in ADMINS):
await query.message.delete()
try:
await query.message.reply_to_message.delete()
except:
pass
else:
await query.answer("That's not for you!!", show_alert=True)
elif "groupcb" in query.data:
await query.answer()
group_id = query.data.split(":")[1]
act = query.data.split(":")[2]
hr = await client.get_chat(int(group_id))
title = hr.title
user_id = query.from_user.id
if act == "":
stat = "CONNECT"
cb = "connectcb"
else:
stat = "DISCONNECT"
cb = "disconnect"
keyboard = InlineKeyboardMarkup([
[InlineKeyboardButton(f"{stat}", callback_data=f"{cb}:{group_id}"),
InlineKeyboardButton("DELETE", callback_data=f"deletecb:{group_id}")],
[InlineKeyboardButton("BACK", callback_data="backcb")]
])
await query.message.edit_text(
f"Group Name : **{title}**\nGroup ID : `{group_id}`",
reply_markup=keyboard,
parse_mode=enums.ParseMode.MARKDOWN
)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
elif "connectcb" in query.data:
await query.answer()
group_id = query.data.split(":")[1]
hr = await client.get_chat(int(group_id))
title = hr.title
user_id = query.from_user.id
mkact = await make_active(str(user_id), str(group_id))
if mkact:
await query.message.edit_text(
f"Connected to **{title}**",
parse_mode=enums.ParseMode.MARKDOWN
)
else:
await query.message.edit_text('Disconnected from', parse_mode=enums.ParseMode.MARKDOWN)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
elif "disconnect" in query.data:
await query.answer()
group_id = query.data.split(":")[1]
hr = await client.get_chat(int(group_id))
title = hr.title
user_id = query.from_user.id
mkinact = await make_inactive(str(user_id))
if mkinact:
await query.message.edit_text(
f"Disconnected from **{title}**",
parse_mode=enums.ParseMode.MARKDOWN
)
else:
await query.message.edit_text(
f"Some error occurred!!",
parse_mode=enums.ParseMode.MARKDOWN
)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
elif "deletecb" in query.data:
await query.answer()
user_id = query.from_user.id
group_id = query.data.split(":")[1]
delcon = await delete_connection(str(user_id), str(group_id))
if delcon:
await query.message.edit_text(
"Successfully deleted connection"
)
else:
await query.message.edit_text(
f"Some error occurred!!",
parse_mode=enums.ParseMode.MARKDOWN
)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
elif query.data == "backcb":
await query.answer()
userid = query.from_user.id
groupids = await all_connections(str(userid))
if groupids is None:
await query.message.edit_text(
"There are no active connections!! Connect to some groups first.",
)
return await query.answer('𝖯𝗂𝗋𝖺𝖼𝗒 𝗂𝗌 𝖢𝗋𝗂𝗆𝖾 !')
buttons = []
for groupid in groupids:
try:
ttl = await client.get_chat(int(groupid))
title = ttl.title
active = await if_active(str(userid), str(groupid))
act = " - ACTIVE" if active else ""
buttons.append(
[
InlineKeyboardButton(
text=f"{title}{act}", callback_data=f"groupcb:{groupid}:{act}"
)
]
)
except:
pass
if buttons:
await query.message.edit_text(
"Your connected group details ;\n\n",
reply_markup=InlineKeyboardMarkup(buttons)
)
elif "gfilteralert" in query.data:
grp_id = query.message.chat.id
i = query.data.split(":")[1]
keyword = query.data.split(":")[2]
reply_text, btn, alerts, fileid = await find_gfilter('gfilters', keyword)
if alerts is not None:
alerts = ast.literal_eval(alerts)
alert = alerts[int(i)]
alert = alert.replace("\\n", "\n").replace("\\t", "\t")
await query.answer(alert, show_alert=True)
elif "alertmessage" in query.data:
grp_id = query.message.chat.id
i = query.data.split(":")[1]
keyword = query.data.split(":")[2]
reply_text, btn, alerts, fileid = await find_filter(grp_id, keyword)
if alerts is not None:
alerts = ast.literal_eval(alerts)
alert = alerts[int(i)]
alert = alert.replace("\\n", "\n").replace("\\t", "\t")
await query.answer(alert, show_alert=True)
if query.data.startswith("file"):
clicked = query.from_user.id
try:
typed = query.message.reply_to_message.from_user.id
except:
typed = query.from_user.id
ident, file_id = query.data.split("#")
files_ = await get_file_details(file_id)
if not files_:
return await query.answer('No such file exist.')
files = files_[0]
title = files.file_name
size = get_size(files.file_size)
f_caption = files.caption
settings = await get_settings(query.message.chat.id)
if CUSTOM_FILE_CAPTION:
try:
f_caption = CUSTOM_FILE_CAPTION.format(file_name='' if title is None else title,
file_size='' if size is None else size,
file_caption='' if f_caption is None else f_caption)
except Exception as e:
logger.exception(e)
f_caption = f_caption
if f_caption is None:
f_caption = f"{files.file_name}"
try:
if AUTH_CHANNEL and not await is_subscribed(client, query):
if clicked == typed:
await query.answer(url=f"https://t.me/{temp.U_NAME}?start={ident}_{file_id}")
return
else:
await query.answer(f"𝖧𝖾𝗒 {query.from_user.first_name}, 𝖳𝗁𝗂𝗌 𝗂𝗌 𝗇𝗈𝗍 𝗒𝗈𝗎𝗋 𝗋𝖾𝗊𝗎𝖾𝗌𝗍 !", show_alert=True)
elif settings['botpm']:
if clicked == typed:
await query.answer(url=f"https://t.me/{temp.U_NAME}?start={ident}_{file_id}")
return
else:
await query.answer(f"𝖧𝖾𝗒 {query.from_user.first_name}, 𝖳𝗁𝗂𝗌 𝗂𝗌 𝗇𝗈𝗍 𝗒𝗈𝗎𝗋 𝗋𝖾𝗊𝗎𝖾𝗌𝗍 !", show_alert=True)
else:
if clicked == typed:
await client.send_cached_media(
chat_id=query.from_user.id,
file_id=file_id,
caption=f_caption,
protect_content=True if ident == "filep" else False,
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url="https://t.me/piroxbots") ] ] ))
else:
await query.answer(f"𝖧𝖾𝗒 {query.from_user.first_name}, 𝖳𝗁𝗂𝗌 𝗂𝗌 𝗇𝗈𝗍 𝗒𝗈𝗎𝗋 𝗋𝖾𝗊𝗎𝖾𝗌𝗍 !", show_alert=True)
await query.answer('𝖢𝗁𝖾𝖼𝗄 𝖯𝖬, 𝖨 𝗁𝖺𝗏𝖾 𝗌𝖾𝗇𝗍 𝖿𝗂𝗅𝖾𝗌 𝗂𝗇 𝖯𝖬', show_alert=True)
except UserIsBlocked:
await query.answer('𝖴𝗇𝖻𝗅𝗈𝖼𝗄 𝗍𝗁𝖾 𝖻𝗈𝗍 𝗆𝖺𝗇𝗁 !', show_alert=True)
except PeerIdInvalid:
await query.answer(url=f"https://t.me/{temp.U_NAME}?start={ident}_{file_id}")
except Exception as e:
await query.answer(url=f"https://t.me/{temp.U_NAME}?start={ident}_{file_id}")
elif query.data.startswith("checksub"):
if AUTH_CHANNEL and not await is_subscribed(client, query):
await query.answer("𝖨 𝖫𝗂𝗄𝖾 𝖸𝗈𝗎𝗋 𝖲𝗆𝖺𝗋𝗍𝗇𝖾𝗌𝗌, 𝖡𝗎𝗍 𝖣𝗈𝗇'𝗍 𝖡𝖾 𝖮𝗏𝖾𝗋𝗌𝗆𝖺𝗋𝗍 😒 \n𝖩𝗈𝗂𝗇 𝖴𝗉𝖽𝖺𝗍𝖾 𝖢𝗁𝖺𝗇𝗇𝖾𝗅 𝖿𝗂𝗋𝗌𝗍 ;)", show_alert=True)
return
ident, file_id = query.data.split("#")
files_ = await get_file_details(file_id)
if not files_:
return await query.answer('No such file exist.')
files = files_[0]
title = files.file_name
size = get_size(files.file_size)
f_caption = files.caption
if CUSTOM_FILE_CAPTION:
try:
f_caption = CUSTOM_FILE_CAPTION.format(file_name='' if title is None else title,
file_size='' if size is None else size,
file_caption='' if f_caption is None else f_caption)
except Exception as e:
logger.exception(e)
f_caption = f_caption
if f_caption is None:
f_caption = f"{title}"
await query.answer()
await client.send_cached_media(
chat_id=query.from_user.id,
file_id=file_id,
caption=f_caption,
protect_content=True if ident == 'checksubp' else False,
reply_markup=InlineKeyboardMarkup( [ [ InlineKeyboardButton('⚔️ 𝖯𝖨𝖱𝖮 𝖴𝖯𝖣𝖠𝖳𝖤𝖲 ⚔️', url="https://t.me/piroxbots") ] ] ))
elif query.data == "pages":
await query.answer()
elif query.data.startswith("send_all"):
_, req, key, pre = query.data.split("#")
if int(req) not in [query.from_user.id, 0]:
return await query.answer(script.ALRT_TXT.format(query.from_user.first_name), show_alert=True)
await query.answer(url=f"https://t.me/{temp.U_NAME}?start=all_{key}_{pre}")
elif query.data.startswith("killfilesdq"):
ident, keyword = query.data.split("#")
await query.message.edit_text(f"Fetching Files for your query {keyword} on DB... Please wait...")
files, total = await get_bad_files(keyword)
await query.message.edit_text(f"Found {total} files for your query {keyword} !\n\nFile deletion process will start in 5 seconds !")
await asyncio.sleep(5)
deleted = 0
async with lock:
try:
for file in files:
file_ids = file.file_id
file_name = file.file_name
result = await Media.collection.delete_one({
'_id': file_ids,
})
if result.deleted_count:
logger.info(f'File Found for your query {keyword}! Successfully deleted {file_name} from database.')
deleted += 1
if deleted % 20 == 0:
await query.message.edit_text(f"Process started for deleting files from DB. Successfully deleted {str(deleted)} files from DB for your query {keyword} !\n\nPlease wait...")
except Exception as e:
logger.exception(e)
await query.message.edit_text(f'Error: {e}')
else:
await query.message.edit_text(f"Process Completed for file deletion !\n\nSuccessfully deleted {str(deleted)} files from database for your query {keyword}.")
elif query.data.startswith("opnsetgrp"):
ident, grp_id = query.data.split("#")
userid = query.from_user.id if query.from_user else None
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
await query.answer("𝖸𝗈𝗎 𝖽𝗈𝗇'𝗍 𝗁𝖺𝗏𝖾 𝗋𝗂𝗀𝗁𝗍𝗌 𝗍𝗈 𝖽𝗈 𝗍𝗁𝗂𝗌 !", show_alert=True)
return
title = query.message.chat.title
settings = await get_settings(grp_id)
if settings is not None:
buttons = [
[
InlineKeyboardButton('𝖥𝗂𝗅𝗍𝖾𝗋 𝖡𝗎𝗍𝗍𝗈𝗇',
callback_data=f'setgs#button#{settings["button"]}#{str(grp_id)}'),
InlineKeyboardButton('𝖲𝗂𝗇𝗀𝗅𝖾 𝖡𝗎𝗍𝗍𝗈𝗇' if settings["button"] else '𝖣𝗈𝗎𝖻𝗅𝖾',
callback_data=f'setgs#button#{settings["button"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖥𝗂𝗅𝖾 𝖲𝖾𝗇𝖽 𝖬𝗈𝖽𝖾', callback_data=f'setgs#botpm#{settings["botpm"]}#{str(grp_id)}'),
InlineKeyboardButton('𝖬𝖺𝗇𝗎𝖺𝗅 𝖲𝗍𝖺𝗋𝗍' if settings["botpm"] else '𝖠𝗎𝗍𝗈 𝖲𝖾𝗇𝖽',
callback_data=f'setgs#botpm#{settings["botpm"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖯𝗋𝗈𝗍𝖾𝖼𝗍 𝖢𝗈𝗇𝗍𝖾𝗇𝗍',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["file_secure"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖨𝖬𝖣𝖻', callback_data=f'setgs#imdb#{settings["imdb"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["imdb"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#imdb#{settings["imdb"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖲𝗉𝖾𝗅𝗅 𝖢𝗁𝖾𝖼𝗄',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["spell_check"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖶𝖾𝗅𝖼𝗈𝗆𝖾 𝖬𝖾𝗌𝗌𝖺𝗀𝖾', callback_data=f'setgs#welcome#{settings["welcome"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["welcome"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#welcome#{settings["welcome"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖠𝗎𝗍𝗈 𝖣𝖾𝗅𝖾𝗍𝖾',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{str(grp_id)}'),
InlineKeyboardButton('5 𝖬𝗂𝗇' if settings["auto_delete"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖠𝗎𝗍𝗈-𝖥𝗂𝗅𝗍𝖾𝗋',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["auto_ffilter"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖬𝖺𝗑 𝖡𝗎𝗍𝗍𝗈𝗇𝗌',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{str(grp_id)}'),
InlineKeyboardButton('10' if settings["max_btn"] else f'{MAX_B_TN}',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{str(grp_id)}')
]
]
reply_markup = InlineKeyboardMarkup(buttons)
await query.message.edit_text(
text=f"𝖢𝗁𝖺𝗇𝗀𝖾 𝖸𝗈𝗎𝗋 𝖲𝖾𝗍𝗍𝗂𝗇𝗀𝗌 𝖥𝗈𝗋 {title} 𝖠𝗌 𝖸𝗈𝗎𝗋 𝖶𝗂𝗌𝗁",
disable_web_page_preview=True,
parse_mode=enums.ParseMode.HTML
)
await query.message.edit_reply_markup(reply_markup)
elif query.data.startswith("opnsetpm"):
ident, grp_id = query.data.split("#")
userid = query.from_user.id if query.from_user else None
st = await client.get_chat_member(grp_id, userid)
if (
st.status != enums.ChatMemberStatus.ADMINISTRATOR
and st.status != enums.ChatMemberStatus.OWNER
and str(userid) not in ADMINS
):
await query.answer("𝖸𝗈𝗎 𝖽𝗈𝗇'𝗍 𝗁𝖺𝗏𝖾 𝗋𝗂𝗀𝗁𝗍𝗌 𝗍𝗈 𝖽𝗈 𝗍𝗁𝗂𝗌 !", show_alert=True)
return
title = query.message.chat.title
settings = await get_settings(grp_id)
btn2 = [[
InlineKeyboardButton("➡ 𝖮𝗉𝖾𝗇 𝗂𝗇 𝖯𝖬 ➡", url=f"t.me/{temp.U_NAME}")
]]
reply_markup = InlineKeyboardMarkup(btn2)
await query.message.edit_text(f"𝖸𝗈𝗎𝗋 𝗌𝖾𝗍𝗍𝗂𝗇𝗀𝗌 𝗆𝖾𝗇𝗎 𝖿𝗈𝗋 {title} 𝗁𝖺𝗌 𝖻𝖾𝖾𝗇 𝗌𝖾𝗇𝗍 𝗍𝗈 𝗒𝗈𝗎𝗋 𝖯𝖬")
await query.message.edit_reply_markup(reply_markup)
if settings is not None:
buttons = [
[
InlineKeyboardButton('𝖥𝗂𝗅𝗍𝖾𝗋 𝖡𝗎𝗍𝗍𝗈𝗇',
callback_data=f'setgs#button#{settings["button"]}#{str(grp_id)}'),
InlineKeyboardButton('𝖲𝗂𝗇𝗀𝗅𝖾 𝖡𝗎𝗍𝗍𝗈𝗇' if settings["button"] else '𝖣𝗈𝗎𝖻𝗅𝖾',
callback_data=f'setgs#button#{settings["button"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖥𝗂𝗅𝖾 𝖲𝖾𝗇𝖽 𝖬𝗈𝖽𝖾', callback_data=f'setgs#botpm#{settings["botpm"]}#{str(grp_id)}'),
InlineKeyboardButton('𝖬𝖺𝗇𝗎𝖺𝗅 𝖲𝗍𝖺𝗋𝗍' if settings["botpm"] else '𝖠𝗎𝗍𝗈 𝖲𝖾𝗇𝖽',
callback_data=f'setgs#botpm#{settings["botpm"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖯𝗋𝗈𝗍𝖾𝖼𝗍 𝖢𝗈𝗇𝗍𝖾𝗇𝗍',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["file_secure"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#file_secure#{settings["file_secure"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖨𝖬𝖣𝖻', callback_data=f'setgs#imdb#{settings["imdb"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["imdb"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#imdb#{settings["imdb"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖲𝗉𝖾𝗅𝗅 𝖢𝗁𝖾𝖼𝗄',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["spell_check"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#spell_check#{settings["spell_check"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖶𝖾𝗅𝖼𝗈𝗆𝖾 𝖬𝖾𝗌𝗌𝖺𝗀𝖾', callback_data=f'setgs#welcome#{settings["welcome"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["welcome"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#welcome#{settings["welcome"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖠𝗎𝗍𝗈 𝖣𝖾𝗅𝖾𝗍𝖾',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{str(grp_id)}'),
InlineKeyboardButton('5 𝖬𝗂𝗇' if settings["auto_delete"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_delete#{settings["auto_delete"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖠𝗎𝗍𝗈-𝖥𝗂𝗅𝗍𝖾𝗋',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{str(grp_id)}'),
InlineKeyboardButton('✅ 𝖮𝗇' if settings["auto_ffilter"] else '❌ 𝖮𝖿𝖿',
callback_data=f'setgs#auto_ffilter#{settings["auto_ffilter"]}#{str(grp_id)}')
],
[
InlineKeyboardButton('𝖬𝖺𝗑 𝖡𝗎𝗍𝗍𝗈𝗇𝗌',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{str(grp_id)}'),
InlineKeyboardButton('10' if settings["max_btn"] else f'{MAX_B_TN}',
callback_data=f'setgs#max_btn#{settings["max_btn"]}#{str(grp_id)}')
]
]
reply_markup = InlineKeyboardMarkup(buttons)
await client.send_message(
chat_id=userid,
text=f"𝖢𝗁𝖺𝗇𝗀𝖾 𝖸𝗈𝗎𝗋 𝖲𝖾𝗍𝗍𝗂𝗇𝗀𝗌 𝖥𝗈𝗋 {title} 𝖠𝗌 𝖸𝗈𝗎𝗋 𝖶𝗂𝗌𝗁",
reply_markup=reply_markup,
disable_web_page_preview=True,
parse_mode=enums.ParseMode.HTML,
reply_to_message_id=query.message.id
)
elif query.data.startswith("show_option"):
ident, from_user = query.data.split("#")
btn = [[
InlineKeyboardButton("⚠ 𝖴𝗇𝖺𝗏𝖺𝗂𝖺𝗅𝖺𝖻𝗅𝖾 ⚠", callback_data=f"unavailable#{from_user}"),
InlineKeyboardButton("✅ 𝖴𝗉𝗅𝗈𝖺𝖽𝖾𝖽 ✅", callback_data=f"uploaded#{from_user}")
],[
InlineKeyboardButton("🔰 𝖠𝗅𝗋𝖾𝖺𝖽𝗒 𝖠𝗏𝖺𝗂𝗅𝖺𝖻𝗅𝖾 🔰", callback_data=f"already_available#{from_user}")
]]
btn2 = [[
InlineKeyboardButton("❕ 𝖵𝗂𝖾𝗐 𝖲𝗍𝖺𝗍𝗎𝗌 ❕", url=f"{query.message.link}")
]]
if query.from_user.id in ADMINS:
user = await client.get_users(from_user)
reply_markup = InlineKeyboardMarkup(btn)
await query.message.edit_reply_markup(reply_markup)
await query.answer("𝖧𝖾𝗋𝖾 𝖺𝗋𝖾 𝗍𝗁𝖾 𝗈𝗉𝗍𝗂𝗈𝗇𝗌")
else:
await query.answer("𝖸𝗈𝗎 𝖽𝗈𝗇'𝗍 𝗁𝖺𝗏𝖾 𝗌𝗎𝖿𝖿𝗂𝖼𝗂𝖾𝗇𝗍 𝗋𝗂𝗀𝗁𝗍𝗌 𝗍𝗈 𝖽𝗈 𝗍𝗁𝗂𝗌 !", show_alert=True)
elif query.data.startswith("unavailable"):
ident, from_user = query.data.split("#")
btn = [[
InlineKeyboardButton("⚠ 𝖴𝗇𝖺𝗏𝖺𝗂𝖺𝗅𝖺𝖻𝗅𝖾 ⚠", callback_data=f"unalert#{from_user}")
]]
btn2 = [[
InlineKeyboardButton("❕ 𝖵𝗂𝖾𝗐 𝖲𝗍𝖺𝗍𝗎𝗌 ❕", url=f"{query.message.link}")
]]
if query.from_user.id in ADMINS:
user = await client.get_users(from_user)
reply_markup = InlineKeyboardMarkup(btn)
content = query.message.text
await query.message.edit_text(f"