mirror of
https://github.com/MuRuLOSE/limoka.git
synced 2026-06-18 23:24:18 +02:00
Commited backup
This commit is contained in:
298
AlpacaGang/ftg-modules/quotes.py
Normal file
298
AlpacaGang/ftg-modules/quotes.py
Normal file
@@ -0,0 +1,298 @@
|
||||
# -*- coding: future_fstrings -*-
|
||||
|
||||
# Friendly Telegram (telegram userbot)
|
||||
# Copyright (C) 2018-2019 The Authors
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import requests
|
||||
import base64
|
||||
import json
|
||||
import telethon
|
||||
|
||||
from .. import loader, utils
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def register(cb):
|
||||
cb(QuotesMod())
|
||||
|
||||
|
||||
@loader.tds
|
||||
class QuotesMod(loader.Module):
|
||||
"""Quote a message."""
|
||||
strings = {
|
||||
"name": "Quotes",
|
||||
"api_token_cfg_doc": "API Key/Token for Quotes.",
|
||||
"api_url_cfg_doc": "API URL for Quotes.",
|
||||
"colors_cfg_doc": "Username colors",
|
||||
"default_username_color_cfg_doc": "Default color for the username.",
|
||||
"no_reply": "<b>You didn't reply to a message.</b>",
|
||||
"no_template": "<b>You didn't specify the template.</b>",
|
||||
"delimiter": "</code>, <code>",
|
||||
"server_error": "<b>Server error. Please report to developer.</b>",
|
||||
"invalid_token": "<b>You've set an invalid token.</b>",
|
||||
"unauthorized": "<b>You're unauthorized to do this.</b>",
|
||||
"not_enough_permissions": "<b>Wrong template. You can use only the default one.</b>",
|
||||
"templates": "<b>Available Templates:</b> <code>{}</code>",
|
||||
"cannot_send_stickers": "<b>You cannot send stickers in this chat.</b>",
|
||||
"admin": "admin",
|
||||
"creator": "creator",
|
||||
"hidden": "hidden",
|
||||
"channel": "Channel",
|
||||
"filename": "file.png"
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.config = loader.ModuleConfig("api_token", None, lambda: self.strings["api_token_cfg_doc"],
|
||||
"api_url", "http://api.antiddos.systems",
|
||||
lambda: self.strings["api_url_cfg_doc"],
|
||||
"username_colors", ["#fb6169", "#faa357", "#b48bf2", "#85de85",
|
||||
"#62d4e3", "#65bdf3", "#ff5694"],
|
||||
lambda: self.strings["colors_cfg_doc"],
|
||||
"default_username_color", "#b48bf2",
|
||||
lambda: self.strings["default_username_color_cfg_doc"])
|
||||
|
||||
def config_complete(self):
|
||||
self.name = self.strings["name"]
|
||||
|
||||
async def client_ready(self, client, db):
|
||||
self.client = client
|
||||
|
||||
async def quotecmd(self, message): # noqa: C901
|
||||
"""Quote a message.
|
||||
Usage: .quote [template] [file/force_file]
|
||||
Or: .quote np [template] [file/force_file]
|
||||
If template is missing, possible templates are fetched.
|
||||
If no args provided, default template will be used, quote sent as sticker"""
|
||||
args = utils.get_args(message)
|
||||
if len(args) > 0 and args[0] == 'np':
|
||||
no_picture = True
|
||||
del args[0]
|
||||
else:
|
||||
no_picture = False
|
||||
reply = await message.get_reply_message()
|
||||
|
||||
if not reply:
|
||||
return await utils.answer(message, self.strings["no_reply"])
|
||||
|
||||
username_color = username = admintitle = user_id = None
|
||||
profile_photo_url = reply.from_id
|
||||
|
||||
admintitle = ""
|
||||
pfp = None
|
||||
if isinstance(reply.to_id, telethon.tl.types.PeerChannel) and reply.fwd_from:
|
||||
user = reply.forward.chat
|
||||
elif isinstance(reply.to_id, telethon.tl.types.PeerChat):
|
||||
chat = await self.client(telethon.tl.functions.messages.GetFullChatRequest(reply.to_id))
|
||||
participants = chat.full_chat.participants.participants
|
||||
participant = next(filter(lambda x: x.user_id == reply.from_id, participants), None)
|
||||
if isinstance(participant, telethon.tl.types.ChatParticipantCreator):
|
||||
admintitle = self.strings["creator"]
|
||||
elif isinstance(participant, telethon.tl.types.ChatParticipantAdmin):
|
||||
admintitle = self.strings["admin"]
|
||||
user = await reply.get_sender()
|
||||
else:
|
||||
user = await reply.get_sender()
|
||||
|
||||
username = telethon.utils.get_display_name(user)
|
||||
if reply.fwd_from is not None and reply.fwd_from.post_author is not None:
|
||||
username += f" ({reply.fwd_from.post_author})"
|
||||
user_id = reply.from_id
|
||||
|
||||
if reply.fwd_from:
|
||||
if reply.fwd_from.saved_from_peer:
|
||||
profile_photo_url = reply.forward.chat
|
||||
admintitle = self.strings["channel"]
|
||||
elif reply.fwd_from.from_name:
|
||||
username = reply.fwd_from.from_name
|
||||
profile_photo_url = None
|
||||
admintitle = ""
|
||||
elif reply.forward.sender:
|
||||
username = telethon.utils.get_display_name(reply.forward.sender)
|
||||
profile_photo_url = reply.forward.sender.id
|
||||
admintitle = ""
|
||||
elif reply.forward.chat:
|
||||
admintitle = self.strings["channel"]
|
||||
profile_photo_url = user
|
||||
else:
|
||||
if isinstance(reply.to_id, telethon.tl.types.PeerUser) is False:
|
||||
try:
|
||||
user = await self.client(telethon.tl.functions.channels.GetParticipantRequest(message.chat_id,
|
||||
user))
|
||||
if isinstance(user.participant, telethon.tl.types.ChannelParticipantCreator):
|
||||
admintitle = user.participant.rank or self.strings["creator"]
|
||||
elif isinstance(user.participant, telethon.tl.types.ChannelParticipantAdmin):
|
||||
admintitle = user.participant.rank or self.strings["admin"]
|
||||
user = user.users[0]
|
||||
except telethon.errors.rpcerrorlist.UserNotParticipantError:
|
||||
pass
|
||||
|
||||
if no_picture:
|
||||
profile_photo_url = ''
|
||||
else:
|
||||
if profile_photo_url is not None:
|
||||
pfp = await self.client.download_profile_photo(profile_photo_url, bytes)
|
||||
|
||||
if pfp is not None:
|
||||
profile_photo_url = "data:image/png;base64, " + base64.b64encode(pfp).decode()
|
||||
else:
|
||||
profile_photo_url = ""
|
||||
|
||||
if user_id is not None:
|
||||
username_color = self.config["username_colors"][user_id % 7]
|
||||
else:
|
||||
username_color = self.config["default_username_color"]
|
||||
|
||||
reply_username = ""
|
||||
reply_text = ""
|
||||
if reply.is_reply is True:
|
||||
reply_to = await reply.get_reply_message()
|
||||
reply_peer = None
|
||||
if reply_to.fwd_from is not None:
|
||||
if reply_to.forward.chat is not None:
|
||||
reply_peer = reply_to.forward.chat
|
||||
elif reply_to.fwd_from.from_id is not None:
|
||||
try:
|
||||
user_id = reply_to.fwd_from.from_id
|
||||
user = await self.client(telethon.tl.functions.users.GetFullUserRequest(user_id))
|
||||
reply_peer = user.user
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
reply_username = reply_to.fwd_from.from_name
|
||||
elif reply_to.from_id is not None:
|
||||
reply_user = await self.client(telethon.tl.functions.users.GetFullUserRequest(reply_to.from_id))
|
||||
reply_peer = reply_user.user
|
||||
|
||||
if reply_username is None or reply_username == "":
|
||||
reply_username = telethon.utils.get_display_name(reply_peer)
|
||||
reply_text = reply_to.message
|
||||
|
||||
date = ""
|
||||
if reply.fwd_from is not None:
|
||||
date = reply.fwd_from.date.strftime("%H:%M")
|
||||
else:
|
||||
date = reply.date.strftime("%H:%M")
|
||||
|
||||
request = json.dumps({
|
||||
"ProfilePhotoURL": profile_photo_url,
|
||||
"usernameColor": username_color,
|
||||
"username": username,
|
||||
"adminTitle": admintitle,
|
||||
"Text": reply.message,
|
||||
"Markdown": get_markdown(reply),
|
||||
"ReplyUsername": reply_username,
|
||||
"ReplyText": reply_text,
|
||||
"Date": date,
|
||||
"Template": args[0] if len(args) > 0 else 'default',
|
||||
"APIKey": self.config["api_token"]
|
||||
})
|
||||
|
||||
resp = await utils.run_sync(requests.post, self.config["api_url"] + "/api/v2/quote", data=request)
|
||||
resp.raise_for_status()
|
||||
resp = await utils.run_sync(resp.json)
|
||||
|
||||
if resp["status"] == 500:
|
||||
return await utils.answer(message, self.strings["server_error"])
|
||||
elif resp["status"] == 401:
|
||||
if resp["message"] == "ERROR_TOKEN_INVALID":
|
||||
return await utils.answer(message, self.strings["invalid_token"])
|
||||
else:
|
||||
raise ValueError("Invalid response from server", resp)
|
||||
elif resp["status"] == 403:
|
||||
if resp["message"] == "ERROR_UNAUTHORIZED":
|
||||
return await utils.answer(message, self.strings["unauthorized"])
|
||||
else:
|
||||
raise ValueError("Invalid response from server", resp)
|
||||
elif resp["status"] == 404:
|
||||
if resp["message"] == "ERROR_TEMPLATE_NOT_FOUND":
|
||||
newreq = await utils.run_sync(requests.post, self.config["api_url"] + "/api/v1/getalltemplates", data={
|
||||
"token": self.config["api_token"]
|
||||
})
|
||||
newreq = await utils.run_sync(newreq.json)
|
||||
|
||||
if newreq["status"] == "NOT_ENOUGH_PERMISSIONS":
|
||||
return await utils.answer(message, self.strings["not_enough_permissions"])
|
||||
elif newreq["status"] == "SUCCESS":
|
||||
templates = self.strings["delimiter"].join(newreq["message"])
|
||||
return await utils.answer(message, self.strings["templates"].format(templates))
|
||||
elif newreq["status"] == "INVALID_TOKEN":
|
||||
return await utils.answer(message, self.strings["invalid_token"])
|
||||
else:
|
||||
raise ValueError("Invalid response from server", newreq)
|
||||
else:
|
||||
raise ValueError("Invalid response from server", resp)
|
||||
elif resp["status"] != 200:
|
||||
raise ValueError("Invalid response from server", resp)
|
||||
|
||||
req = await utils.run_sync(requests.get, self.config["api_url"] + "/cdn/" + resp["message"])
|
||||
req.raise_for_status()
|
||||
file = BytesIO(req.content)
|
||||
file.seek(0)
|
||||
|
||||
if len(args) == 2:
|
||||
if args[1] == "file":
|
||||
await utils.answer(message, file)
|
||||
elif args[1] == "force_file":
|
||||
file.name = self.strings["filename"]
|
||||
await utils.answer(message, file, force_document=True)
|
||||
else:
|
||||
img = await utils.run_sync(Image.open, file)
|
||||
with BytesIO() as sticker:
|
||||
await utils.run_sync(img.save, sticker, "webp")
|
||||
sticker.name = "sticker.webp"
|
||||
sticker.seek(0)
|
||||
try:
|
||||
await utils.answer(message, sticker)
|
||||
except telethon.errors.rpcerrorlist.ChatSendStickersForbiddenError:
|
||||
await utils.answer(message, self.strings["cannot_send_stickers"])
|
||||
file.close()
|
||||
|
||||
|
||||
def get_markdown(reply):
|
||||
if not reply.entities:
|
||||
return []
|
||||
|
||||
markdown = []
|
||||
for entity in reply.entities:
|
||||
md_item = {
|
||||
"Type": None,
|
||||
"Start": entity.offset,
|
||||
"End": entity.offset + entity.length - 1
|
||||
}
|
||||
if isinstance(entity, telethon.tl.types.MessageEntityBold):
|
||||
md_item["Type"] = "bold"
|
||||
elif isinstance(entity, telethon.tl.types.MessageEntityItalic):
|
||||
md_item["Type"] = "italic"
|
||||
elif isinstance(entity, (telethon.tl.types.MessageEntityMention, telethon.tl.types.MessageEntityTextUrl,
|
||||
telethon.tl.types.MessageEntityMentionName, telethon.tl.types.MessageEntityHashtag,
|
||||
telethon.tl.types.MessageEntityCashtag, telethon.tl.types.MessageEntityBotCommand,
|
||||
telethon.tl.types.MessageEntityUrl)):
|
||||
md_item["Type"] = "link"
|
||||
elif isinstance(entity, telethon.tl.types.MessageEntityCode):
|
||||
md_item["Type"] = "code"
|
||||
elif isinstance(entity, telethon.tl.types.MessageEntityStrike):
|
||||
md_item["Type"] = "stroke"
|
||||
elif isinstance(entity, telethon.tl.types.MessageEntityUnderline):
|
||||
md_item["Type"] = "underline"
|
||||
else:
|
||||
logger.warning("Unknown entity: " + str(entity))
|
||||
|
||||
markdown.append(md_item)
|
||||
return markdown
|
||||
Reference in New Issue
Block a user