mirror of
https://github.com/MuRuLOSE/limoka.git
synced 2026-06-16 14:34:17 +02:00
Commited backup
This commit is contained in:
8
MoriSummerz/ftg-mods/.deepsource.toml
Normal file
8
MoriSummerz/ftg-mods/.deepsource.toml
Normal file
@@ -0,0 +1,8 @@
|
||||
version = 1
|
||||
|
||||
[[analyzers]]
|
||||
name = "python"
|
||||
enabled = true
|
||||
|
||||
[analyzers.meta]
|
||||
runtime_version = "3.x.x"
|
||||
437
MoriSummerz/ftg-mods/LICENSE
Normal file
437
MoriSummerz/ftg-mods/LICENSE
Normal file
@@ -0,0 +1,437 @@
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||
does not provide legal services or legal advice. Distribution of
|
||||
Creative Commons public licenses does not create a lawyer-client or
|
||||
other relationship. Creative Commons makes its licenses and related
|
||||
information available on an "as-is" basis. Creative Commons gives no
|
||||
warranties regarding its licenses, any material licensed under their
|
||||
terms and conditions, or any related information. Creative Commons
|
||||
disclaims all liability for damages resulting from their use to the
|
||||
fullest extent possible.
|
||||
|
||||
Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and
|
||||
conditions that creators and other rights holders may use to share
|
||||
original works of authorship and other material subject to copyright
|
||||
and certain other rights specified in the public license below. The
|
||||
following considerations are for informational purposes only, are not
|
||||
exhaustive, and do not form part of our licenses.
|
||||
|
||||
Considerations for licensors: Our public licenses are
|
||||
intended for use by those authorized to give the public
|
||||
permission to use material in ways otherwise restricted by
|
||||
copyright and certain other rights. Our licenses are
|
||||
irrevocable. Licensors should read and understand the terms
|
||||
and conditions of the license they choose before applying it.
|
||||
Licensors should also secure all rights necessary before
|
||||
applying our licenses so that the public can reuse the
|
||||
material as expected. Licensors should clearly mark any
|
||||
material not subject to the license. This includes other CC-
|
||||
licensed material, or material used under an exception or
|
||||
limitation to copyright. More considerations for licensors:
|
||||
wiki.creativecommons.org/Considerations_for_licensors
|
||||
|
||||
Considerations for the public: By using one of our public
|
||||
licenses, a licensor grants the public permission to use the
|
||||
licensed material under specified terms and conditions. If
|
||||
the licensor's permission is not necessary for any reason--for
|
||||
example, because of any applicable exception or limitation to
|
||||
copyright--then that use is not regulated by the license. Our
|
||||
licenses grant only permissions under copyright and certain
|
||||
other rights that a licensor has authority to grant. Use of
|
||||
the licensed material may still be restricted for other
|
||||
reasons, including because others have copyright or other
|
||||
rights in the material. A licensor may make special requests,
|
||||
such as asking that all changes be marked or described.
|
||||
Although not required by our licenses, you are encouraged to
|
||||
respect those requests where reasonable. More considerations
|
||||
for the public:
|
||||
wiki.creativecommons.org/Considerations_for_licensees
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree
|
||||
to be bound by the terms and conditions of this Creative Commons
|
||||
Attribution-NonCommercial-ShareAlike 4.0 International Public License
|
||||
("Public License"). To the extent this Public License may be
|
||||
interpreted as a contract, You are granted the Licensed Rights in
|
||||
consideration of Your acceptance of these terms and conditions, and the
|
||||
Licensor grants You such rights in consideration of benefits the
|
||||
Licensor receives from making the Licensed Material available under
|
||||
these terms and conditions.
|
||||
|
||||
|
||||
Section 1 -- Definitions.
|
||||
|
||||
a. Adapted Material means material subject to Copyright and Similar
|
||||
Rights that is derived from or based upon the Licensed Material
|
||||
and in which the Licensed Material is translated, altered,
|
||||
arranged, transformed, or otherwise modified in a manner requiring
|
||||
permission under the Copyright and Similar Rights held by the
|
||||
Licensor. For purposes of this Public License, where the Licensed
|
||||
Material is a musical work, performance, or sound recording,
|
||||
Adapted Material is always produced where the Licensed Material is
|
||||
synched in timed relation with a moving image.
|
||||
|
||||
b. Adapter's License means the license You apply to Your Copyright
|
||||
and Similar Rights in Your contributions to Adapted Material in
|
||||
accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. BY-NC-SA Compatible License means a license listed at
|
||||
creativecommons.org/compatiblelicenses, approved by Creative
|
||||
Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||
closely related to copyright including, without limitation,
|
||||
performance, broadcast, sound recording, and Sui Generis Database
|
||||
Rights, without regard to how the rights are labeled or
|
||||
categorized. For purposes of this Public License, the rights
|
||||
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||
Rights.
|
||||
|
||||
e. Effective Technological Measures means those measures that, in the
|
||||
absence of proper authority, may not be circumvented under laws
|
||||
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||
Treaty adopted on December 20, 1996, and/or similar international
|
||||
agreements.
|
||||
|
||||
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||
any other exception or limitation to Copyright and Similar Rights
|
||||
that applies to Your use of the Licensed Material.
|
||||
|
||||
g. License Elements means the license attributes listed in the name
|
||||
of a Creative Commons Public License. The License Elements of this
|
||||
Public License are Attribution, NonCommercial, and ShareAlike.
|
||||
|
||||
h. Licensed Material means the artistic or literary work, database,
|
||||
or other material to which the Licensor applied this Public
|
||||
License.
|
||||
|
||||
i. Licensed Rights means the rights granted to You subject to the
|
||||
terms and conditions of this Public License, which are limited to
|
||||
all Copyright and Similar Rights that apply to Your use of the
|
||||
Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||
under this Public License.
|
||||
|
||||
k. NonCommercial means not primarily intended for or directed towards
|
||||
commercial advantage or monetary compensation. For purposes of
|
||||
this Public License, the exchange of the Licensed Material for
|
||||
other material subject to Copyright and Similar Rights by digital
|
||||
file-sharing or similar means is NonCommercial provided there is
|
||||
no payment of monetary compensation in connection with the
|
||||
exchange.
|
||||
|
||||
l. Share means to provide material to the public by any means or
|
||||
process that requires permission under the Licensed Rights, such
|
||||
as reproduction, public display, public performance, distribution,
|
||||
dissemination, communication, or importation, and to make material
|
||||
available to the public including in ways that members of the
|
||||
public may access the material from a place and at a time
|
||||
individually chosen by them.
|
||||
|
||||
m. Sui Generis Database Rights means rights other than copyright
|
||||
resulting from Directive 96/9/EC of the European Parliament and of
|
||||
the Council of 11 March 1996 on the legal protection of databases,
|
||||
as amended and/or succeeded, as well as other essentially
|
||||
equivalent rights anywhere in the world.
|
||||
|
||||
n. You means the individual or entity exercising the Licensed Rights
|
||||
under this Public License. Your has a corresponding meaning.
|
||||
|
||||
|
||||
Section 2 -- Scope.
|
||||
|
||||
a. License grant.
|
||||
|
||||
1. Subject to the terms and conditions of this Public License,
|
||||
the Licensor hereby grants You a worldwide, royalty-free,
|
||||
non-sublicensable, non-exclusive, irrevocable license to
|
||||
exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
a. reproduce and Share the Licensed Material, in whole or
|
||||
in part, for NonCommercial purposes only; and
|
||||
|
||||
b. produce, reproduce, and Share Adapted Material for
|
||||
NonCommercial purposes only.
|
||||
|
||||
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||
Exceptions and Limitations apply to Your use, this Public
|
||||
License does not apply, and You do not need to comply with
|
||||
its terms and conditions.
|
||||
|
||||
3. Term. The term of this Public License is specified in Section
|
||||
6(a).
|
||||
|
||||
4. Media and formats; technical modifications allowed. The
|
||||
Licensor authorizes You to exercise the Licensed Rights in
|
||||
all media and formats whether now known or hereafter created,
|
||||
and to make technical modifications necessary to do so. The
|
||||
Licensor waives and/or agrees not to assert any right or
|
||||
authority to forbid You from making technical modifications
|
||||
necessary to exercise the Licensed Rights, including
|
||||
technical modifications necessary to circumvent Effective
|
||||
Technological Measures. For purposes of this Public License,
|
||||
simply making modifications authorized by this Section 2(a)
|
||||
(4) never produces Adapted Material.
|
||||
|
||||
5. Downstream recipients.
|
||||
|
||||
a. Offer from the Licensor -- Licensed Material. Every
|
||||
recipient of the Licensed Material automatically
|
||||
receives an offer from the Licensor to exercise the
|
||||
Licensed Rights under the terms and conditions of this
|
||||
Public License.
|
||||
|
||||
b. Additional offer from the Licensor -- Adapted Material.
|
||||
Every recipient of Adapted Material from You
|
||||
automatically receives an offer from the Licensor to
|
||||
exercise the Licensed Rights in the Adapted Material
|
||||
under the conditions of the Adapter's License You apply.
|
||||
|
||||
c. No downstream restrictions. You may not offer or impose
|
||||
any additional or different terms or conditions on, or
|
||||
apply any Effective Technological Measures to, the
|
||||
Licensed Material if doing so restricts exercise of the
|
||||
Licensed Rights by any recipient of the Licensed
|
||||
Material.
|
||||
|
||||
6. No endorsement. Nothing in this Public License constitutes or
|
||||
may be construed as permission to assert or imply that You
|
||||
are, or that Your use of the Licensed Material is, connected
|
||||
with, or sponsored, endorsed, or granted official status by,
|
||||
the Licensor or others designated to receive attribution as
|
||||
provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. Other rights.
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not
|
||||
licensed under this Public License, nor are publicity,
|
||||
privacy, and/or other similar personality rights; however, to
|
||||
the extent possible, the Licensor waives and/or agrees not to
|
||||
assert any such rights held by the Licensor to the limited
|
||||
extent necessary to allow You to exercise the Licensed
|
||||
Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this
|
||||
Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to
|
||||
collect royalties from You for the exercise of the Licensed
|
||||
Rights, whether directly or through a collecting society
|
||||
under any voluntary or waivable statutory or compulsory
|
||||
licensing scheme. In all other cases the Licensor expressly
|
||||
reserves any right to collect such royalties, including when
|
||||
the Licensed Material is used other than for NonCommercial
|
||||
purposes.
|
||||
|
||||
|
||||
Section 3 -- License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the
|
||||
following conditions.
|
||||
|
||||
a. Attribution.
|
||||
|
||||
1. If You Share the Licensed Material (including in modified
|
||||
form), You must:
|
||||
|
||||
a. retain the following if it is supplied by the Licensor
|
||||
with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed
|
||||
Material and any others designated to receive
|
||||
attribution, in any reasonable manner requested by
|
||||
the Licensor (including by pseudonym if
|
||||
designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of
|
||||
warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the
|
||||
extent reasonably practicable;
|
||||
|
||||
b. indicate if You modified the Licensed Material and
|
||||
retain an indication of any previous modifications; and
|
||||
|
||||
c. indicate the Licensed Material is licensed under this
|
||||
Public License, and include the text of, or the URI or
|
||||
hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||
reasonable manner based on the medium, means, and context in
|
||||
which You Share the Licensed Material. For example, it may be
|
||||
reasonable to satisfy the conditions by providing a URI or
|
||||
hyperlink to a resource that includes the required
|
||||
information.
|
||||
3. If requested by the Licensor, You must remove any of the
|
||||
information required by Section 3(a)(1)(A) to the extent
|
||||
reasonably practicable.
|
||||
|
||||
b. ShareAlike.
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share
|
||||
Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter's License You apply must be a Creative Commons
|
||||
license with the same License Elements, this version or
|
||||
later, or a BY-NC-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the
|
||||
Adapter's License You apply. You may satisfy this condition
|
||||
in any reasonable manner based on the medium, means, and
|
||||
context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms
|
||||
or conditions on, or apply any Effective Technological
|
||||
Measures to, Adapted Material that restrict exercise of the
|
||||
rights granted under the Adapter's License You apply.
|
||||
|
||||
|
||||
Section 4 -- Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that
|
||||
apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||
to extract, reuse, reproduce, and Share all or a substantial
|
||||
portion of the contents of the database for NonCommercial purposes
|
||||
only;
|
||||
|
||||
b. if You include all or a substantial portion of the database
|
||||
contents in a database in which You have Sui Generis Database
|
||||
Rights, then the database in which You have Sui Generis Database
|
||||
Rights (but not its individual contents) is Adapted Material,
|
||||
including for purposes of Section 3(b); and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share
|
||||
all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not
|
||||
replace Your obligations under this Public License where the Licensed
|
||||
Rights include other Copyright and Similar Rights.
|
||||
|
||||
|
||||
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||
|
||||
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided
|
||||
above shall be interpreted in a manner that, to the extent
|
||||
possible, most closely approximates an absolute disclaimer and
|
||||
waiver of all liability.
|
||||
|
||||
|
||||
Section 6 -- Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and
|
||||
Similar Rights licensed here. However, if You fail to comply with
|
||||
this Public License, then Your rights under this Public License
|
||||
terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under
|
||||
Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided
|
||||
it is cured within 30 days of Your discovery of the
|
||||
violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||
right the Licensor may have to seek remedies for Your violations
|
||||
of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the
|
||||
Licensed Material under separate terms or conditions or stop
|
||||
distributing the Licensed Material at any time; however, doing so
|
||||
will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||
License.
|
||||
|
||||
|
||||
Section 7 -- Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different
|
||||
terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the
|
||||
Licensed Material not stated herein are separate from and
|
||||
independent of the terms and conditions of this Public License.
|
||||
|
||||
|
||||
Section 8 -- Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and
|
||||
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||
conditions on any use of the Licensed Material that could lawfully
|
||||
be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is
|
||||
deemed unenforceable, it shall be automatically reformed to the
|
||||
minimum extent necessary to make it enforceable. If the provision
|
||||
cannot be reformed, it shall be severed from this Public License
|
||||
without affecting the enforceability of the remaining terms and
|
||||
conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no
|
||||
failure to comply consented to unless expressly agreed to by the
|
||||
Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted
|
||||
as a limitation upon, or waiver of, any privileges and immunities
|
||||
that apply to the Licensor or You, including from the legal
|
||||
processes of any jurisdiction or authority.
|
||||
|
||||
=======================================================================
|
||||
|
||||
Creative Commons is not a party to its public
|
||||
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||
its public licenses to material it publishes and in those instances
|
||||
will be considered the “Licensor.” The text of the Creative Commons
|
||||
public licenses is dedicated to the public domain under the CC0 Public
|
||||
Domain Dedication. Except for the limited purpose of indicating that
|
||||
material is shared under a Creative Commons public license or as
|
||||
otherwise permitted by the Creative Commons policies published at
|
||||
creativecommons.org/policies, Creative Commons does not authorize the
|
||||
use of the trademark "Creative Commons" or any other trademark or logo
|
||||
of Creative Commons without its prior written consent including,
|
||||
without limitation, in connection with any unauthorized modifications
|
||||
to any of its public licenses or any other arrangements,
|
||||
understandings, or agreements concerning use of licensed material. For
|
||||
the avoidance of doubt, this paragraph does not form part of the
|
||||
public licenses.
|
||||
|
||||
Creative Commons may be contacted at creativecommons.org.
|
||||
3
MoriSummerz/ftg-mods/README.md
Normal file
3
MoriSummerz/ftg-mods/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Userbot modules
|
||||

|
||||
Description of mods and installation is available in my [Telegram channel](https://t.me/morisummermods)
|
||||
52
MoriSummerz/ftg-mods/TimeBot.py
Normal file
52
MoriSummerz/ftg-mods/TimeBot.py
Normal file
@@ -0,0 +1,52 @@
|
||||
__version__ = (1, 0, 1)
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
|
||||
from asyncio import sleep
|
||||
|
||||
from .. import loader, utils
|
||||
|
||||
|
||||
class TimerBotMod(loader.Module):
|
||||
strings = {"name": "TimeBot"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
|
||||
async def timebcmd(self, message):
|
||||
"""Пример ввода: .timeb <задержка появления текста в минутах> <текст>"""
|
||||
args = utils.get_args(message)
|
||||
if not args:
|
||||
self.db.set(self.strings["name"], "state", False)
|
||||
await utils.answer(message, "<b>Модуль TimeBot остановлен!</b>")
|
||||
return
|
||||
|
||||
await utils.answer(
|
||||
message,
|
||||
(
|
||||
"<b>Модуль TimeBot запущен!\n\n"
|
||||
"Чтобы его остановить, используй <code>.timeb</code></b>"
|
||||
),
|
||||
)
|
||||
|
||||
try:
|
||||
time = float(args[0]) * 60
|
||||
except ValueError:
|
||||
await utils.answer(message, "<b>Введите корректную задержку!</b>")
|
||||
return
|
||||
|
||||
text = " ".join(utils.get_args_raw(message).split()[1:])
|
||||
self.db.set(self.strings["name"], "state", True)
|
||||
|
||||
while self.db.get(self.strings["name"], "state"):
|
||||
await message.respond(text)
|
||||
await sleep(0.1)
|
||||
await sleep(time)
|
||||
343
MoriSummerz/ftg-mods/airalert.py
Normal file
343
MoriSummerz/ftg-mods/airalert.py
Normal file
@@ -0,0 +1,343 @@
|
||||
__version__ = (1, 1, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# scope: inline_content
|
||||
# meta developer: @morisummermods
|
||||
# meta banner: https://i.imgur.com/V0Qhyi0.jpg
|
||||
# meta pic: https://i.imgur.com/AwKGCQe.png
|
||||
|
||||
import logging
|
||||
from asyncio import sleep
|
||||
|
||||
from aiogram.types import InlineQueryResultArticle, InputTextMessageContent
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
from telethon.utils import get_display_name
|
||||
|
||||
from .. import loader, utils
|
||||
from ..inline import GeekInlineQuery, rand
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ua = [
|
||||
"all",
|
||||
"Кіровоградська_область",
|
||||
"Попаснянська_територіальна_громада",
|
||||
"Бердянський_район",
|
||||
"Полтавська_область",
|
||||
"м_Краматорськ_та_Краматорська_територіальна_громада",
|
||||
"м_Старокостянтинів_та_Старокостянтинівська_територіальна_громада",
|
||||
"Ізюмський_район",
|
||||
"Покровська_територіальна_громада",
|
||||
"Волноваський_район",
|
||||
"Краматорський_район",
|
||||
"Київська_область",
|
||||
"м_Київ",
|
||||
"Херсонська_область",
|
||||
"Ніжинський_район",
|
||||
"Бахмутська_територіальна_громада",
|
||||
"м_Кремінна_та_Кремінська_територіальна_громада",
|
||||
"Рівненська_область",
|
||||
"Запорізька_область",
|
||||
"м_Маріуполь_та_Маріупольська_територіальна_громада",
|
||||
"м_Рівне_та_Рівненська_територіальна_громада",
|
||||
"м_Черкаси_та_Черкаська_територіальна_громада",
|
||||
"Марїнська_територіальна_громада",
|
||||
"Сквирська_територіальна_громада",
|
||||
"Охтирський_район",
|
||||
"м_Конотоп_та_Конотопська_територіальна_громада",
|
||||
"Вознесенський_район",
|
||||
"Сарненський_район",
|
||||
"Миколаївський_район",
|
||||
"Смілянська_територіальна_громада",
|
||||
"Сєвєродонецький_район",
|
||||
"Гірська_територіальна_громада",
|
||||
"Костянтинівська_територіальна_громада",
|
||||
"Прилуцький_район",
|
||||
"м_Пирятин_та_Пирятинська_територіальна_громада",
|
||||
"Вишгородська_територіальна_громада",
|
||||
"Воскресенська_територіальна_громада",
|
||||
"м_Переяслав_та_Переяславська_територіальна_громада",
|
||||
"м_Полтава_та_Полтавська_територіальна_громада",
|
||||
"м_Вознесенськ_та_Вознесенська_територіальна_громада",
|
||||
"Дружківська_територіальна_громада",
|
||||
"Золотоніський_район",
|
||||
"Макарівська_територіальна_громада",
|
||||
"Дубровицька_територіальна_громада",
|
||||
"Хмельницька_область",
|
||||
"Великоновосілківська_територіальна_громада",
|
||||
"м_Шостка_та_Шосткинська_територіальна_громада",
|
||||
"Львівська_область",
|
||||
"Волинська_область",
|
||||
"Первомайський_район",
|
||||
"м_Запоріжжя_та_Запорізька_територіальна_громада",
|
||||
"м_Бровари_та_Броварська_територіальна_громада",
|
||||
"Лиманська_територіальна_громада",
|
||||
"м_Лисичанськ_та_Лисичанська_територіальна_громада",
|
||||
"м_Бориспіль_та_Бориспільська_територіальна_громада",
|
||||
"м_Обухів_та_Обухівська_територіальна_громада",
|
||||
"Звенигородський_район",
|
||||
"Роздільнянський_район",
|
||||
"м_Нікополь_та_Нікопольська_територіальна_громада",
|
||||
"м_Першотравенськ_та_Першотравенська_територіальна_громада",
|
||||
"м_Васильків_та_Васильківська_територіальна_громада",
|
||||
"Кропивницький_район",
|
||||
"Шепетівський_район",
|
||||
"Житомирська_область",
|
||||
"Вараський_район",
|
||||
"Болградський_район",
|
||||
"Закарпатська_область",
|
||||
"Шосткинський_район",
|
||||
"Гребінківська_територіальна_громада",
|
||||
"Чернівецька_область",
|
||||
"Синельниківський_район",
|
||||
"Уманська_територіальна_громада",
|
||||
"Олешківська_територіальна_громада",
|
||||
"м_Кременчук_та_Кременчуцька_територіальна_громада",
|
||||
"Коростенський_район",
|
||||
"Купянський_район",
|
||||
"Подільський_район",
|
||||
"м_Мелітополь_та_Мелітопольська_територіальна_громада",
|
||||
"Ізмаїльський_район",
|
||||
"Вінницька_область",
|
||||
"м_Славутич_та_Славутицька_територіальна_громада",
|
||||
"Бородянська_територіальна_громада",
|
||||
"Святогірська_територіальна_громада",
|
||||
"Добропільська_територіальна_громада",
|
||||
"Черкаський_район",
|
||||
"Пологівський_район",
|
||||
"м_Сарни_та_Сарненська_територіальна_громада",
|
||||
"Маріупольський_район",
|
||||
"Лозівський_район",
|
||||
"Березівський_район",
|
||||
"Українська_територіальна_громада",
|
||||
"м_Охтирка_та_Охтирська_територіальна_громада",
|
||||
"Жашківська_територіальна_громада",
|
||||
"Житомирський_район",
|
||||
"Донецький_район",
|
||||
"м_Кривий_Ріг_та_Криворізька_територіальна_громада",
|
||||
"Радомишльська_територіальна_громада",
|
||||
"м_Дніпро_та_Дніпровська_територіальна_громада",
|
||||
"м_Миколаїв_та_Миколаївська_територіальна_громада",
|
||||
"Гостомелська_територіальна_громада",
|
||||
"м_Миргород_та_Миргородська_територіальна_громада",
|
||||
"Сумська_область",
|
||||
"Торецька_територіальна_громада",
|
||||
"м_Ватутіне_та_Ватутінська_територіальна_громада",
|
||||
"м_Коростень_та_Коростенська_територіальна_громада",
|
||||
"Харківський_район",
|
||||
"Уманський_район",
|
||||
"Сумський_район",
|
||||
"Одеський_район",
|
||||
"БілгородДністровський_район",
|
||||
"Тернопільська_область",
|
||||
"Первомайська_територіальна_громада",
|
||||
"м_Первомайськ_та_Первомайська_територіальна_громада",
|
||||
"Чугуївський_район",
|
||||
"м_Фастів_та_Фастівська_територіальна_громада",
|
||||
"Миронівська_територіальна_громада",
|
||||
"м_Лубни_та_Лубенська_територіальна_громада",
|
||||
"Черкаська_область",
|
||||
"Луганська_область",
|
||||
"м_Житомир_та_Житомирська_територіальна_громада",
|
||||
"Новоукраїнський_район",
|
||||
"м_Словянськ_та_Словянська_територіальна_громада",
|
||||
"Чернігівський_район",
|
||||
"м_Очаків_та_Очаківська_територіальна_громада",
|
||||
"Вугледарська_територіальна_громада",
|
||||
"м_Сєвєродонецьк_та_Сєвєродонецька_територіальна_громада",
|
||||
"Дніпропетровська_область",
|
||||
"Запорізький_район",
|
||||
"Широківська_територіальна_громада",
|
||||
"Узинська_територіальна_громада",
|
||||
"Миколаївська_область",
|
||||
"Харківська_область",
|
||||
"НовоградВолинський_район",
|
||||
"Курахівська_територіальна_громада",
|
||||
"м_Рубіжне_та_Рубіжанська_територіальна_громада",
|
||||
"Донецька_область",
|
||||
"м_Суми_та_Сумська_територіальна_громада",
|
||||
"м_Біла_Церква_та_Білоцерківська_територіальна_громада",
|
||||
"Голованівський_район",
|
||||
"Одеська_область",
|
||||
"Павлоградський_район",
|
||||
"Чернігівська_область",
|
||||
"Сватівський_район",
|
||||
"ІваноФранківська_область",
|
||||
"Покровський_район",
|
||||
"Бахмутський_район",
|
||||
]
|
||||
|
||||
|
||||
class AirAlertMod(loader.Module):
|
||||
"""🇺🇦 Предупреждение о воздушной тревоге.
|
||||
Нужно быть подписаным на @air_alert_ua и включены уведомления в вашем боте"""
|
||||
|
||||
strings = {"name": "AirAlert"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
self.regions = db.get(self.strings["name"], "regions", [])
|
||||
self.nametag = db.get(self.strings["name"], "nametag", "")
|
||||
self.forwards = db.get(self.strings["name"], "forwards", [])
|
||||
|
||||
if hasattr(self, "hikka"):
|
||||
self.me = self._client.tg_id
|
||||
self.bot_id = self.inline.bot_id
|
||||
await self.request_join(
|
||||
"@air_alert_ua", "Required by AirAlert", assure_joined=True
|
||||
)
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
self.bot_id = (await self.inline.bot.get_me()).id
|
||||
self.me = (await client.get_me()).id
|
||||
try:
|
||||
await client(
|
||||
JoinChannelRequest(await self.client.get_entity("t.me/air_alert_ua"))
|
||||
)
|
||||
except Exception:
|
||||
logger.error("Can't join t.me/air_alert_ua")
|
||||
try:
|
||||
channel = await self.client.get_entity("t.me/morisummermods")
|
||||
await client(JoinChannelRequest(channel))
|
||||
except Exception:
|
||||
logger.error("Can't join morisummermods")
|
||||
try:
|
||||
post = (await client.get_messages("@morisummermods", ids=[15]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.error("Can't react to t.me/morisummermods")
|
||||
|
||||
async def alertforwardcmd(self, message: Message) -> None:
|
||||
"""Перенаправление предупреждений в другие чаты.
|
||||
Для добавления/удаления введите команду с ссылкой на чат.
|
||||
Для просмотра чатов введите команду без аргументов
|
||||
Для установки кастомной таблички введите .alertforward set <text>"""
|
||||
text = utils.get_args_raw(message)
|
||||
if text[:3] == "set":
|
||||
self.nametag = text[4:]
|
||||
self.db.set(self.strings["name"], "nametag", self.nametag)
|
||||
return await utils.answer(
|
||||
message,
|
||||
f"🏷 <b>Табличка успешно установлена: <code>{self.nametag}</code></b>",
|
||||
)
|
||||
if not text:
|
||||
chats = "<b>Текущие чаты для перенаправления: </b>\n"
|
||||
for chat in self.forwards:
|
||||
chats += f"{get_display_name(await self.client.get_entity(chat))}\n"
|
||||
await utils.answer(message, chats)
|
||||
return
|
||||
try:
|
||||
chat = (await self.client.get_entity(text.replace("https://", ""))).id
|
||||
except Exception:
|
||||
await utils.answer(message, "<b>Чат не найден</b>")
|
||||
return
|
||||
if chat in self.forwards:
|
||||
self.forwards.remove(chat)
|
||||
self.db.set(self.strings["name"], "forwards", self.forwards)
|
||||
await utils.answer(message, "<b>Чат успешно удален для перенаправления</b>")
|
||||
else:
|
||||
self.forwards.append(chat)
|
||||
self.db.set(self.strings["name"], "forwards", self.forwards)
|
||||
await utils.answer(
|
||||
message, "<b>Чат успешно установлен для перенаправления</b>"
|
||||
)
|
||||
|
||||
async def alert_inline_handler(self, query: GeekInlineQuery) -> None:
|
||||
"""Выбор регионов.
|
||||
Чтобы получать все предупреждения введите alert all.
|
||||
Чтобы посмотреть ваши регионы alert my"""
|
||||
text = query.args
|
||||
if not text:
|
||||
result = ua
|
||||
elif text == "my":
|
||||
result = self.regions
|
||||
else:
|
||||
result = [region for region in ua if text.lower() in region.lower()]
|
||||
if not result:
|
||||
await query.e404()
|
||||
return
|
||||
res = [
|
||||
InlineQueryResultArticle(
|
||||
id=rand(20),
|
||||
title=(
|
||||
f"{'✅' if reg in self.regions else '❌'}{reg if reg != 'all' else 'Все уведомления'}"
|
||||
),
|
||||
description=(
|
||||
f"Нажмите чтобы {'удалить' if reg in self.regions else 'добавить'}"
|
||||
if reg != "all"
|
||||
else (
|
||||
"🇺🇦 Нажмите чтобы"
|
||||
f" {'выключить' if 'all' in self.regions else 'включить'} все"
|
||||
" уведомления"
|
||||
)
|
||||
),
|
||||
input_message_content=InputTextMessageContent(
|
||||
f"⌛ Редактирование региона <code>{reg}</code>",
|
||||
parse_mode="HTML",
|
||||
),
|
||||
)
|
||||
for reg in result[:50]
|
||||
]
|
||||
await query.answer(res, cache_time=0)
|
||||
|
||||
async def watcher(self, message: Message) -> None:
|
||||
if (
|
||||
getattr(message, "out", False)
|
||||
and getattr(message, "via_bot_id", False)
|
||||
and message.via_bot_id == self.bot_id
|
||||
and "⌛ Редактирование региона" in getattr(message, "raw_text", "")
|
||||
):
|
||||
self.regions = self.db.get(self.strings["name"], "regions", [])
|
||||
region = message.raw_text[25:]
|
||||
state = "добавлен"
|
||||
if region not in self.regions:
|
||||
self.regions.append(region)
|
||||
else:
|
||||
self.regions.remove(region)
|
||||
state = "удален"
|
||||
self.db.set(self.strings["name"], "regions", self.regions)
|
||||
try:
|
||||
e = await self.client.get_entity("t.me/air_alert_ua")
|
||||
sub = not e.left
|
||||
except Exception:
|
||||
sub = False
|
||||
n = "\n"
|
||||
res = f"<b>Регион <code>{region}</code> успешно {state}</b>{n}"
|
||||
if not sub:
|
||||
res += (
|
||||
"<b>НЕ ВЫХОДИ С @air_alert_ua (иначе ничего работать не будет)</b>"
|
||||
)
|
||||
if not hasattr(self, "hikka"):
|
||||
await self.client(
|
||||
JoinChannelRequest(
|
||||
await self.client.get_entity("t.me/air_alert_ua")
|
||||
)
|
||||
)
|
||||
await self.inline.form(res, message=message)
|
||||
if (
|
||||
getattr(message, "peer_id", False)
|
||||
and getattr(message.peer_id, "channel_id", 0) == 1766138888
|
||||
and (
|
||||
"all" in self.regions
|
||||
or any(reg in message.raw_text for reg in self.regions)
|
||||
)
|
||||
):
|
||||
for _ in range(3):
|
||||
await self.inline.bot.send_message(
|
||||
self.me,
|
||||
message.text,
|
||||
parse_mode="HTML",
|
||||
)
|
||||
await sleep(1)
|
||||
for chat in self.forwards:
|
||||
await self.client.send_message(
|
||||
chat,
|
||||
message.text + "\n\n" + self.nametag,
|
||||
)
|
||||
278
MoriSummerz/ftg-mods/chatgpt.py
Normal file
278
MoriSummerz/ftg-mods/chatgpt.py
Normal file
@@ -0,0 +1,278 @@
|
||||
__version__ = (1, 0, 0)
|
||||
|
||||
import contextlib
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# meta developer: @morisummermods
|
||||
# meta banner: https://i.imgur.com/H1vPM6U.jpg
|
||||
|
||||
from telethon.tl.types import Message
|
||||
import requests
|
||||
import logging
|
||||
import re
|
||||
|
||||
from .. import loader, utils # noqa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@loader.tds
|
||||
class ChatGPT(loader.Module):
|
||||
"""ChatGPT AI API interaction"""
|
||||
|
||||
strings = {
|
||||
"name": "ChatGPT",
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>No arguments"
|
||||
" provided</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Question:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Answer:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Loading...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 No API key provided</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Get it from official OpenAI"
|
||||
" website and add it to config</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_ru = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Не указаны"
|
||||
" аргументы</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Вопрос:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Ответ:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Загрузка...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 Не указан API ключ</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Получите его на официальном"
|
||||
" сайте OpenAI и добавьте в конфиг</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_es = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>No se han"
|
||||
" proporcionado argumentos</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Pregunta:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Respuesta:</b>"
|
||||
" {answer}"
|
||||
),
|
||||
"loading": "<code>Cargando...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 No se ha proporcionado una clave API</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Obtenga una en el sitio web"
|
||||
" oficial de OpenAI y agréguela a la configuración</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_fr = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Aucun argument"
|
||||
" fourni</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Question:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Réponse:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Chargement...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 Aucune clé API fournie</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Obtenez-en un sur le site"
|
||||
" officiel d'OpenAI et ajoutez-le à la configuration</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_de = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Keine Argumente"
|
||||
" angegeben</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Frage:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Antwort:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Laden...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 Kein API-Schlüssel angegeben</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Holen Sie sich einen auf der"
|
||||
" offiziellen OpenAI-Website und fügen Sie ihn der Konfiguration hinzu</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_tr = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Argümanlar"
|
||||
" verilmedi</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Soru:</b> {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Cevap:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Yükleniyor...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 API anahtarı verilmedi</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> OpenAI'nın resmi websitesinden"
|
||||
" alın ve yapılandırmaya ekleyin</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_uz = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Argumentlar"
|
||||
" ko'rsatilmadi</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Savol:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Javob:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Yuklanmoqda...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 API kalit ko'rsatilmadi</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Ofitsial OpenAI veb-saytidan"
|
||||
" oling</i>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_it = {
|
||||
"no_args": (
|
||||
"<emoji document_id=5312526098750252863>🚫</emoji> <b>Nessun argomento"
|
||||
" fornito</b>"
|
||||
),
|
||||
"question": (
|
||||
"<emoji document_id=5974038293120027938>👤</emoji> <b>Domanda:</b>"
|
||||
" {question}\n"
|
||||
),
|
||||
"answer": (
|
||||
"<emoji document_id=5199682846729449178>🤖</emoji> <b>Risposta:</b> {answer}"
|
||||
),
|
||||
"loading": "<code>Caricamento...</code>",
|
||||
"no_api_key": (
|
||||
"<b>🚫 Nessuna chiave API fornita</b>\n<i><emoji"
|
||||
" document_id=5199682846729449178>ℹ️</emoji> Ottienila dal sito ufficiale"
|
||||
" di OpenAI e aggiungila al tuo file di configurazione</i>"
|
||||
),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.config = loader.ModuleConfig(
|
||||
loader.ConfigValue(
|
||||
"api_key",
|
||||
"",
|
||||
"API key from OpenAI",
|
||||
validator=loader.validators.Hidden(loader.validators.String()),
|
||||
),
|
||||
)
|
||||
|
||||
async def _make_request(
|
||||
self,
|
||||
method: str,
|
||||
url: str,
|
||||
headers: dict,
|
||||
data: dict,
|
||||
) -> dict:
|
||||
resp = await utils.run_sync(
|
||||
requests.request,
|
||||
method,
|
||||
url,
|
||||
headers=headers,
|
||||
json=data,
|
||||
)
|
||||
return resp.json()
|
||||
|
||||
def _process_code_tags(self, text: str) -> str:
|
||||
return re.sub(
|
||||
r"`(.*?)`",
|
||||
r"<code>\1</code>",
|
||||
re.sub(r"```(.*?)```", r"<code>\1</code>", text, flags=re.DOTALL),
|
||||
flags=re.DOTALL,
|
||||
)
|
||||
|
||||
async def _get_chat_completion(self, prompt: str) -> str:
|
||||
resp = await self._make_request(
|
||||
method="POST",
|
||||
url="https://api.openai.com/v1/chat/completions",
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f'Bearer {self.config["api_key"]}',
|
||||
},
|
||||
data={
|
||||
"model": "gpt-3.5-turbo",
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
},
|
||||
)
|
||||
if resp.get("error", None):
|
||||
return f"🚫 {resp['error']['message']}"
|
||||
return resp["choices"][0]["message"]["content"]
|
||||
|
||||
@loader.command(
|
||||
ru_doc="<вопрос> - Задать вопрос",
|
||||
it_doc="<domanda> - Fai una domanda",
|
||||
fr_doc="<question> - Posez une question",
|
||||
de_doc="<frage> - Stelle eine Frage",
|
||||
es_doc="<pregunta> - Haz una pregunta",
|
||||
tr_doc="<soru> - Soru sor",
|
||||
uz_doc="<savol> - Savol ber",
|
||||
)
|
||||
async def gpt(self, message: Message):
|
||||
"""<question> - Ask a question"""
|
||||
if self.config["api_key"] == "":
|
||||
return await utils.answer(message, self.strings("no_api_key"))
|
||||
|
||||
args = utils.get_args_raw(message)
|
||||
if not args:
|
||||
return await utils.answer(message, self.strings("no_args"))
|
||||
|
||||
await utils.answer(
|
||||
message,
|
||||
"\n".join(
|
||||
[
|
||||
self.strings("question").format(question=args),
|
||||
self.strings("answer").format(answer=self.strings("loading")),
|
||||
]
|
||||
),
|
||||
)
|
||||
answer = await self._get_chat_completion(args)
|
||||
await utils.answer(
|
||||
message,
|
||||
"\n".join(
|
||||
[
|
||||
self.strings("question").format(question=args),
|
||||
self.strings("answer").format(
|
||||
answer=self._process_code_tags(answer)
|
||||
),
|
||||
]
|
||||
),
|
||||
)
|
||||
8
MoriSummerz/ftg-mods/full.txt
Normal file
8
MoriSummerz/ftg-mods/full.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
osu
|
||||
magictext
|
||||
qr
|
||||
top20
|
||||
lyrics
|
||||
picsaver
|
||||
weather
|
||||
chatgpt
|
||||
320
MoriSummerz/ftg-mods/lyrics.py
Normal file
320
MoriSummerz/ftg-mods/lyrics.py
Normal file
@@ -0,0 +1,320 @@
|
||||
__version__ = (2, 6, 1)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# scope: inline_content
|
||||
# requires: requests bs4 spotipy
|
||||
# meta developer: @morisummermods
|
||||
# meta pic: https://i.imgur.com/pViqDsI.png
|
||||
# meta banner: https://i.imgur.com/AIjsMoV.jpg
|
||||
|
||||
import logging
|
||||
import re
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import requests
|
||||
import spotipy
|
||||
from aiogram.types import (
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
InlineQueryResultArticle,
|
||||
InputTextMessageContent,
|
||||
)
|
||||
from bs4 import BeautifulSoup
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
|
||||
from .. import loader # noqa
|
||||
from .. import utils # noqa
|
||||
from ..inline import GeekInlineQuery, rand # noqa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
api_headers = {
|
||||
"User-Agent": "CompuServe Classic/1.22",
|
||||
"Accept": "application/json",
|
||||
"Host": "api.genius.com",
|
||||
}
|
||||
headers = {
|
||||
"User-Agent": (
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) "
|
||||
"Chrome/99.0.4844.82 Safari/537.36"
|
||||
)
|
||||
}
|
||||
host = "https://api.genius.com"
|
||||
n = "\n"
|
||||
|
||||
|
||||
def get_lyrics(self, song_url, remove_section_headers=False):
|
||||
"""Uses BeautifulSoup to scrape song info off of a Genius song URL"""
|
||||
page = requests.get(song_url, headers=headers)
|
||||
html = BeautifulSoup(page.text.replace("<br/>", "\n"), "html.parser")
|
||||
lyrics = "\n".join(
|
||||
[
|
||||
p.get_text()
|
||||
for p in html.find_all("div", attrs={"data-lyrics-container": "true"})
|
||||
]
|
||||
)
|
||||
# Remove [Verse], [Bridge], etc.
|
||||
lyrics = re.sub(r"(\[.*?\])", "</i><b>\g<1></b><i>", lyrics)
|
||||
if remove_section_headers:
|
||||
lyrics = re.sub(r"(\[.*?\])*", "", lyrics)
|
||||
lyrics = re.sub("\n{2}", "\n", lyrics)
|
||||
|
||||
return lyrics or self.strings["noLyrics"]
|
||||
|
||||
|
||||
def search(q):
|
||||
"""Search documents hosted on Genius"""
|
||||
req = requests.get(
|
||||
(
|
||||
"https://api.genius.com/search"
|
||||
"?text_format=plain"
|
||||
f"&q={quote_plus(q)}"
|
||||
"&access_token=uhYUr-qrBp5V3o46lA8vcaL1DKXTWVs5SDsb_0CDCIcKxKLwtapqeqkdNu8JnA6w"
|
||||
),
|
||||
headers=api_headers,
|
||||
).json()
|
||||
|
||||
return [
|
||||
{
|
||||
"artists": hit["result"]["artist_names"].replace("\u200b", ""),
|
||||
"title": hit["result"]["title"].replace("\u200b", ""),
|
||||
"pic": hit["result"]["header_image_thumbnail_url"],
|
||||
"url": hit["result"]["url"],
|
||||
"id": hit["result"]["id"],
|
||||
}
|
||||
for hit in req["response"]["hits"]
|
||||
]
|
||||
|
||||
|
||||
def add_protocol(x):
|
||||
"""Add https protocol to link"""
|
||||
return f"https:{x}" if x.startswith("//") else x
|
||||
|
||||
|
||||
@loader.tds
|
||||
class LyricsMod(loader.Module):
|
||||
"""Song lyrics from Genius"""
|
||||
|
||||
strings = {
|
||||
"name": "Lyrics",
|
||||
"type_name": "<b>🚫 Please type name of the song</b>",
|
||||
"genius": "🎵 Full lyrics on Genius",
|
||||
"noSpotify": (
|
||||
"<b>🚫 Please install SpotifyNow module and proceed auth</b>\n"
|
||||
"🌃 Install: <code>.dlmod https://mods.hikariatama.ru/spotify.py</code>"
|
||||
),
|
||||
"notFound": "🚫 No results found",
|
||||
"couldn'tFind": "We couldn't find what are you looking for",
|
||||
"sauth": "<b>🚫 Execute <code>.sauth</code> before using this action.</b>",
|
||||
"SpotifyError": "<b>🚫 Spotify error</b>",
|
||||
"noResults": "<b>🚫 No results found for <code>{}</code></b>",
|
||||
"noLyrics": "<b>🚫 Couldn't find the lyrics</b>",
|
||||
"lyrics": "Lyrics for <b>{}</b> by <b>{}</b>\n<i>{}",
|
||||
"loading": "Loading lyrics for <b>{}</b> by <b>{}</b>...\n{}",
|
||||
}
|
||||
|
||||
strings_ru = {
|
||||
"_cls_doc": "Поиск тексов песен с Genius",
|
||||
"_cmd_doc_lyrics": "Получить слова песни",
|
||||
"_cmd_doc_slyrics": (
|
||||
"Получить слова песни прослушиваемой в Спотифай, "
|
||||
"для работоспособности требуется модуль SpotifyNow"
|
||||
),
|
||||
"_ihandle_doc_lyrics": "Поиск текста песни",
|
||||
"type_name": "<b>🚫 Пожалуйста, введите имя композиции</b>",
|
||||
"genius": "🎵 Полный текст на Genius",
|
||||
"noSpotify": (
|
||||
"<b>🚫 Пожалуйста установи модуль SpotifyNow и пройди авторизацию.</b>\n"
|
||||
"🌃 Установка: <code>.dlmod https://mods.hikariatama.ru/spotify.py</code>"
|
||||
),
|
||||
"notFound": "🚫 Результаты не найдены",
|
||||
"couldn'tFind": "К сожалению мы не нашли, что вы искали",
|
||||
"sauth": "<b>🚫 Выполни <code>.sauth</code> перед этим действием.</b>",
|
||||
"SpotifyError": "<b>🚫 Ошибка Спотифай</b>",
|
||||
"noResults": "<b>🚫 Результаты для <code>{}</code> не найдены</b>",
|
||||
"noLyrics": "<b>🚫 Не удалось найти текст</b>",
|
||||
"lyrics": "Текст песни <b>{}</b> от <b>{}</b>\n<i>{}",
|
||||
"loading": "Загрузка текста песни <b>{}</b> от <b>{}</b>...\n{}",
|
||||
}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
if hasattr(self, "hikka"):
|
||||
self.bot_id = self.inline.bot_id
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
self.bot_id = (await self.inline.bot.get_me()).id
|
||||
try:
|
||||
channel = await self.client.get_entity("t.me/morisummermods")
|
||||
await client(JoinChannelRequest(channel))
|
||||
except Exception:
|
||||
logger.info("Can't join morisummermods")
|
||||
try:
|
||||
post = (await client.get_messages("@morisummermods", ids=[13]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.info("Can't react to morisummermods")
|
||||
|
||||
async def lyricscmd(self, message: Message):
|
||||
"""Get lyrics"""
|
||||
text = utils.get_args_raw(message)
|
||||
reply = await message.get_reply_message()
|
||||
if not text:
|
||||
if reply:
|
||||
if (
|
||||
getattr(reply, "media", None)
|
||||
and getattr(reply.media, "document", None)
|
||||
and getattr(reply.media.document, "attributes", None)
|
||||
):
|
||||
text = reply.media.document.attributes[1].file_name.rsplit(".", 1)[
|
||||
0
|
||||
]
|
||||
else:
|
||||
try:
|
||||
e = next(
|
||||
entity
|
||||
for entity in reply.entities
|
||||
if type(entity).__name__ == "MessageEntityCode"
|
||||
)
|
||||
text = reply.raw_text[e.offset - 1 : e.offset + e.length]
|
||||
except Exception:
|
||||
text = reply.raw_text
|
||||
else:
|
||||
await utils.answer(message, self.strings["type_name"])
|
||||
return
|
||||
if tracks := search(text):
|
||||
track = tracks[0]
|
||||
else:
|
||||
await utils.answer(message, self.strings["noResults"].format(text))
|
||||
return
|
||||
await self.inline.form(
|
||||
self.strings["lyrics"].format(
|
||||
track["title"], track["artists"], get_lyrics(self, track["url"])
|
||||
)[:4092]
|
||||
+ "</i>",
|
||||
reply_markup=[[{"text": self.strings["genius"], "url": track["url"]}]],
|
||||
force_me=False,
|
||||
message=message,
|
||||
)
|
||||
|
||||
async def lyrics_inline_handler(self, query: GeekInlineQuery) -> None:
|
||||
"""Search song"""
|
||||
text = query.args
|
||||
if not text:
|
||||
return
|
||||
tracks = search(text)
|
||||
if not tracks:
|
||||
await query.answer(
|
||||
[
|
||||
InlineQueryResultArticle(
|
||||
id="-1",
|
||||
title=self.strings["notFound"],
|
||||
description=self.strings["couldn'tFind"],
|
||||
thumb_url="https://img.icons8.com/stickers/100/000000/nothing-found.png",
|
||||
input_message_content=InputTextMessageContent(
|
||||
self.strings["noResults"].format(text),
|
||||
parse_mode="HTML",
|
||||
),
|
||||
)
|
||||
],
|
||||
cache_time=0,
|
||||
)
|
||||
return
|
||||
res = [
|
||||
InlineQueryResultArticle(
|
||||
id=track["id"],
|
||||
title=track["title"],
|
||||
description=track["artists"],
|
||||
thumb_url=add_protocol(track["pic"]),
|
||||
input_message_content=InputTextMessageContent(
|
||||
self.strings["loading"].format(
|
||||
track["title"], track["artists"], track["url"]
|
||||
),
|
||||
parse_mode="HTML",
|
||||
disable_web_page_preview=True,
|
||||
),
|
||||
reply_markup=InlineKeyboardMarkup().add(
|
||||
InlineKeyboardButton(self.strings["genius"], url=track["url"])
|
||||
),
|
||||
)
|
||||
for track in tracks[:50]
|
||||
]
|
||||
await query.answer(res, cache_time=0)
|
||||
|
||||
async def slyricscmd(self, message: Message):
|
||||
"""Get lyrics from your current Spotify playback (Needs SpotifyNow module)"""
|
||||
check = self.db.get("SpotifyNow", "acs_tkn", "404")
|
||||
if check == "404":
|
||||
await utils.answer(message, self.strings["noSpotify"])
|
||||
return
|
||||
elif check is None:
|
||||
await utils.answer(message, self.strings["sauth"])
|
||||
return
|
||||
try:
|
||||
sp = spotipy.Spotify(
|
||||
auth=self.db.get("SpotifyNow", "acs_tkn")["access_token"]
|
||||
)
|
||||
current_playback = sp.current_playback()
|
||||
except Exception:
|
||||
await utils.answer(message, self.strings["SpotifyError"])
|
||||
return
|
||||
try:
|
||||
track = current_playback["item"]["name"]
|
||||
except Exception:
|
||||
track = None
|
||||
try:
|
||||
artists = ", ".join(
|
||||
[artist["name"] for artist in current_playback["item"]["artists"]]
|
||||
)
|
||||
except Exception:
|
||||
artists = None
|
||||
text = f"{artists} {track}"
|
||||
if tracks := search(text):
|
||||
track = tracks[0]
|
||||
else:
|
||||
await utils.answer(message, self.strings["noResults"].format(text))
|
||||
return
|
||||
await self.inline.form(
|
||||
self.strings["lyrics"].format(
|
||||
track["title"], track["artists"], get_lyrics(self, track["url"])
|
||||
)[:4092]
|
||||
+ "</i>",
|
||||
reply_markup=[[{"text": self.strings["genius"], "url": track["url"]}]],
|
||||
force_me=False,
|
||||
message=message,
|
||||
)
|
||||
|
||||
async def watcher(self, message: Message) -> None:
|
||||
if (
|
||||
getattr(message, "out", False)
|
||||
and getattr(message, "via_bot_id", False)
|
||||
and message.via_bot_id == self.bot_id
|
||||
and (
|
||||
"Loading lyrics for" in getattr(message, "raw_text", "")
|
||||
or "Загрузка текста песни" in getattr(message, "raw_text", "")
|
||||
)
|
||||
):
|
||||
e = message.entities
|
||||
track = {
|
||||
"title": message.raw_text[e[0].offset : e[0].offset + e[0].length],
|
||||
"artists": message.raw_text[e[1].offset : e[1].offset + e[1].length],
|
||||
"url": message.raw_text.splitlines()[1],
|
||||
}
|
||||
await self.inline.form(
|
||||
self.strings["lyrics"].format(
|
||||
track["title"], track["artists"], get_lyrics(self, track["url"])
|
||||
)[:4092]
|
||||
+ "</i>",
|
||||
reply_markup=[[{"text": self.strings["genius"], "url": track["url"]}]],
|
||||
force_me=False,
|
||||
message=message,
|
||||
)
|
||||
return
|
||||
150
MoriSummerz/ftg-mods/magictext-ftg.py
Normal file
150
MoriSummerz/ftg-mods/magictext-ftg.py
Normal file
@@ -0,0 +1,150 @@
|
||||
__version__ = (0, 0, 1)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
import logging
|
||||
from asyncio import sleep
|
||||
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
|
||||
# scope: inline_content
|
||||
# meta developer: @morisummermods
|
||||
from .. import loader, utils # noqa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
letters = {
|
||||
" ": "000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000",
|
||||
"a": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n000000000000",
|
||||
"b": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111000\n001111111000\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"c": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001100000000\n001100000000\n001100000000\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"d": "000000000000\n001111111000\n001111111100\n000110001100\n000110001100\n000110001100\n000110001100\n000110001100\n000110001100\n001111111100\n001111111000\n000000000000",
|
||||
"e": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"f": "000000000000\n000111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"g": "000000000000\n000111111000\n001111111100\n001100000000\n001100000000\n001100111100\n001100111100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"h": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"i": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n001111111100\n001111111100\n000000000000",
|
||||
"j": "000000000000\n000111111100\n000111111100\n000000011000\n000000011000\n000000011000\n000000011000\n001100011000\n001100011000\n001111111000\n000111110000\n000000000000",
|
||||
"k": "000000000000\n001100001100\n001100011100\n001100111000\n001101110000\n001111100000\n001111100000\n001101110000\n001100111000\n001100011100\n001100001100\n000000000000",
|
||||
"l": "000000000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001111111100\n001111111100\n000000000000",
|
||||
"m": "000000000000\n001100001100\n001110011100\n001111111100\n001111111100\n001101101100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"n": "000000000000\n001100001100\n001110001100\n001111001100\n001111101100\n001101111100\n001100111100\n001100011100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"o": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"p": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"q": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001101101100\n001101111100\n001100111000\n001111111100\n000111101100\n000000000000",
|
||||
"r": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100011100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"s": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001111111000\n000111111100\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"t": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"u": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"v": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001110011100\n000111111000\n000011110000\n000001100000\n000000000000",
|
||||
"w": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001101101100\n001111111100\n001111111100\n001110011100\n001100001100\n000000000000",
|
||||
"x": "000000000000\n001100001100\n001100001100\n001110011100\n000111011000\n000011110000\n000011110000\n000110111000\n001110011100\n001100001100\n001100001100\n000000000000",
|
||||
"y": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n001111111100\n001111111000\n000000000000",
|
||||
"z": "000000000000\n001111111100\n001111111100\n000000011100\n000000111000\n000001110000\n000011100000\n000111000000\n001110000000\n001111111100\n001111111100\n000000000000",
|
||||
"а": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n000000000000",
|
||||
"б": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"в": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111000\n001111111000\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"г": "000000000000\n000011111100\n000111111100\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000000000000",
|
||||
"д": "000000000000\n000001111000\n000011111100\n000111001100\n001110001100\n001100001100\n001111111100\n011111111110\n011100001110\n011000000110\n011000000110\n000000000000",
|
||||
"е": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"ё": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"ж": "000000000000\n001101101100\n001101101100\n001111111100\n000111111000\n000011110000\n000011110000\n000111111000\n001111111100\n001101101100\n001101101100\n000000000000",
|
||||
"з": "000000000000\n000111111000\n001111111100\n001100001100\n000000001100\n000001111000\n000001111000\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"и": "000000000000\n001100001100\n001100001100\n001100011100\n001100111100\n001101111100\n001111101100\n001111001100\n001110001100\n001100001100\n001100001100\n000000000000",
|
||||
"й": "000000000000\n001101101100\n001100001100\n001100011100\n001100111100\n001101111100\n001111101100\n001111001100\n001110001100\n001100001100\n001100001100\n000000000000",
|
||||
"к": "000000000000\n001100001100\n001100011100\n001100111000\n001101110000\n001111100000\n001111100000\n001101110000\n001100111000\n001100011100\n001100001100\n000000000000",
|
||||
"л": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"м": "000000000000\n001100001100\n001110011100\n001111111100\n001111111100\n001101101100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"н": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"о": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"п": "000000000000\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"р": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"с": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001100000000\n001100000000\n001100000000\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"т": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"у": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n001111111100\n001111111000\n000000000000",
|
||||
"ф": "000000000000\n000111111000\n001111111100\n011001100110\n011001100110\n011001100110\n001111111100\n000111111000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"х": "000000000000\n001100001100\n001100001100\n001110011100\n000111011000\n000011110000\n000011110000\n000110111000\n001110011100\n001100001100\n001100001100\n000000000000",
|
||||
"ц": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111110\n000111111110\n000000000110\n000000000000",
|
||||
"ч": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n000000001100\n000000000000",
|
||||
"ш": "000000000000\n001100001100\n001100001100\n001100001100\n001101101100\n001101101100\n001101101100\n001101101100\n001101101100\n001111111100\n001111111100\n000000000000",
|
||||
"щ": "000000000000\n001100001100\n001100001100\n001100001100\n001101101100\n001101101100\n001101101100\n001101101100\n001111111110\n001111111110\n000000000110\n000000000000",
|
||||
"ь": "000000000000\n001100000000\n001100000000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"ъ": "000000000000\n011100000000\n011100000000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"ы": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111101100\n001111111100\n001100011100\n001100011100\n001111111100\n001111101100\n000000000000",
|
||||
"э": "000000000000\n000111111000\n001111111100\n001100001100\n000000001100\n000011111100\n000011111100\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"ю": "000000000000\n011001111100\n011011111110\n011011000110\n011011000110\n011111000110\n011111000110\n011011000110\n011011000110\n011011111110\n011001111100\n000000000000",
|
||||
"я": "000000000000\n000111111100\n001111111100\n001100001100\n001100001100\n001111111100\n000111111100\n000000111100\n000001111100\n000011101100\n000111001100\n000000000000",
|
||||
".": "000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000001100000\n000001100000\n000000000000",
|
||||
"!": "000000000000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000\n000000000000\n000001100000\n000001100000\n000000000000",
|
||||
"💖": "000000000000\n001110011100\n011🤍11111110\n01🤍111111110\n011111111110\n011111111110\n011111111110\n001111111100\n000111111000\n000011110000\n000001100000\n000000000000",
|
||||
}
|
||||
|
||||
|
||||
class MagicTextMod(loader.Module):
|
||||
"""Magic Text generator"""
|
||||
|
||||
strings = {"name": "MagicText", "author": "morisummermods"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
self.db = db
|
||||
self.client = client
|
||||
self.symbols = self.db.get(self.strings["name"], "symbols", "✨💖")
|
||||
try:
|
||||
await client(
|
||||
JoinChannelRequest(
|
||||
await self.client.get_entity(f"t.me/{self.strings['author']}")
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
logger.error(f"Can't join {self.strings['author']}")
|
||||
try:
|
||||
post = (await client.get_messages(self.strings["author"], ids=[9]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.error(f"Can't react to t.me/{self.strings['author']}")
|
||||
|
||||
async def mtsetcmd(self, message: Message):
|
||||
"""Set the symbols for animation (Separated by space. Example: .mtset ✨ 💖)"""
|
||||
text = utils.get_args_raw(message).split()
|
||||
|
||||
if len(text) != 2:
|
||||
await message.edit("<b>🚫 Please type only 2 symbols</b>")
|
||||
return
|
||||
|
||||
self.db.set(self.strings["name"], "symbols", text)
|
||||
self.symbols = text
|
||||
|
||||
await message.edit("<b>✅ Symbols set successfully</b>")
|
||||
|
||||
async def mtcmd(self, message: Message):
|
||||
"""Send message with animating text"""
|
||||
text = utils.get_args_raw(message)
|
||||
text = text.replace("<3", "💖")
|
||||
await message.edit(letters[" "].replace("0", self.symbols[0]))
|
||||
_last = ""
|
||||
for letter in text:
|
||||
if _last and _last == letter:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
if letter not in letters and _last not in letters:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
await message.edit(
|
||||
letters.get(letter.lower(), "<b>🚫 Not supported symbol</b>")
|
||||
.replace("0", self.symbols[0])
|
||||
.replace("1", self.symbols[1])
|
||||
)
|
||||
|
||||
_last = letter
|
||||
await sleep(0.7)
|
||||
text = text.replace("💖", "<3")
|
||||
|
||||
await message.edit(
|
||||
f"{self.symbols[0]}{self.symbols[1]}<b>{text}</b>{self.symbols[1]}{self.symbols[0]}"
|
||||
)
|
||||
245
MoriSummerz/ftg-mods/magictext.py
Normal file
245
MoriSummerz/ftg-mods/magictext.py
Normal file
@@ -0,0 +1,245 @@
|
||||
__version__ = (2, 0, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# scope: inline_content
|
||||
# meta developer: @morisummermods
|
||||
# meta banner: https://i.imgur.com/3joMFwC.jpg
|
||||
# meta pic: https://i.imgur.com/nmAXM3k.png
|
||||
|
||||
import logging
|
||||
from asyncio import sleep
|
||||
|
||||
from aiogram.types import CallbackQuery
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
|
||||
from .. import loader, utils # noqa
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
letters = {
|
||||
" ": "000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000",
|
||||
"a": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n000000000000",
|
||||
"b": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111000\n001111111000\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"c": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001100000000\n001100000000\n001100000000\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"d": "000000000000\n001111111000\n001111111100\n000110001100\n000110001100\n000110001100\n000110001100\n000110001100\n000110001100\n001111111100\n001111111000\n000000000000",
|
||||
"e": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"f": "000000000000\n000111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"g": "000000000000\n000111111000\n001111111100\n001100000000\n001100000000\n001100111100\n001100111100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"h": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"i": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n001111111100\n001111111100\n000000000000",
|
||||
"j": "000000000000\n000111111100\n000111111100\n000000011000\n000000011000\n000000011000\n000000011000\n001100011000\n001100011000\n001111111000\n000111110000\n000000000000",
|
||||
"k": "000000000000\n001100001100\n001100011100\n001100111000\n001101110000\n001111100000\n001111100000\n001101110000\n001100111000\n001100011100\n001100001100\n000000000000",
|
||||
"l": "000000000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001100000000\n001111111100\n001111111100\n000000000000",
|
||||
"m": "000000000000\n001100001100\n001110011100\n001111111100\n001111111100\n001101101100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"n": "000000000000\n001100001100\n001110001100\n001111001100\n001111101100\n001101111100\n001100111100\n001100011100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"o": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"p": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"q": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001101101100\n001101111100\n001100111000\n001111111100\n000111101100\n000000000000",
|
||||
"r": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100011100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"s": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001111111000\n000111111100\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"t": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"u": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"v": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001110011100\n000111111000\n000011110000\n000001100000\n000000000000",
|
||||
"w": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001101101100\n001111111100\n001111111100\n001110011100\n001100001100\n000000000000",
|
||||
"x": "000000000000\n001100001100\n001100001100\n001110011100\n000111011000\n000011110000\n000011110000\n000110111000\n001110011100\n001100001100\n001100001100\n000000000000",
|
||||
"y": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n001111111100\n001111111000\n000000000000",
|
||||
"z": "000000000000\n001111111100\n001111111100\n000000011100\n000000111000\n000001110000\n000011100000\n000111000000\n001110000000\n001111111100\n001111111100\n000000000000",
|
||||
"а": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n000000000000",
|
||||
"б": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"в": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111000\n001111111000\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"г": "000000000000\n000011111100\n000111111100\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000110000000\n000000000000",
|
||||
"д": "000000000000\n000001111000\n000011111100\n000111001100\n001110001100\n001100001100\n001111111100\n011111111110\n011100001110\n011000000110\n011000000110\n000000000000",
|
||||
"е": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"ё": "000000000000\n001111111000\n001111111000\n001100000000\n001100000000\n001111110000\n001111110000\n001100000000\n001100000000\n001111111000\n001111111000\n000000000000",
|
||||
"ж": "000000000000\n001101101100\n001101101100\n001111111100\n000111111000\n000011110000\n000011110000\n000111111000\n001111111100\n001101101100\n001101101100\n000000000000",
|
||||
"з": "000000000000\n000111111000\n001111111100\n001100001100\n000000001100\n000001111000\n000001111000\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"и": "000000000000\n001100001100\n001100001100\n001100011100\n001100111100\n001101111100\n001111101100\n001111001100\n001110001100\n001100001100\n001100001100\n000000000000",
|
||||
"й": "000000000000\n001101101100\n001100001100\n001100011100\n001100111100\n001101111100\n001111101100\n001111001100\n001110001100\n001100001100\n001100001100\n000000000000",
|
||||
"к": "000000000000\n001100001100\n001100011100\n001100111000\n001101110000\n001111100000\n001111100000\n001101110000\n001100111000\n001100011100\n001100001100\n000000000000",
|
||||
"л": "000000000000\n000001100000\n000011110000\n000111111000\n001110011100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"м": "000000000000\n001100001100\n001110011100\n001111111100\n001111111100\n001101101100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"н": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"о": "000000000000\n000111111000\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"п": "000000000000\n001111111100\n001111111100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n000000000000",
|
||||
"р": "000000000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n001100000000\n001100000000\n001100000000\n001100000000\n000000000000",
|
||||
"с": "000000000000\n000111111000\n001111111100\n001100001100\n001100000000\n001100000000\n001100000000\n001100000000\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"т": "000000000000\n001111111100\n001111111100\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"у": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n001111111100\n001111111000\n000000000000",
|
||||
"ф": "000000000000\n000111111000\n001111111100\n011001100110\n011001100110\n011001100110\n001111111100\n000111111000\n000001100000\n000001100000\n000001100000\n000000000000",
|
||||
"х": "000000000000\n001100001100\n001100001100\n001110011100\n000111011000\n000011110000\n000011110000\n000110111000\n001110011100\n001100001100\n001100001100\n000000000000",
|
||||
"ц": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111110\n000111111110\n000000000110\n000000000000",
|
||||
"ч": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001100001100\n001111111100\n000111111100\n000000001100\n000000001100\n000000001100\n000000000000",
|
||||
"ш": "000000000000\n001100001100\n001100001100\n001100001100\n001101101100\n001101101100\n001101101100\n001101101100\n001101101100\n001111111100\n001111111100\n000000000000",
|
||||
"щ": "000000000000\n001100001100\n001100001100\n001100001100\n001101101100\n001101101100\n001101101100\n001101101100\n001111111110\n001111111110\n000000000110\n000000000000",
|
||||
"ь": "000000000000\n001100000000\n001100000000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"ъ": "000000000000\n011100000000\n011100000000\n001100000000\n001100000000\n001111111000\n001111111100\n001100001100\n001100001100\n001111111100\n001111111000\n000000000000",
|
||||
"ы": "000000000000\n001100001100\n001100001100\n001100001100\n001100001100\n001111101100\n001111111100\n001100011100\n001100011100\n001111111100\n001111101100\n000000000000",
|
||||
"э": "000000000000\n000111111000\n001111111100\n001100001100\n000000001100\n000011111100\n000011111100\n000000001100\n001100001100\n001111111100\n000111111000\n000000000000",
|
||||
"ю": "000000000000\n011001111100\n011011111110\n011011000110\n011011000110\n011111000110\n011111000110\n011011000110\n011011000110\n011011111110\n011001111100\n000000000000",
|
||||
"я": "000000000000\n000111111100\n001111111100\n001100001100\n001100001100\n001111111100\n000111111100\n000000111100\n000001111100\n000011101100\n000111001100\n000000000000",
|
||||
".": "000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000000000000\n000001100000\n000001100000\n000000000000",
|
||||
"!": "000000000000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000001100000\n000000000000\n000000000000\n000001100000\n000001100000\n000000000000",
|
||||
"💖": "000000000000\n001110011100\n011🤍11111110\n01🤍111111110\n011111111110\n011111111110\n011111111110\n001111111100\n000111111000\n000011110000\n000001100000\n000000000000",
|
||||
}
|
||||
|
||||
|
||||
class MagicTextMod(loader.Module):
|
||||
"""Magic Text generator"""
|
||||
|
||||
strings = {
|
||||
"name": "MagicText",
|
||||
"inline_text": "❤️🔥 I want to tell you something...",
|
||||
"only_2": "<b>🚫 Please type only 2 symbols</b>",
|
||||
"symbols_success": "<b>✅ Symbols set successfully</b>",
|
||||
"text_success": "<b>✅ Text set successfully</b>",
|
||||
"no_text": "<b>🚫 Please type text</b>",
|
||||
"open": "💖 Open",
|
||||
"not_supported": "<b>🚫 Not supported symbol</b>",
|
||||
}
|
||||
|
||||
strings_ru = {
|
||||
"inline_text": "❤️🔥 Я хочу тебе сказать что-то...",
|
||||
"only_2": "<b>🚫 Пожалуйста, введите только 2 символа</b>",
|
||||
"symbols_success": "<b>✅ Символы установлены успешно</b>",
|
||||
"text_success": "<b>✅ Текст успешно установлен</b>",
|
||||
"no_text": "<b>🚫 Пожалуйста, введите текст</b>",
|
||||
"open": "💖 Открыть",
|
||||
"not_supported": "<b>🚫 Неподдерживаемый символ</b>",
|
||||
}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
self.symbols = self.db.get(self.strings["name"], "symbols", "✨💖")
|
||||
self.inline_text = self.db.get(
|
||||
self.strings["name"],
|
||||
"inline_text",
|
||||
self.strings["inline_text"],
|
||||
)
|
||||
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
try:
|
||||
channel = await self.client.get_entity("t.me/morisummermods")
|
||||
await client(JoinChannelRequest(channel))
|
||||
except Exception:
|
||||
logger.error("Can't join morisummermods")
|
||||
try:
|
||||
post = (await client.get_messages("@morisummermods", ids=[9]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.error("Can't react to t.me/morisummermods")
|
||||
|
||||
async def mtsetcmd(self, message: Message):
|
||||
"""Set the symbols for animation (Separated by space. Example: .mtset ✨ 💖)"""
|
||||
text = utils.get_args_raw(message).split()
|
||||
|
||||
if len(text) != 2:
|
||||
await utils.answer(message, self.strings("only_2"))
|
||||
return
|
||||
|
||||
self.db.set(self.strings["name"], "symbols", text)
|
||||
self.symbols = text
|
||||
|
||||
await utils.answer(message, self.strings("symbols_success"))
|
||||
|
||||
async def mtisetcmd(self, message: Message):
|
||||
"""Set the text for inline message (Example: .mtiset ❤️🔥 I want to tell you something...)"""
|
||||
text = utils.get_args_raw(message)
|
||||
|
||||
if not text:
|
||||
await utils.answer(message, self.strings("no_text"))
|
||||
return
|
||||
|
||||
self.db.set(self.strings["name"], "inline_text", text)
|
||||
self.inline_text = text
|
||||
|
||||
await utils.answer(message, self.strings("text_success"))
|
||||
|
||||
async def mtcmd(self, message: Message):
|
||||
"""Send message with animating text"""
|
||||
text = utils.get_args_raw(message)
|
||||
text = text.replace("<3", "💖")
|
||||
await utils.answer(message, letters[" "].replace("0", self.symbols[0]))
|
||||
_last = ""
|
||||
for letter in text:
|
||||
if _last and _last == letter:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
if letter not in letters and _last not in letters:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
await utils.answer(
|
||||
message,
|
||||
letters.get(letter.lower(), self.strings("not_supported"))
|
||||
.replace("0", self.symbols[0])
|
||||
.replace("1", self.symbols[1]),
|
||||
)
|
||||
|
||||
_last = letter
|
||||
await sleep(0.7)
|
||||
text = text.replace("💖", "<3")
|
||||
|
||||
await utils.answer(
|
||||
message,
|
||||
f"{self.symbols[0]}{self.symbols[1]}<b>{text}</b>{self.symbols[1]}{self.symbols[0]}",
|
||||
)
|
||||
|
||||
async def mticmd(self, message: Message) -> None:
|
||||
"""Send inline message with animating text"""
|
||||
text = utils.get_args_raw(message)
|
||||
|
||||
await self.inline.form(
|
||||
self.inline_text,
|
||||
reply_markup=[
|
||||
[
|
||||
{
|
||||
"text": self.strings("open"),
|
||||
"callback": self.inline__handler,
|
||||
"args": (text,),
|
||||
}
|
||||
]
|
||||
],
|
||||
force_me=False,
|
||||
message=message,
|
||||
ttl=60 * 60,
|
||||
)
|
||||
|
||||
async def inline__handler(self, call: CallbackQuery, args: str) -> None:
|
||||
"""Inline handler"""
|
||||
args = args.replace("<3", "💖")
|
||||
await call.edit(letters[" "].replace("0", self.symbols[0]))
|
||||
_last = ""
|
||||
|
||||
for letter in args:
|
||||
if _last and _last == letter:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
if letter not in letters and _last not in letters:
|
||||
await sleep(0.7)
|
||||
continue
|
||||
|
||||
await call.edit(
|
||||
letters.get(letter.lower(), self.strings("not_supported"))
|
||||
.replace("0", self.symbols[0])
|
||||
.replace("1", self.symbols[1])
|
||||
)
|
||||
|
||||
_last = letter
|
||||
await sleep(0.7)
|
||||
|
||||
args = args.replace("💖", "<3")
|
||||
|
||||
await call.edit(
|
||||
f"{self.symbols[0]}{self.symbols[1]}<b>{args}</b>{self.symbols[1]}{self.symbols[0]}"
|
||||
)
|
||||
await call.unload()
|
||||
1
MoriSummerz/ftg-mods/minimal.txt
Normal file
1
MoriSummerz/ftg-mods/minimal.txt
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
250
MoriSummerz/ftg-mods/osu.py
Normal file
250
MoriSummerz/ftg-mods/osu.py
Normal file
@@ -0,0 +1,250 @@
|
||||
__version__ = (1, 3, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# requires: requests emoji-country-flag
|
||||
# meta developer: @morisummermods
|
||||
# meta banner: https://i.imgur.com/fPWWFrL.jpg
|
||||
# meta pic: https://i.imgur.com/fcHCrS2.png
|
||||
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
|
||||
import flag
|
||||
import requests
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
|
||||
from .. import loader, utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@loader.tds
|
||||
class OsuMod(loader.Module):
|
||||
""" "I'm an osu!bot that can do some things written by @morisummerzxc"""
|
||||
|
||||
strings = {
|
||||
"name": "Osu",
|
||||
"you_are": (
|
||||
"<emoji document_id=5398001711786762757>✅</emoji> <b>You are"
|
||||
" </b><code>{}</code><b> now</b>"
|
||||
),
|
||||
}
|
||||
|
||||
strings_ru = {
|
||||
"you_are": (
|
||||
"<emoji document_id=5398001711786762757>✅</emoji> <b>Теперь ты"
|
||||
" </b><code>{}</code><b></b>"
|
||||
),
|
||||
}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
self.url = "https://osu.ppy.sh/users/"
|
||||
self.nickname = self.db.get(self.strings["name"], "nickname", "")
|
||||
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
try:
|
||||
channel = await self.client.get_entity("t.me/morisummermods")
|
||||
await client(JoinChannelRequest(channel))
|
||||
except Exception:
|
||||
logger.error("Can't join morisummermods")
|
||||
try:
|
||||
post = (await client.get_messages("@morisummermods", ids=[11]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.error("Can't react to t.me/morisummermods")
|
||||
|
||||
@loader.unrestricted
|
||||
async def osumecmd(self, message: Message) -> None:
|
||||
"""Remember user's nickname for commands"""
|
||||
nickname = utils.get_args_raw(message)
|
||||
self.db.set(self.strings["name"], "nickname", nickname)
|
||||
self.nickname = nickname
|
||||
await utils.answer(
|
||||
message,
|
||||
self.strings("you_are").format(utils.escape_html(self.nickname)),
|
||||
)
|
||||
|
||||
@loader.unrestricted
|
||||
async def osutopcmd(self, message: Message) -> None:
|
||||
"""Get user's 5 best plays"""
|
||||
nickname = self.nickname
|
||||
url = self.url
|
||||
args = utils.get_args_raw(message)
|
||||
if not nickname and not args:
|
||||
await utils.answer(
|
||||
message,
|
||||
(
|
||||
"Remember your nickname with .osume <your nickname> or use .osutop"
|
||||
" <nickname>"
|
||||
),
|
||||
)
|
||||
return
|
||||
if args:
|
||||
nickname = args
|
||||
req = requests.get(f"https://osu.ppy.sh/users/{nickname}").text
|
||||
s = req.find('data-initial-data="') + 19
|
||||
JSON = req[s : req.find('"', s + 1)].replace(""", '"')
|
||||
info = json.loads(JSON)
|
||||
topScores = info["extras"]["scoresBest"]
|
||||
rank = info["user"]["statistics"]["global_rank"]
|
||||
out = (
|
||||
"5 best scores for: "
|
||||
+ '<a href="'
|
||||
+ url
|
||||
+ nickname
|
||||
+ '">'
|
||||
+ nickname
|
||||
+ "</a> #"
|
||||
+ str(rank)
|
||||
+ "\n\n<b>"
|
||||
)
|
||||
for top in topScores[:5]:
|
||||
# todo: beatmap with link
|
||||
out += (
|
||||
'<a href="'
|
||||
+ top["beatmap"]["url"]
|
||||
+ '">'
|
||||
+ top["beatmapset"]["title"]
|
||||
+ "</b> by <b>"
|
||||
+ top["beatmapset"]["artist_unicode"]
|
||||
+ "["
|
||||
+ top["beatmap"]["version"].replace("'", "'")
|
||||
+ "]</a>\n"
|
||||
)
|
||||
if top["rank"] == "X":
|
||||
grade = "SS+"
|
||||
elif top["rank"][-1] == "H":
|
||||
grade = top["rank"][:-1] + "+"
|
||||
else:
|
||||
grade = top["rank"]
|
||||
out += f"{grade} " + str(round(float(top["accuracy"]) * 100, 2)) + "% "
|
||||
for mod in top["mods"]:
|
||||
out += f"{mod} "
|
||||
out += str(top["beatmap"]["difficulty_rating"]) + "★"
|
||||
if top["perfect"]:
|
||||
out += "FC"
|
||||
out += "\n" + str(top["pp"]) + "pp\n</b>"
|
||||
out += (
|
||||
datetime.strptime(
|
||||
top["created_at"], "%Y-%m-%dT%H:%M:%S+00:00"
|
||||
).strftime("%d.%m.%Y %H:%M:%S")
|
||||
+ "\n\n"
|
||||
)
|
||||
await utils.answer(message, out)
|
||||
return
|
||||
|
||||
@loader.unrestricted
|
||||
async def osuprofilecmd(self, message: Message) -> None:
|
||||
"""Get user's profile"""
|
||||
nickname = self.nickname
|
||||
url = self.url
|
||||
args = utils.get_args_raw(message)
|
||||
if not nickname and not args:
|
||||
await utils.answer(
|
||||
message,
|
||||
(
|
||||
"Remember your nickname with .osume <your nickname> or use .osutop"
|
||||
" <nickname>"
|
||||
),
|
||||
)
|
||||
return
|
||||
if args:
|
||||
nickname = args
|
||||
await message.delete()
|
||||
req = requests.get(f"https://osu.ppy.sh/users/{nickname}").text
|
||||
s = req.find('data-initial-data="') + 19
|
||||
JSON = req[s : req.find('"', s + 1)].replace(""", '"')
|
||||
info = json.loads(JSON)
|
||||
profile = info["user"]
|
||||
photo = profile["avatar_url"]
|
||||
out = (
|
||||
'<a href="'
|
||||
+ url
|
||||
+ profile["username"]
|
||||
+ '">'
|
||||
+ flag.flag(profile["country_code"])
|
||||
+ profile["username"]
|
||||
+ " profile</a>:\n\n"
|
||||
)
|
||||
out += (
|
||||
"<b>PP: "
|
||||
+ str(profile["statistics"]["pp"])
|
||||
+ "| #"
|
||||
+ str(profile["statistics"]["global_rank"])
|
||||
+ "(#"
|
||||
+ str(profile["statistics"]["country_rank"])
|
||||
+ ")</b>"
|
||||
+ "\n\n"
|
||||
)
|
||||
top = info["extras"]["scoresBest"][0]
|
||||
topScore = (
|
||||
'<a href="'
|
||||
+ top["beatmap"]["url"]
|
||||
+ '">'
|
||||
+ top["beatmapset"]["title"]
|
||||
+ "</b> by <b>"
|
||||
+ top["beatmapset"]["artist_unicode"]
|
||||
+ "["
|
||||
+ top["beatmap"]["version"].replace("'", "'")
|
||||
+ "]</a>\n"
|
||||
)
|
||||
if top["rank"] == "X":
|
||||
grade = "SS+"
|
||||
elif top["rank"][-1] == "H":
|
||||
grade = top["rank"][:-1] + "+"
|
||||
else:
|
||||
grade = top["rank"]
|
||||
topScore += f"{grade} " + str(round(float(top["accuracy"]) * 100, 2)) + "% "
|
||||
for mod in top["mods"]:
|
||||
topScore += f"{mod} "
|
||||
topScore += str(top["beatmap"]["difficulty_rating"]) + "★"
|
||||
if top["perfect"]:
|
||||
topScore += "FC"
|
||||
topScore += "\n" + str(top["pp"]) + "pp\n</b>"
|
||||
topScore += (
|
||||
"{"
|
||||
+ str(top["statistics"]["count_300"])
|
||||
+ "/"
|
||||
+ str(top["statistics"]["count_100"])
|
||||
+ "/"
|
||||
+ str(top["statistics"]["count_50"])
|
||||
+ "/"
|
||||
+ str(top["statistics"]["count_miss"])
|
||||
+ "}\n"
|
||||
)
|
||||
topScore += (
|
||||
datetime.strptime(top["created_at"], "%Y-%m-%dT%H:%M:%S+00:00").strftime(
|
||||
"%d.%m.%Y %H:%M:%S"
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
out += "Highest pp play:\n" + topScore + "\n"
|
||||
out += (
|
||||
"Play count: "
|
||||
+ str(profile["statistics"]["play_count"])
|
||||
+ "\nPlay time: "
|
||||
+ str(round(profile["statistics"]["play_time"] / 3600, 2))
|
||||
+ "h\nAccuracy: "
|
||||
+ str(round(profile["statistics"]["hit_accuracy"], 2))
|
||||
+ "%\nLVL: "
|
||||
+ str(profile["statistics"]["level"]["current"])
|
||||
+ "\n\nJoined "
|
||||
+ str(
|
||||
datetime.strptime(
|
||||
profile["join_date"], "%Y-%m-%dT%H:%M:%S+00:00"
|
||||
).strftime("%d.%m.%Y")
|
||||
)
|
||||
)
|
||||
await self.client.send_file(message.peer_id, photo, caption=out)
|
||||
84
MoriSummerz/ftg-mods/picsaver.py
Normal file
84
MoriSummerz/ftg-mods/picsaver.py
Normal file
@@ -0,0 +1,84 @@
|
||||
__version__ = (1, 2, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
|
||||
# meta developer: @morisummermods
|
||||
|
||||
import logging
|
||||
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
from telethon.utils import get_display_name
|
||||
|
||||
from .. import loader, utils
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PicsaverMod(loader.Module):
|
||||
""" "Automatic Self-destructing media saver to Saved Messages"""
|
||||
|
||||
strings = {"name": "Picsaver"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
self.enable = db.get(self.strings["name"], "enable", True)
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
try:
|
||||
await client(
|
||||
JoinChannelRequest(await self.client.get_entity("t.me/morisummermods"))
|
||||
)
|
||||
except Exception:
|
||||
logger.error("Can't join morisummermods")
|
||||
|
||||
async def watcher(self, message: Message) -> None:
|
||||
if (
|
||||
getattr(message, "media", False)
|
||||
and getattr(message.media, "ttl_seconds", False)
|
||||
and self.enable
|
||||
and not message.out
|
||||
):
|
||||
media = await self.client.download_media(message.media)
|
||||
name = get_display_name(await self.client.get_entity(message.sender_id))
|
||||
return await self.client.send_file(
|
||||
"me",
|
||||
media,
|
||||
caption=f"Self-destructing media from {name}",
|
||||
)
|
||||
|
||||
async def spcmd(self, message: Message):
|
||||
"""Reply to self-destructing media to save"""
|
||||
reply = await message.get_reply_message()
|
||||
if (
|
||||
not reply
|
||||
or not getattr(reply, "media", False)
|
||||
or not getattr(reply.media, "ttl_seconds", False)
|
||||
):
|
||||
return await message.edit("Reply for self-destructing media !")
|
||||
await message.delete()
|
||||
media = await self.client.download_media(reply.media)
|
||||
name = get_display_name(await self.client.get_entity(reply.sender_id))
|
||||
return await self.client.send_file(
|
||||
"me",
|
||||
media,
|
||||
caption=f"Self-destructing media from {name}",
|
||||
)
|
||||
|
||||
async def pscmd(self, message: Message):
|
||||
"""Enable/disable automatic self-destructing media save"""
|
||||
if self.enable:
|
||||
self.enable = False
|
||||
self.db.set(self.strings["name"], "enable", False)
|
||||
return await utils.answer(message, "<b>Autosave is disabled</b>")
|
||||
else:
|
||||
self.enable = True
|
||||
self.db.set(self.strings["name"], "enable", True)
|
||||
return await utils.answer(message, "<b>Autosave is enabled</b>")
|
||||
51
MoriSummerz/ftg-mods/top20.py
Normal file
51
MoriSummerz/ftg-mods/top20.py
Normal file
@@ -0,0 +1,51 @@
|
||||
__version__ = (1, 2, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# meta developer: @morisummermods
|
||||
|
||||
import logging
|
||||
|
||||
from telethon.tl.types import Message
|
||||
|
||||
from .. import loader
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@loader.tds
|
||||
class Top20Mod(loader.Module):
|
||||
strings = {"name": "Top20"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
|
||||
async def top20cmd(self, message: Message) -> None:
|
||||
words = {}
|
||||
await message.edit("Processed 0 messages")
|
||||
total = 0
|
||||
async for msg in self.client.iter_messages(message.peer_id):
|
||||
total += 1
|
||||
if total % 500 == 0:
|
||||
await message.edit(f"Processed {total} messages")
|
||||
if msg.text:
|
||||
for word in msg.text.split():
|
||||
if len(word) >= 3:
|
||||
if word.lower() not in words:
|
||||
words[word.lower()] = 0
|
||||
else:
|
||||
words[word.lower()] += 1
|
||||
global freq
|
||||
freq = sorted(words, key=words.get, reverse=True)
|
||||
out = "".join(
|
||||
f"Top {i + 1}. {words[freq[i]]} occurrences: {freq[i]}\n" for i in range(20)
|
||||
)
|
||||
await message.edit(out, parse_mode=None)
|
||||
108
MoriSummerz/ftg-mods/weather.py
Normal file
108
MoriSummerz/ftg-mods/weather.py
Normal file
@@ -0,0 +1,108 @@
|
||||
__version__ = (1, 1, 0)
|
||||
|
||||
"""
|
||||
█▀▄▀█ █▀█ █▀█ █ █▀ █ █ █▀▄▀█ █▀▄▀█ █▀▀ █▀█
|
||||
█ ▀ █ █▄█ █▀▄ █ ▄█ █▄█ █ ▀ █ █ ▀ █ ██▄ █▀▄
|
||||
Copyright 2022 t.me/morisummermods
|
||||
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
"""
|
||||
# scope: inline_content
|
||||
# requires: requests
|
||||
# meta developer: @morisummermods
|
||||
# meta banner: https://i.imgur.com/JR6VqYF.png
|
||||
# meta pic: https://i.imgur.com/iwoskSb.png
|
||||
|
||||
import logging
|
||||
import re
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
import requests
|
||||
from aiogram.types import InlineQueryResultArticle, InputTextMessageContent
|
||||
from telethon.tl.functions.channels import JoinChannelRequest
|
||||
from telethon.tl.types import Message
|
||||
|
||||
from .. import loader, utils
|
||||
from ..inline import GeekInlineQuery, rand
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
n = "\n"
|
||||
rus = "ёйцукенгшщзхъфывапролджэячсмитьбю"
|
||||
|
||||
|
||||
def escape_ansi(line):
|
||||
ansi_escape = re.compile(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]")
|
||||
return ansi_escape.sub("", line)
|
||||
|
||||
|
||||
class WeatherMod(loader.Module):
|
||||
"""Weather module"""
|
||||
|
||||
strings = {"name": "Weather"}
|
||||
|
||||
async def client_ready(self, client, db) -> None:
|
||||
if hasattr(self, "hikka"):
|
||||
return
|
||||
|
||||
self.db = db
|
||||
self.client = client
|
||||
try:
|
||||
channel = await self.client.get_entity("t.me/morisummermods")
|
||||
await client(JoinChannelRequest(channel))
|
||||
except Exception:
|
||||
logger.error("Can't join morisummermods")
|
||||
try:
|
||||
post = (await client.get_messages("@morisummermods", ids=[17]))[0]
|
||||
await post.react("❤️")
|
||||
except Exception:
|
||||
logger.error("Can't react to t.me/morisummermods")
|
||||
|
||||
async def weathercitycmd(self, message: Message) -> None:
|
||||
"""Set default city for forecast"""
|
||||
if args := utils.get_args_raw(message):
|
||||
self.db.set(self.strings["name"], "city", args)
|
||||
|
||||
await utils.answer(
|
||||
message,
|
||||
(
|
||||
"<b>🏙 Your current city: "
|
||||
f"<code>{self.db.get(self.strings['name'], 'city', '🚫 Not specified')}</code></b>"
|
||||
),
|
||||
)
|
||||
return
|
||||
|
||||
async def weathercmd(self, message: Message) -> None:
|
||||
"""Current forecast for provided city"""
|
||||
city = utils.get_args_raw(message)
|
||||
if not city:
|
||||
city = self.db.get(self.strings["name"], "city", "")
|
||||
|
||||
lang = "ru" if city and city[0].lower() in rus else "en"
|
||||
req = requests.get(f"https://wttr.in/{city}?m&T&lang={lang}")
|
||||
await utils.answer(message, f"<code>{n.join(req.text.splitlines()[:7])}</code>")
|
||||
|
||||
async def weather_inline_handler(self, query: GeekInlineQuery) -> None:
|
||||
"""Search city"""
|
||||
args = query.args
|
||||
if not args:
|
||||
args = self.db.get(self.strings["name"], "city", "")
|
||||
|
||||
if not args:
|
||||
return
|
||||
|
||||
lang = "ru" if args and args[0].lower() in rus else "en"
|
||||
req = requests.get(f"https://wttr.in/{quote_plus(args)}?format=3")
|
||||
await query.answer(
|
||||
[
|
||||
InlineQueryResultArticle(
|
||||
id=rand(20),
|
||||
title=f"Forecast for {args}",
|
||||
description=req.text,
|
||||
input_message_content=InputTextMessageContent(
|
||||
f'<code>{n.join(requests.get(f"https://wttr.in/{args}?m&T&lang={lang}").text.splitlines()[:7])}</code>',
|
||||
parse_mode="HTML",
|
||||
),
|
||||
)
|
||||
],
|
||||
cache_time=0,
|
||||
)
|
||||
Reference in New Issue
Block a user