diff --git a/README.md b/README.md index 81d01e213..f36cdfb07 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ async def testing(message: Message): ### Project Credits -* [Specially these projects](https://github.com/uaudith/Userge#inspiration) +* [Specially to these projects](https://github.com/uaudith/Userge#inspiration) * [@uaudIth](https://t.me/uaudIth) * [@K_E_N_W_A_Y](https://t.me/K_E_N_W_A_Y) * [@nawwasl](https://t.me/nawwasl) @@ -84,4 +84,4 @@ async def testing(message: Message): ### Copyright & License * Copyright (C) 2020 [@SLBOTS](https://t.me/slbotsupdates) -* Licensed under the terms of the [GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007](https://github.com/uaudith/Userge/LICENSE) \ No newline at end of file +* Licensed under the terms of the [GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007](https://github.com/uaudith/Userge/blob/master/LICENSE) \ No newline at end of file diff --git a/genStrSession.py b/genStrSession.py index 6a14b4354..cd56a87ce 100644 --- a/genStrSession.py +++ b/genStrSession.py @@ -1,3 +1,14 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# All rights reserved. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# file that should have been included as part of this package. + + from pyrogram import Client import asyncio diff --git a/requirements.txt b/requirements.txt index a66ebb21a..a016cdc02 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,4 +19,5 @@ selenium google-api-python-client google-auth-httplib2 google-auth-oauthlib -oauth2client \ No newline at end of file +oauth2client +cowpy \ No newline at end of file diff --git a/userge/__init__.py b/userge/__init__.py index cf42413cf..813da023d 100644 --- a/userge/__init__.py +++ b/userge/__init__.py @@ -1,6 +1,16 @@ -from userge.utils import Config, logging +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge.core import ( Userge, Filters, Message, get_collection) +from userge.utils import Config, logging + userge = Userge() # userge is the client name diff --git a/userge/__main__.py b/userge/__main__.py index 5e1ec1524..d55888d0b 100644 --- a/userge/__main__.py +++ b/userge/__main__.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge diff --git a/userge/core/__init__.py b/userge/core/__init__.py index 5369a8cb1..7d23819e0 100644 --- a/userge/core/__init__.py +++ b/userge/core/__init__.py @@ -1,2 +1,11 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from ._userge import Userge, Filters, Message from ._database import get_collection \ No newline at end of file diff --git a/userge/core/_database/__init__.py b/userge/core/_database/__init__.py index 2a8780b23..ad597379c 100644 --- a/userge/core/_database/__init__.py +++ b/userge/core/_database/__init__.py @@ -1 +1,10 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from .db import get_collection \ No newline at end of file diff --git a/userge/core/_database/db.py b/userge/core/_database/db.py index ebe33f49d..a48c26f65 100644 --- a/userge/core/_database/db.py +++ b/userge/core/_database/db.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from pymongo import MongoClient from pymongo.collection import Collection from userge.utils import Config, logging diff --git a/userge/core/_userge/__init__.py b/userge/core/_userge/__init__.py index 9b5af140d..12f73ef3e 100644 --- a/userge/core/_userge/__init__.py +++ b/userge/core/_userge/__init__.py @@ -1,2 +1,11 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from .client import Userge, Filters from .message import Message \ No newline at end of file diff --git a/userge/core/_userge/base.py b/userge/core/_userge/base.py index 1ccaa1ca4..5a683a195 100644 --- a/userge/core/_userge/base.py +++ b/userge/core/_userge/base.py @@ -1,10 +1,41 @@ -from pyrogram import Client +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. -class Base(Client): +from pyrogram import Client, Message + + +class BaseMessage(Message): + """ + Base Class for Message. + """ + + @property + def process_is_canceled(self) -> bool: + pass + + +class BaseCLogger: + """ + Base Class for CLogger. + """ + + async def fwd_msg(self, + message: BaseMessage, + as_copy: bool = False, + remove_caption: bool = False) -> None: + pass + + +class BaseClient(Client): """ - Base Class for Userge. + Base Class for Client. """ - def getCLogger(self, name: str): - pass \ No newline at end of file + def getCLogger(self, name: str) -> BaseCLogger: + pass diff --git a/userge/core/_userge/client.py b/userge/core/_userge/client.py index d577f12a6..b52632fea 100644 --- a/userge/core/_userge/client.py +++ b/userge/core/_userge/client.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import re import asyncio import importlib @@ -13,41 +22,42 @@ from userge.utils import Config, logging from userge.plugins import get_all_plugins -from .base import Base +from .base import BaseClient from .message import Message from .logger import CLogger PYROFUNC = Callable[[Message], Any] +PLUGINS_PATH = "userge.plugins.{}" + +LOG = logging.getLogger(__name__) +LOG_STR = "<<>>" -class Userge(Base): +class Userge(BaseClient): """ Userge: userbot """ - __LOG = logging.getLogger(__name__) - __LOG_STR = "<<>>" - __PLUGINS_PATH = "userge.plugins.{}" - def __init__(self) -> None: self.__help_dict: Dict[str, Dict[str, str]] = {} self.__imported: List[ModuleType] = [] - self.__LOG.info( - self.__LOG_STR.format("Setting Userge Configs")) + LOG.info( + LOG_STR.format("Setting Userge Configs")) super().__init__(Config.HU_STRING_SESSION, api_id=Config.API_ID, api_hash=Config.API_HASH) - def getLogger(self, name: str) -> logging.Logger: + @staticmethod + def getLogger(name: str) -> logging.Logger: """ This will return new logger object. """ - self.__LOG.info( - self.__LOG_STR.format(f"Creating Logger => {name}")) + LOG.info( + LOG_STR.format(f"Creating Logger => {name}")) return logging.getLogger(name) @@ -56,32 +66,32 @@ def getCLogger(self, name: str) -> CLogger: This will return new channel logger object. """ - self.__LOG.info( - self.__LOG_STR.format(f"Creating CLogger => {name}")) + LOG.info( + LOG_STR.format(f"Creating CLogger => {name}")) return CLogger(self, name) - def new_thread(self, func: Callable) -> Callable: + @staticmethod + def new_thread(func: Callable[[Any], Any]) -> Callable[[Any], Any]: """ Run funcion in new thread. """ - async def thread(*args, **kwargs): + async def thread(*args: Any) -> Any: loop = asyncio.get_event_loop() - self.__LOG.info( - self.__LOG_STR.format("Creating new thread")) + LOG.info( + LOG_STR.format("Creating new thread")) with ThreadPoolExecutor() as pool: - return await loop.run_in_executor(pool, func, - *args, **kwargs) + return await loop.run_in_executor(pool, func, *args) return thread async def get_user_dict(self, user_id: int) -> Dict[str, str]: """ This will return user `Dict` which contains - `fname`, `lname`, `flname` and `uname`. + `fname`(first name), `lname`(last name), `flname`(full name) and `uname`(username). """ user_obj = await self.get_users(user_id) @@ -107,6 +117,7 @@ async def get_user_dict(self, user_id: int) -> Dict[str, str]: async def send_message(self, chat_id: Union[int, str], text: str, + del_in: int = -1, log: bool = False, parse_mode: Union[str, object] = object, disable_web_page_preview: Optional[bool] = None, @@ -116,7 +127,7 @@ async def send_message(self, reply_markup: Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, - ForceReply] = None) -> Message: + ForceReply] = None) -> Union[Message, bool]: """ Send text messages. @@ -130,8 +141,10 @@ async def send_message(self, For a contact that exists in your Telegram address book you can use his phone number (str). text (``str``): Text of the message to be sent. + del_in (``int``): + Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. parse_mode (``str``, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -151,7 +164,7 @@ async def send_message(self, Additional interface options. An object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. Returns: - :obj:`Message`: On success, the sent text message is returned. + :obj:`Message`: On success, the sent text message or True is returned. """ msg = await super().send_message(chat_id=chat_id, @@ -166,6 +179,10 @@ async def send_message(self, if log: await self.getCLogger(__name__).fwd_msg(msg) + if del_in > 0: + await asyncio.sleep(del_in) + return await msg.delete() + return Message(self, msg) def on_cmd(self, @@ -175,7 +192,7 @@ def on_cmd(self, name: str = '', trigger: str = '.', only_me: bool = True, - **kwargs) -> Callable[[PYROFUNC], PYROFUNC]: + **kwargs: Union[str, bool]) -> Callable[[PYROFUNC], PYROFUNC]: """ Decorator for handling messages. @@ -281,10 +298,10 @@ def __add_help(self, module: str, cname: str = '', chelp: str = '', - **_) -> None: + **_: Union[str, bool]) -> None: if cname: - self.__LOG.info( - self.__LOG_STR.format(f"Updating Help Dict => [ {cname} : {chelp} ]")) + LOG.info( + LOG_STR.format(f"Updating Help Dict => [ {cname} : {chelp} ]")) mname = module.split('.')[-1] @@ -298,17 +315,17 @@ def __build_decorator(self, log: str, filters: Filters, group: int, - **kwargs) -> Callable[[PYROFUNC], PYROFUNC]: + **kwargs: Union[str, bool]) -> Callable[[PYROFUNC], PYROFUNC]: def __decorator(func: PYROFUNC) -> PYROFUNC: - async def __template(_: Base, message: Message) -> None: + async def __template(_: BaseClient, message: Message) -> None: await func(Message(self, message, **kwargs)) - self.__LOG.info( - self.__LOG_STR.format(f"Loading => [ async def {func.__name__}(message) ] " + \ - f"from {func.__module__} `{log}`")) + LOG.info( + LOG_STR.format(f"Loading => [ async def {func.__name__}(message) ] " + \ + f"from {func.__module__} `{log}`")) self.__add_help(func.__module__, **kwargs) @@ -323,14 +340,14 @@ def load_plugin(self, name: str) -> None: Load plugin to Userge. """ - self.__LOG.info( - self.__LOG_STR.format(f"Importing {name}")) + LOG.info( + LOG_STR.format(f"Importing {name}")) self.__imported.append( - importlib.import_module(self.__PLUGINS_PATH.format(name))) + importlib.import_module(PLUGINS_PATH.format(name))) - self.__LOG.info( - self.__LOG_STR.format( + LOG.info( + LOG_STR.format( f"Imported {self.__imported[-1].__name__} Plugin Successfully")) def load_plugins(self) -> None: @@ -340,20 +357,20 @@ def load_plugins(self) -> None: self.__imported.clear() - self.__LOG.info( - self.__LOG_STR.format("Importing All Plugins")) + LOG.info( + LOG_STR.format("Importing All Plugins")) for name in get_all_plugins(): try: self.load_plugin(name) except ImportError as i_e: - self.__LOG.error(i_e) + LOG.error(i_e) - self.__LOG.info( - self.__LOG_STR.format( + LOG.info( + LOG_STR.format( f"Imported ({len(self.__imported)}) Plugins => " + \ - str([i.__name__ for i in self.__imported]))) + str([i.__name__ for i in self.__imported]))) async def reload_plugins(self) -> int: """ @@ -363,21 +380,21 @@ async def reload_plugins(self) -> int: self.__help_dict.clear() reloaded: List[str] = [] - self.__LOG.info( - self.__LOG_STR.format("Reloading All Plugins")) + LOG.info( + LOG_STR.format("Reloading All Plugins")) for imported in self.__imported: try: reloaded_ = importlib.reload(imported) except ImportError as i_e: - self.__LOG.error(i_e) + LOG.error(i_e) else: reloaded.append(reloaded_.__name__) - self.__LOG.info( - self.__LOG_STR.format( + LOG.info( + LOG_STR.format( f"Reloaded {len(reloaded)} Plugins => {reloaded}")) return len(reloaded) @@ -387,26 +404,26 @@ async def restart(self) -> None: Restart the Userge. """ - self.__LOG.info( - self.__LOG_STR.format("Restarting Userge")) + LOG.info( + LOG_STR.format("Restarting Userge")) await self.stop() await self.reload_plugins() await self.start() - self.__LOG.info( - self.__LOG_STR.format("Restarted Userge")) + LOG.info( + LOG_STR.format("Restarted Userge")) def begin(self) -> None: """ This will start the Userge. """ - self.__LOG.info( - self.__LOG_STR.format("Starting Userge")) + LOG.info( + LOG_STR.format("Starting Userge")) nest_asyncio.apply() self.run() - self.__LOG.info( - self.__LOG_STR.format("Exiting Userge")) + LOG.info( + LOG_STR.format("Exiting Userge")) diff --git a/userge/core/_userge/logger.py b/userge/core/_userge/logger.py index 696be6258..d53f2ba98 100644 --- a/userge/core/_userge/logger.py +++ b/userge/core/_userge/logger.py @@ -1,17 +1,25 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge.utils import Config, logging -from .base import Base -from .message import Message +from .base import BaseCLogger, BaseClient, BaseMessage +LOG = logging.getLogger(__name__) +LOG_STR = "<<>>" -class CLogger: + +class CLogger(BaseCLogger): """ Channel logger for Userge. """ - __LOG = logging.getLogger(__name__) - __LOG_STR = "<<>>" - - def __init__(self, client: Base, name: str) -> None: + def __init__(self, client: BaseClient, name: str) -> None: self.__client = client self.__string = "**logger** : `" + name + "`\n\n{}" @@ -26,17 +34,17 @@ async def log(self, text: str) -> None: None """ - self.__LOG.info( - self.__LOG_STR.format(f"logging text : {text} to channel : {Config.LOG_CHANNEL_ID}")) + LOG.info( + LOG_STR.format(f"logging text : {text} to channel : {Config.LOG_CHANNEL_ID}")) if Config.LOG_CHANNEL_ID: await self.__client.send_message(chat_id=Config.LOG_CHANNEL_ID, text=self.__string.format(text)) async def fwd_msg(self, - message: Message, - as_copy=False, - remove_caption=False) -> None: + message: BaseMessage, + as_copy: bool = False, + remove_caption: bool = False) -> None: """ forward message to log channel. @@ -55,8 +63,8 @@ async def fwd_msg(self, None """ - self.__LOG.info( - self.__LOG_STR.format(f"logging msg : {message} to channel : {Config.LOG_CHANNEL_ID}")) + LOG.info( + LOG_STR.format(f"logging msg : {message} to channel : {Config.LOG_CHANNEL_ID}")) if Config.LOG_CHANNEL_ID: await self.__client.forward_messages(chat_id=Config.LOG_CHANNEL_ID, diff --git a/userge/core/_userge/message.py b/userge/core/_userge/message.py index c066e2945..02bc9fc8e 100644 --- a/userge/core/_userge/message.py +++ b/userge/core/_userge/message.py @@ -1,35 +1,53 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import re import os import asyncio -from typing import Dict, Union, Optional, Sequence +from typing import List, Dict, Union, Optional, Sequence -from pyrogram import Message as Msg, InlineKeyboardMarkup -from pyrogram.errors.exceptions import MessageAuthorRequired +from pyrogram import InlineKeyboardMarkup +from pyrogram.errors.exceptions import MessageAuthorRequired, MessageTooLong +from pyrogram.errors.exceptions.bad_request_400 import MessageNotModified from userge.utils import logging -from .base import Base +from .base import BaseClient, BaseMessage + +CANCEL_LIST: List[int] = [] +ERROR_MSG_DELETE_TIMEOUT = 5 +ERROR_STRING = "**ERROR**: `{}`" +LOG = logging.getLogger(__name__) +LOG_STR = "<<>>" -class Message(Msg): + +class Message(BaseMessage): """ Moded Message Class For Userge """ - __LOG = logging.getLogger(__name__) - __LOG_STR = "<<>>" - __ERROR_MSG_DELETE_TIMEOUT = 5 - __ERROR_STRING = "**ERROR**: `{}`" - def __init__(self, - client: Base, - message: Msg, - **kwargs) -> None: + client: BaseClient, + message: BaseMessage, + **kwargs: Union[str, bool]) -> None: super().__init__(client=client, **self.__msg_to_dict(message)) + self.reply_to_message: BaseMessage + + if self.reply_to_message: + self.reply_to_message = self.__class__(self._client, self.reply_to_message) + self.__channel = client.getCLogger(__name__) self.__filtered = False + self.__process_canceled = False self.__filtered_input_str: str = '' self.__flags: Dict[str, str] = {} self.__kwargs = kwargs @@ -47,6 +65,19 @@ def input_str(self) -> str: return '' + @property + def input_or_reply_str(self) -> str: + """ + Returns the input string without command or replied msg text. + """ + + input_ = self.input_str + + if self.reply_to_message: + input_ = (self.reply_to_message.text or '').strip() + + return input_ + @property def filtered_input_str(self) -> str: """ @@ -67,10 +98,29 @@ def flags(self) -> Dict[str, str]: return self.__flags - def __msg_to_dict(self, message: Msg) -> Dict[str, object]: + @property + def process_is_canceled(self) -> bool: + """ + Returns True if process canceled. + """ + + if self.message_id in CANCEL_LIST: + CANCEL_LIST.remove(self.message_id) + self.__process_canceled = True + + return self.__process_canceled - self.__LOG.info( - self.__LOG_STR.format("Creating moded message object")) + def cancel_the_process(self) -> None: + """ + Set True to the self.process_is_canceled. + """ + + CANCEL_LIST.append(self.message_id) + + def __msg_to_dict(self, message: BaseMessage) -> Dict[str, object]: + + LOG.info( + LOG_STR.format("Creating moded message object")) kwargs_ = vars(message) del message @@ -83,6 +133,9 @@ def __msg_to_dict(self, message: Msg) -> Dict[str, object]: if '_Message__filtered' in kwargs_: del kwargs_['_Message__filtered'] + if '_Message__process_canceled' in kwargs_: + del kwargs_['_Message__process_canceled'] + if '_Message__filtered_input_str' in kwargs_: del kwargs_['_Message__filtered_input_str'] @@ -97,9 +150,9 @@ def __msg_to_dict(self, message: Msg) -> Dict[str, object]: def __filter(self) -> None: if not self.__filtered: - prefix: str = self.__kwargs.get('prefix', '-') - del_pre: bool = self.__kwargs.get('del_pre', False) - input_str: str = self.input_str + prefix = str(self.__kwargs.get('prefix', '-')) + del_pre = bool(self.__kwargs.get('del_pre', False)) + input_str = self.input_str for i in input_str.strip().split(): match = re.match(f"({prefix}[a-z]+)($|[0-9]+)?$", i) @@ -114,8 +167,8 @@ def __filter(self) -> None: self.__filtered_input_str = self.__filtered_input_str.strip() - self.__LOG.info( - self.__LOG_STR.format( + LOG.info( + LOG_STR.format( f"Filtered Input String => [ {self.__filtered_input_str}, {self.__flags} ]")) self.__filtered = True @@ -125,7 +178,7 @@ async def send_as_file(self, filename: str = "output.txt", caption: str = '', log: bool = False, - delete_message: bool = True) -> Msg: + delete_message: bool = True) -> BaseMessage: """ You can send large outputs as file @@ -140,7 +193,7 @@ async def send_as_file(self, caption (``str``, *optional*): caption for output file. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. delete_message (``bool``, *optional*): If ``True``, the message will be deleted after sending the file. Returns: @@ -153,8 +206,8 @@ async def send_as_file(self, reply_to_id = self.reply_to_message.message_id if self.reply_to_message \ else self.message_id - self.__LOG.info( - self.__LOG_STR.format(f"Uploading {filename} To Telegram")) + LOG.info( + LOG_STR.format(f"Uploading {filename} To Telegram")) msg = await self._client.send_document(chat_id=self.chat.id, document=filename, @@ -181,7 +234,7 @@ async def reply(self, disable_web_page_preview: Optional[bool] = None, disable_notification: Optional[bool] = None, reply_to_message_id: Optional[int] = None, - reply_markup: InlineKeyboardMarkup = None) -> Msg: + reply_markup: InlineKeyboardMarkup = None) -> Union[BaseMessage, bool]: """ Example: message.reply("hello") @@ -192,7 +245,7 @@ async def reply(self, del_in (``int``): Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. quote (``bool``, *optional*): If ``True``, the message will be sent as a reply to this message. If *reply_to_message_id* is passed, this parameter will be ignored. @@ -214,7 +267,7 @@ async def reply(self, Additional interface options. An object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. Returns: - On success, the sent Message is returned. + On success, the sent Message or True is returned. Raises: RPCError: In case of a Telegram RPC error. """ @@ -238,7 +291,7 @@ async def reply(self, if del_in > 0: await asyncio.sleep(del_in) - await msg.delete() + return await msg.delete() return Message(self._client, msg) @@ -250,7 +303,7 @@ async def edit(self, log: bool = False, parse_mode: Union[str, object] = object, disable_web_page_preview: Optional[bool] = None, - reply_markup: InlineKeyboardMarkup = None) -> Msg: + reply_markup: InlineKeyboardMarkup = None) -> Union[BaseMessage, bool]: """ Example: message.edit_text("hello") @@ -261,7 +314,7 @@ async def edit(self, del_in (``int``): Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. parse_mode (``str``, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -273,7 +326,7 @@ async def edit(self, reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message` is returned. + On success, the edited :obj:`Message` or True is returned. Raises: RPCError: In case of a Telegram RPC error. """ @@ -290,7 +343,7 @@ async def edit(self, if del_in > 0: await asyncio.sleep(del_in) - await msg.delete() + return await msg.delete() return Message(self._client, msg) @@ -303,10 +356,10 @@ async def force_edit(self, parse_mode: Union[str, object] = object, disable_web_page_preview: Optional[bool] = None, reply_markup: InlineKeyboardMarkup = None, - **kwargs) -> Msg: + **kwargs) -> Union[BaseMessage, bool]: """ - This will first try to edit that message. If it found any errors - it will reply that message. + This will first try to message.edit. If it raise MessageAuthorRequired error, + run message.reply. Example: message.force_edit(text='force_edit', del_in=3) @@ -317,7 +370,7 @@ async def force_edit(self, del_in (``int``): Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. parse_mode (``str``, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -328,33 +381,27 @@ async def force_edit(self, Disables link previews for links in this message. reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. - **kwargs (for reply message) + **kwargs (for message.reply) Returns: - On success, the edited or replied :obj:`Message` is returned. + On success, the edited or replied :obj:`Message` or True is returned. """ try: - msg = await self.edit(text=text, - del_in=del_in, - log=log, - parse_mode=parse_mode, - disable_web_page_preview=disable_web_page_preview, - reply_markup=reply_markup) - - except MessageAuthorRequired: - msg = await self.reply(text=text, + return await self.edit(text=text, del_in=del_in, log=log, parse_mode=parse_mode, disable_web_page_preview=disable_web_page_preview, - reply_markup=reply_markup, - **kwargs) - - if del_in > 0: - await asyncio.sleep(del_in) - await msg.delete() + reply_markup=reply_markup) - return Message(self._client, msg) + except MessageAuthorRequired: + return await self.reply(text=text, + del_in=del_in, + log=log, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup, + **kwargs) async def err(self, text: str, @@ -362,7 +409,7 @@ async def err(self, log: bool = False, parse_mode: Union[str, object] = object, disable_web_page_preview: Optional[bool] = None, - reply_markup: InlineKeyboardMarkup = None) -> Msg: + reply_markup: InlineKeyboardMarkup = None) -> Union[BaseMessage, bool]: """ You can send error messages using this method @@ -375,7 +422,7 @@ async def err(self, del_in (``int``): Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. parse_mode (``str``, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -387,13 +434,13 @@ async def err(self, reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. Returns: - On success, the edited :obj:`Message` is returned. + On success, the edited :obj:`Message` or True is returned. """ del_in = del_in if del_in > 0 \ - else self.__ERROR_MSG_DELETE_TIMEOUT + else ERROR_MSG_DELETE_TIMEOUT - return await self.edit(text=self.__ERROR_STRING.format(text), + return await self.edit(text=ERROR_STRING.format(text), del_in=del_in, log=log, parse_mode=parse_mode, @@ -407,10 +454,10 @@ async def force_err(self, parse_mode: Union[str, object] = object, disable_web_page_preview: Optional[bool] = None, reply_markup: InlineKeyboardMarkup = None, - **kwargs) -> Msg: + **kwargs) -> Union[BaseMessage, bool]: """ - This will first try to edit that message. If it found any errors - it will reply that message. + This will first try to message.edit. If it raise MessageAuthorRequired error, + run message.reply. Example: message.force_err(text='force_err', del_in=3) @@ -421,7 +468,7 @@ async def force_err(self, del_in (``int``): Time in Seconds for delete that message. log (``bool``, *optional*): - If ``True``, the message will be log to the log channel. + If ``True``, the message will be forwarded to the log channel. parse_mode (``str``, *optional*): By default, texts are parsed using both Markdown and HTML styles. You can combine both syntaxes together. @@ -432,18 +479,241 @@ async def force_err(self, Disables link previews for links in this message. reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): An InlineKeyboardMarkup object. - **kwargs (for reply message) + **kwargs (for message.reply) Returns: - On success, the edited or replied :obj:`Message` is returned. + On success, the edited or replied :obj:`Message` or True is returned. """ del_in = del_in if del_in > 0 \ - else self.__ERROR_MSG_DELETE_TIMEOUT + else ERROR_MSG_DELETE_TIMEOUT - return await self.force_edit(text=self.__ERROR_STRING.format(text), + return await self.force_edit(text=ERROR_STRING.format(text), del_in=del_in, log=log, parse_mode=parse_mode, disable_web_page_preview=disable_web_page_preview, reply_markup=reply_markup, **kwargs) + + async def try_to_edit(self, + text: str, + del_in: int = -1, + log: bool = False, + parse_mode: Union[str, object] = object, + disable_web_page_preview: Optional[bool] = None, + reply_markup: InlineKeyboardMarkup = None) -> Union[BaseMessage, bool]: + + """ + This will first try to message.edit. If it raise MessageNotModified error, + just pass it. + + Example: + message.try_to_edit("hello") + + Parameters: + text (``str``): + New text of the message. + del_in (``int``): + Time in Seconds for delete that message. + log (``bool``, *optional*): + If ``True``, the message will be forwarded to the log channel. + parse_mode (``str``, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + Pass "markdown" or "md" to enable Markdown-style parsing only. + Pass "html" to enable HTML-style parsing only. + Pass None to completely disable style parsing. + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + Returns: + On success, the edited :obj:`Message` or True is returned. + Raises: + RPCError: In case of a Telegram RPC error. + """ + + try: + return await self.edit(text=text, + del_in=del_in, + log=log, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup) + + except MessageNotModified: + return False + + async def edit_or_send_as_file(self, + text: str, + del_in: int = -1, + log: bool = False, + parse_mode: Union[str, object] = object, + disable_web_page_preview: Optional[bool] = None, + reply_markup: InlineKeyboardMarkup = None, + **kwargs) -> Union[BaseMessage, bool]: + + """ + This will first try to message.edit. If it raise MessageTooLong error, + run message.send_as_file. + + Example: + message.edit_or_send_as_file("some huge text") + + Parameters: + text (``str``): + New text of the message. + del_in (``int``): + Time in Seconds for delete that message. + log (``bool``, *optional*): + If ``True``, the message will be forwarded to the log channel. + parse_mode (``str``, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + Pass "markdown" or "md" to enable Markdown-style parsing only. + Pass "html" to enable HTML-style parsing only. + Pass None to completely disable style parsing. + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + **kwargs (for message.send_as_file) + Returns: + On success, the edited :obj:`Message` or True is returned. + Raises: + RPCError: In case of a Telegram RPC error. + """ + + try: + return await self.edit(text=text, + del_in=del_in, + log=log, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup) + + except MessageTooLong: + return await self.send_as_file(text=text, log=log, **kwargs) + + async def reply_or_send_as_file(self, + text: str, + del_in: int = -1, + log: bool = False, + quote: Optional[bool] = None, + parse_mode: Union[str, object] = object, + disable_web_page_preview: Optional[bool] = None, + disable_notification: Optional[bool] = None, + reply_to_message_id: Optional[int] = None, + reply_markup: InlineKeyboardMarkup = None, + **kwargs) -> Union[BaseMessage, bool]: + + """ + This will first try to message.reply. If it raise MessageTooLong error, + run message.send_as_file. + + Example: + message.reply_or_send_as_file("some huge text") + + Parameters: + text (``str``): + Text of the message to be sent. + del_in (``int``): + Time in Seconds for delete that message. + log (``bool``, *optional*): + If ``True``, the message will be forwarded to the log channel. + quote (``bool``, *optional*): + If ``True``, the message will be sent as a reply to this message. + If *reply_to_message_id* is passed, this parameter will be ignored. + Defaults to ``True`` in group chats and ``False`` in private chats. + parse_mode (``str``, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + Pass "markdown" or "md" to enable Markdown-style parsing only. + Pass "html" to enable HTML-style parsing only. + Pass None to completely disable style parsing. + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + disable_notification (``bool``, *optional*): + Sends the message silently. + Users will receive a notification with no sound. + reply_to_message_id (``int``, *optional*): + If the message is a reply, ID of the original message. + reply_markup (:obj:`InlineKeyboardMarkup` | :obj:`ReplyKeyboardMarkup` | :obj:`ReplyKeyboardRemove` | :obj:`ForceReply`, *optional*): + Additional interface options. An object for an inline keyboard, custom reply keyboard, + instructions to remove reply keyboard or to force a reply from the user. + **kwargs (for message.send_as_file) + Returns: + On success, the sent Message or True is returned. + Raises: + RPCError: In case of a Telegram RPC error. + """ + + try: + return await self.reply(text=text, + del_in=del_in, + log=log, + quote=quote, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + reply_markup=reply_markup) + + except MessageTooLong: + return await self.send_as_file(text=text, log=log, **kwargs) + + async def force_edit_or_send_as_file(self, + text: str, + del_in: int = -1, + log: bool = False, + parse_mode: Union[str, object] = object, + disable_web_page_preview: Optional[bool] = None, + reply_markup: InlineKeyboardMarkup = None, + **kwargs) -> Union[BaseMessage, bool]: + + """ + This will first try to message.edit_or_send_as_file. If it raise MessageAuthorRequired error, + run message.reply_or_send_as_file. + + Example: + message.force_edit_or_send_as_file("some huge text") + + Parameters: + text (``str``): + New text of the message. + del_in (``int``): + Time in Seconds for delete that message. + log (``bool``, *optional*): + If ``True``, the message will be forwarded to the log channel. + parse_mode (``str``, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + Pass "markdown" or "md" to enable Markdown-style parsing only. + Pass "html" to enable HTML-style parsing only. + Pass None to completely disable style parsing. + disable_web_page_preview (``bool``, *optional*): + Disables link previews for links in this message. + reply_markup (:obj:`InlineKeyboardMarkup`, *optional*): + An InlineKeyboardMarkup object. + **kwargs (for message.reply and message.send_as_file) + Returns: + On success, the edited or replied :obj:`Message` or True is returned. + """ + + try: + return await self.edit_or_send_as_file(text=text, + del_in=del_in, + log=log, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup, + **kwargs) + + except MessageAuthorRequired: + return await self.reply_or_send_as_file(text=text, + del_in=del_in, + log=log, + parse_mode=parse_mode, + disable_web_page_preview=disable_web_page_preview, + reply_markup=reply_markup, + **kwargs) diff --git a/userge/plugins/__init__.py b/userge/plugins/__init__.py index 8196bb769..ad79fd44b 100644 --- a/userge/plugins/__init__.py +++ b/userge/plugins/__init__.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from os.path import dirname from userge.utils import get_import_path, logging diff --git a/userge/plugins/admin/__init__.py b/userge/plugins/admin/__init__.py index e69de29bb..4bba28ab4 100644 --- a/userge/plugins/admin/__init__.py +++ b/userge/plugins/admin/__init__.py @@ -0,0 +1,7 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. \ No newline at end of file diff --git a/userge/plugins/admin/gadmin.py b/userge/plugins/admin/gadmin.py index 461813fa5..197033816 100644 --- a/userge/plugins/admin/gadmin.py +++ b/userge/plugins/admin/gadmin.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message CHANNEL = userge.getCLogger(__name__) diff --git a/userge/plugins/admin/lock.py b/userge/plugins/admin/lock.py index be8ba7011..34bac22ba 100644 --- a/userge/plugins/admin/lock.py +++ b/userge/plugins/admin/lock.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os from pyrogram import ChatPermissions from userge import userge, Message diff --git a/userge/plugins/fun/__init__.py b/userge/plugins/fun/__init__.py index e69de29bb..4bba28ab4 100644 --- a/userge/plugins/fun/__init__.py +++ b/userge/plugins/fun/__init__.py @@ -0,0 +1,7 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. \ No newline at end of file diff --git a/userge/plugins/fun/alive.py b/userge/plugins/fun/alive.py index f84dd1063..bb0e9c75d 100644 --- a/userge/plugins/fun/alive.py +++ b/userge/plugins/fun/alive.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from pyrogram.errors.exceptions import FileIdInvalid, FileReferenceEmpty from userge import userge, Message diff --git a/userge/plugins/fun/convert.py b/userge/plugins/fun/convert.py index 25028d47c..898aadfeb 100644 --- a/userge/plugins/fun/convert.py +++ b/userge/plugins/fun/convert.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/fun/memes.py b/userge/plugins/fun/memes.py new file mode 100644 index 000000000..43ed9367e --- /dev/null +++ b/userge/plugins/fun/memes.py @@ -0,0 +1,872 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + +import os +import time +from re import sub +from asyncio import sleep +from collections import deque +from random import choice, getrandbits, randint + +import wget +import requests +from cowpy import cow + +from userge import userge, Message + + +THROW = ("throws", "flings", "chucks", "hurls") + +HIT = ("hits", "whacks", "slaps", "smacks", "bashes") + +WHERE = ("in the chest", "on the head", "on the butt", "on the crotch") + +METOOSTR = ("Me too thanks", "Haha yes, me too", "Same lol", "Me irl", "Same here", "Haha yes", "Me rn") + +HELLOSTR = ( + "Hi !", "‘Ello, gov'nor!", "What’s crackin’?", "‘Sup, homeslice?", "Howdy, howdy ,howdy!", + "Hello, who's there, I'm talking.", "You know who this is.", "Yo!", "Whaddup.", "Greetings and salutations!", + "Hello, sunshine!", "Hey, howdy, hi!", "What’s kickin’, little chicken?", "Peek-a-boo!", "Howdy-doody!", + "Hey there, freshman!", "I come in peace!", "Ahoy, matey!", "Hiya!") + +ITEMS = ( + "cast iron skillet", "large trout", "baseball bat", "cricket bat", "wooden cane", "nail", "printer", + "shovel", "pair of trousers", "CRT monitor", "diamond sword", "baguette", "physics textbook", + "toaster", "portrait of Richard Stallman", "television", "mau5head", "five ton truck", "roll of duct tape", + "book", "laptop", "old television", "sack of rocks", "rainbow trout", "cobblestone block", "lava bucket", + "rubber chicken", "spiked bat", "gold block", "fire extinguisher", "heavy rock", "chunk of dirt", + "beehive", "piece of rotten meat", "bear", "ton of bricks") + +RUNS_STR = ( + "Runs to Thanos..", + "Runs far, far away from earth..", + "Running faster than Bolt coz i'mma userbot !!", + "Runs to Marie..", + "This Group is too cancerous to deal with.", + "Cya bois", + "Kys", + "I go away", + "I am just walking off, coz me is too fat.", + "I Fugged off!", + "Will run for chocolate.", + "I run because I really like food.", + "Running...\nbecause dieting is not an option.", + "Wicked fast runnah", + "If you wanna catch me, you got to be fast...\nIf you wanna stay with me, you got to be good...\nBut if you wanna pass me...\nYou've got to be kidding.", + "Anyone can run a hundred meters, it's the next forty-two thousand and two hundred that count.", + "Why are all these people following me?", + "Are the kids still chasing me?", + "Running a marathon...there's an app for that.") + +SLAP_TEMPLATES = ( + "{hits} {victim} with a {item}.", + "{hits} {victim} in the face with a {item}.", + "{hits} {victim} around a bit with a {item}.", + "{throws} a {item} at {victim}.", + "grabs a {item} and {throws} it at {victim}'s face.", + "{hits} a {item} at {victim}.", "{throws} a few {item} at {victim}.", + "grabs a {item} and {throws} it in {victim}'s face.", + "launches a {item} in {victim}'s general direction.", + "sits on {victim}'s face while slamming a {item} {where}.", + "starts slapping {victim} silly with a {item}.", + "pins {victim} down and repeatedly {hits} them with a {item}.", + "grabs up a {item} and {hits} {victim} with it.", + "starts slapping {victim} silly with a {item}.", + "holds {victim} down and repeatedly {hits} them with a {item}.", + "prods {victim} with a {item}.", + "picks up a {item} and {hits} {victim} with it.", + "ties {victim} to a chair and {throws} a {item} at them.", + "{hits} {victim} {where} with a {item}.", + "ties {victim} to a pole and whips them {where} with a {item}." + "gave a friendly push to help {victim} learn to swim in lava.", + "sent {victim} to /dev/null.", "sent {victim} down the memory hole.", + "beheaded {victim}.", "threw {victim} off a building.", + "replaced all of {victim}'s music with Nickelback.", + "spammed {victim}'s email.", "made {victim} a knuckle sandwich.", + "slapped {victim} with pure nothing.", + "hit {victim} with a small, interstellar spaceship.", + "quickscoped {victim}.", "put {victim} in check-mate.", + "RSA-encrypted {victim} and deleted the private key.", + "put {victim} in the friendzone.", + "slaps {victim} with a DMCA takedown request!") + +CHASE_STR = ( + "Where do you think you're going?", + "Huh? what? did they get away?", + "ZZzzZZzz... Huh? what? oh, just them again, nevermind.", + "Get back here!", + "Not so fast...", + "Look out for the wall!", + "Don't leave me alone with them!!", + "You run, you die.", + "Jokes on you, I'm everywhere", + "You're gonna regret that...", + "You could also try /kickme, I hear that's fun.", + "Go bother someone else, no-one here cares.", + "You can run, but you can't hide.", + "Is that all you've got?", + "I'm behind you...", + "You've got company!", + "We can do this the easy way, or the hard way.", + "You just don't get it, do you?", + "Yeah, you better run!", + "Please, remind me how much I care?", + "I'd run faster if I were you.", + "That's definitely the droid we're looking for.", + "May the odds be ever in your favour.", + "Famous last words.", + "And they disappeared forever, never to be seen again.", + "\"Oh, look at me! I'm so cool, I can run from a bot!\" - this person", + "Yeah yeah, just tap /kickme already.", + "Here, take this ring and head to Mordor while you're at it.", + "Legend has it, they're still running...", + "Unlike Harry Potter, your parents can't protect you from me.", + "Fear leads to anger. Anger leads to hate. Hate leads to suffering. If you keep running in fear, you might " + "be the next Vader.", + "Multiple calculations later, I have decided my interest in your shenanigans is exactly 0.", + "Legend has it, they're still running.", + "Keep it up, not sure we want you here anyway.", + "You're a wiza- Oh. Wait. You're not Harry, keep moving.", + "NO RUNNING IN THE HALLWAYS!", + "Hasta la vista, baby.", + "Who let the dogs out?", + "It's funny, because no one cares.", + "Ah, what a waste. I liked that one.", + "Frankly, my dear, I don't give a damn.", + "My milkshake brings all the boys to yard... So run faster!", + "You can't HANDLE the truth!", + "A long time ago, in a galaxy far far away... Someone would've cared about that. Not anymore though.", + "Hey, look at them! They're running from the inevitable banhammer... Cute.", + "Han shot first. So will I.", + "What are you running after, a white rabbit?", + "As The Doctor would say... RUN!") + +INSULT_STRINGS = ( + "Owww ... Such a stupid idiot.", + "Don't drink and type.", + "I think you should go home or better a mental asylum.", + "Command not found. Just like your brain.", + "Do you realize you are making a fool of yourself? Apparently not.", + "You can type better than that.", + "Bot rule 544 section 9 prevents me from replying to stupid humans like you.", + "Sorry, we do not sell brains.", + "Believe me you are not normal.", + "I bet your brain feels as good as new, seeing that you never use it.", + "If I wanted to kill myself I'd climb your ego and jump to your IQ.", + "Zombies eat brains... you're safe.", + "You didn't evolve from apes, they evolved from you.", + "Come back and talk to me when your I.Q. exceeds your age.", + "I'm not saying you're stupid, I'm just saying you've got bad luck when it comes to thinking.", + "What language are you speaking? Cause it sounds like bullshit.", + "Stupidity is not a crime so you are free to go.", + "You are proof that evolution CAN go in reverse.", + "I would ask you how old you are but I know you can't count that high.", + "As an outsider, what do you think of the human race?", + "Brains aren't everything. In your case they're nothing.", + "Ordinarily people live and learn. You just live.", + "I don't know what makes you so stupid, but it really works.", + "Keep talking, someday you'll say something intelligent! (I doubt it though)", + "Shock me, say something intelligent.", + "Your IQ's lower than your shoe size.", + "Alas! Your neurotransmitters are no more working.", + "Are you crazy you fool.", + "Everyone has the right to be stupid but you are abusing the privilege.", + "I'm sorry I hurt your feelings when I called you stupid. I thought you already knew that.", + "You should try tasting cyanide.", + "Your enzymes are meant to digest rat poison.", + "You should try sleeping forever.", + "Pick up a gun and shoot yourself.", + "You could make a world record by jumping from a plane without parachute.", + "Stop talking BS and jump in front of a running bullet train.", + "Try bathing with Hydrochloric Acid instead of water.", + "Try this: if you hold your breath underwater for an hour, you can then hold it forever.", + "Go Green! Stop inhaling Oxygen.", + "God was searching for you. You should leave to meet him.", + "give your 100%. Now, go donate blood.", + "Try jumping from a hundred story building but you can do it only once.", + "You should donate your brain seeing that you never used it.", + "Volunteer for target in an firing range.", + "Head shots are fun. Get yourself one.", + "You should try swimming with great white sharks.", + "You should paint yourself red and run in a bull marathon.", + "You can stay underwater for the rest of your life without coming back up.", + "How about you stop breathing for like 1 day? That'll be great.", + "Try provoking a tiger while you both are in a cage.", + "Have you tried shooting yourself as high as 100m using a canon.", + "You should try holding TNT in your mouth and igniting it.", + "Try playing catch and throw with RDX its fun.", + "I heard phogine is poisonous but i guess you wont mind inhaling it for fun.", + "Launch yourself into outer space while forgetting oxygen on Earth.", + "You should try playing snake and ladders, with real snakes and no ladders.", + "Dance naked on a couple of HT wires.", + "Active Volcano is the best swimming pool for you.", + "You should try hot bath in a volcano.", + "Try to spend one day in a coffin and it will be yours forever.", + "Hit Uranium with a slow moving neutron in your presence. It will be a worthwhile experience.", + "You can be the first person to step on sun. Have a try.") + +EMOJIS = ( + "😂", "😂", "👌", "✌", "💞", "👍", "👌", "💯", "🎶", "👀", "😂", "👓", "👏", "👐", "🍕", + "💥", "🍴", "💦", "💦", "🍑", "🍆", "😩", "😏", "👉👌", "👀", "👅", "😩", "🚰") + +ZALG_LIST = ( + ("̖", " ̗", " ̘", " ̙", " ̜", " ̝", " ̞", " ̟", " ̠", " ̤", " ̥", " ̦", " ̩", " ̪", " ̫", " ̬", " ̭", " ̮", + " ̯", " ̰", " ̱", " ̲", " ̳", " ̹", " ̺", " ̻", " ̼", " ͅ", " ͇", " ͈", " ͉", " ͍", " ͎", " ͓", " ͔", + " ͕", " ͖", " ͙", " ͚", " "), + + (" ̍", " ̎", " ̄", " ̅", " ̿", " ̑", " ̆", " ̐", " ͒", " ͗", " ͑", " ̇", " ̈", " ̊", " ͂", " ̓", " ̈́", " ͊", + " ͋", " ͌", " ̃", " ̂", " ̌", " ͐", " ́", " ̋", " ̏", " ̽", " ̉", " ͣ", " ͤ", " ͥ", " ͦ", " ͧ", " ͨ", " ͩ", + " ͪ", " ͫ", " ͬ", " ͭ", " ͮ", " ͯ", " ̾", " ͛", " ͆", " ̚"), + + (" ̕", " ̛", " ̀", " ́", " ͘", " ̡", " ̢", " ̧", " ̨", " ̴", " ̵", " ̶", " ͜", " ͝", " ͞", " ͟", " ͠", + " ͢", " ̸", " ̷", " ͡") +) + +UWUS = ( + "(・`ω´・)", ";;w;;", "owo", "UwU", ">w<", "^w^", r"\(^o\) (/o^)/", "( ^ _ ^)∠☆", "(ô_ô)", + "~:o", ";-;", "(*^*)", "(>_", "(♥_♥)", "*(^O^)*", "((+_+))") + +SHGS = ( + "┐(´д`)┌", "┐(´~`)┌", "┐(´ー`)┌", "┐( ̄ヘ ̄)┌", "╮(╯∀╰)╭", "╮(╯_╰)╭", "┐(´д`)┌", "┐(´∀`)┌", + "ʅ(́◡◝)ʃ", "┐(゚~゚)┌", "┐('д')┌", "┐(‘~`;)┌", "ヘ(´-`;)ヘ", "┐( -“-)┌", "ʅ(´◔౪◔)ʃ", "ヽ(゜~゜o)ノ", + "ヽ(~~~ )ノ", "┐(~ー~;)┌", "┐(-。ー;)┌", r"¯\_(ツ)_/¯", r"¯\_(⊙_ʖ⊙)_/¯", r"¯\_༼ ಥ ‿ ಥ ༽_/¯", "乁( ⁰͡ Ĺ̯ ⁰͡ ) ㄏ") + +CRI = ( + "أ‿أ", "╥﹏╥", "(;﹏;)", "(ToT)", "(┳Д┳)", "(ಥ﹏ಥ)", "(;へ:)", "(T_T)", "(πーπ)", "(T▽T)", + "(⋟﹏⋞)", "(iДi)", "(´Д⊂ヽ", "(;Д;)", "(>﹏<)", "(TдT)", "(つ﹏⊂)", "༼☯﹏☯༽", "(ノ﹏ヽ)", "(ノAヽ)", + "(╥_╥)", "(T⌓T)", "(༎ຶ⌑༎ຶ)", "(☍﹏⁰)。", "(ಥ_ʖಥ)", "(つд⊂)", "(≖͞_≖̥)", "(இ﹏இ`。)", "༼ಢ_ಢ༽", "༼ ༎ຶ ෴ ༎ຶ༽") + +FACEREACTS = ( + "ʘ‿ʘ", "ヾ(-_- )ゞ", "(っ˘ڡ˘ς)", "(´ж`ς)", "( ಠ ʖ̯ ಠ)", "(° ͜ʖ͡°)╭∩╮", "(ᵟຶ︵ ᵟຶ)", "(งツ)ว", + "ʚ(•`", "(っ▀¯▀)つ", "(◠﹏◠)", "( ͡ಠ ʖ̯ ͡ಠ)", "( ఠ ͟ʖ ఠ)", "(∩`-´)⊃━☆゚.*・。゚", "(⊃。•́‿•̀。)⊃", "(._.)", "{•̃_•̃}", + "(ᵔᴥᵔ)", "♨_♨", "⥀.⥀", "ح˚௰˚づ ", "(҂◡_◡)", "ƪ(ړײ)‎ƪ​​", "(っ•́。•́)♪♬", "◖ᵔᴥᵔ◗ ♪ ♫ ", "(☞゚ヮ゚)☞", "[¬º-°]¬", + "(Ծ‸ Ծ)", "(•̀ᴗ•́)و ̑̑", "ヾ(´〇`)ノ♪♪♪", "(ง'̀-'́)ง", "ლ(•́•́ლ)", "ʕ •́؈•̀ ₎", "♪♪ ヽ(ˇ∀ˇ )ゞ", "щ(゚Д゚щ)", + "( ˇ෴ˇ )", "눈_눈", "(๑•́ ₃ •̀๑) ", "( ˘ ³˘)♥ ", "ԅ(≖‿≖ԅ)", "♥‿♥", "◔_◔", "⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾", + "乁( ◔ ౪◔)「 ┑( ̄Д  ̄)┍", "( ఠൠఠ )ノ", "٩(๏_๏)۶", "┌(ㆆ㉨ㆆ)ʃ", "ఠ_ఠ", "(づ。◕‿‿◕。)づ", + "༼ ༎ຶ ෴ ༎ຶ༽", "。゚( ゚இ‸இ゚)゚。", "(づ ̄ ³ ̄)づ", "(⊙.☉)7", "ᕕ( ᐛ )ᕗ", "t(-_-t)", "(ಥ⌣ಥ)", "ヽ༼ ಠ益ಠ ༽ノ", + "༼∵༽ ༼⍨༽ ༼⍢༽ ༼⍤༽", "ミ●﹏☉ミ", "(⊙_◎)", "¿ⓧ_ⓧﮌ", "ಠ_ಠ", "(´・_・`)", "ᕦ(ò_óˇ)ᕤ", "⊙﹏⊙", "(╯°□°)╯︵ ┻━┻", + r"¯\_(⊙︿⊙)_/¯", "٩◔̯◔۶", "°‿‿°", "ᕙ(⇀‸↼‶)ᕗ", "⊂(◉‿◉)つ", "V•ᴥ•V", "q(❂‿❂)p", "ಥ_ಥ", "ฅ^•ﻌ•^ฅ", "ಥ﹏ಥ", + "( ^_^)o自自o(^_^ )", "ಠ‿ಠ", "ヽ(´▽`)/", "ᵒᴥᵒ#", "( ͡° ͜ʖ ͡°)", "┬─┬ ノ( ゜-゜ノ)", "ヽ(´ー`)ノ", + "☜(⌒▽⌒)☞", "ε=ε=ε=┌(;*´Д`)ノ", "(╬ ಠ益ಠ)", "┬─┬⃰͡ (ᵔᵕᵔ͜ )", "┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻", r"¯\_(ツ)_/¯", "ʕᵔᴥᵔʔ", + "(`・ω・´)", "ʕ•ᴥ•ʔ", "ლ(`ー´ლ)", "ʕʘ̅͜ʘ̅ʔ", "( ゚Д゚)", r"¯\(°_o)/¯", "(。◕‿◕。)", + "(ノಠ ∩ಠ)ノ彡( \\o°o)\\", "“ヽ(´▽`)ノ”",) + + +@userge.on_cmd(":/$", about="__Check yourself ;)__", name="kek", trigger='') +async def kek_(message: Message): + """kek""" + kek = ["/", "\\"] + for i in range(1, 15): + time.sleep(0.3) + await message.edit(":" + kek[i % 2]) + + +@userge.on_cmd("-_-$", about="__Ok...__", name="lol", trigger='') +async def lol_(message: Message): + """lol""" + lol = "-_ " + for _ in range(10): + lol = lol[:-1] + "_-" + await message.edit(lol, parse_mode="html") + + +@userge.on_cmd(";_;$", about="__Like `-_-` but crying__", name="fun", trigger='') +async def fun_(message: Message): + """fun""" + fun = ";_ " + for _ in range(10): + fun = fun[:-1] + "_;" + await message.edit(fun, parse_mode="html") + + +@userge.on_cmd("Oof$", about="__Ooooof__", trigger='') +async def Oof_(message: Message): + """Oof""" + Oof = "Oo " + for _ in range(15): + Oof = Oof[:-1] + "of" + await message.edit(Oof) + + +@userge.on_cmd("fp$", about="__Facepalm :P__") +async def facepalm_(message: Message): + """facepalm_""" + await message.edit("🤦‍♂") + + +@userge.on_cmd("cry$", about="__y u du dis, i cri__") +async def cry_(message: Message): + """cry""" + await message.edit(choice(CRI), parse_mode="html") + + +@userge.on_cmd("insult$", about="__Check yourself ;)__") +async def insult_(message: Message): + """insult""" + await message.edit(choice(INSULT_STRINGS), parse_mode="html") + + +@userge.on_cmd("hi", about="""\ +__Greet everyone!__ + +**Usage:** + + `.hi` + `.hi [emoji | character]` + `.hi [emoji | character] [emoji | character]`""") +async def hi_(message: Message): + """hi""" + input_str = message.input_str + if not input_str: + await message.edit(choice(HELLOSTR), parse_mode="html") + + else: + args = input_str.split() + if len(args) == 2: + paytext, filler = args + + else: + paytext = args[0] + filler = choice(EMOJIS) + + pay = "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}".format( + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 4, + paytext * 2 + filler * 4 + paytext * 2 + filler * 4, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 8 + filler * 2 + paytext * 2, + paytext * 8 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2, + paytext * 2 + filler * 4 + paytext * 2 + filler * 2 + paytext * 2) + + await message.edit(pay) + + +@userge.on_cmd("react$", about="__Make your userbot react to everything__") +async def react_(message: Message): + """react""" + await message.edit(choice(FACEREACTS), parse_mode="html") + + +@userge.on_cmd("shg$", about="__Shrug at it !!__") +async def shrugger(message: Message): + """shrugger""" + await message.edit(choice(SHGS), parse_mode="html") + + +@userge.on_cmd("chase$", about="__You better start running__") +async def chase_(message: Message): + """chase""" + await message.edit(choice(CHASE_STR), parse_mode="html") + + +@userge.on_cmd("run$", about="__Let Me Run, run, RUNNN!__") +async def run_(message: Message): + """run""" + await message.edit(choice(RUNS_STR), parse_mode="html") + + +@userge.on_cmd("metoo$", about="__Haha yes__") +async def metoo_(message: Message): + """metoo""" + await message.edit(choice(METOOSTR), parse_mode="html") + + +@userge.on_cmd("10iq$", about="__You retard !!__", name="10iq") +async def iqless(message: Message): + """iqless""" + await message.edit("♿") + + +@userge.on_cmd("moon$", about="__kensar moon animation__") +async def moon_(message: Message): + """moon""" + deq = deque(list("🌗🌘🌑🌒🌓🌔🌕🌖")) + + try: + for _ in range(32): + await sleep(0.1) + await message.edit("".join(deq)) + deq.rotate(1) + + except Exception: + return + + +@userge.on_cmd("clock$", about="__kensar clock animation__") +async def clock_(message: Message): + """clock""" + deq = deque(list("🕙🕘🕗🕖🕕🕔🕓🕒🕑🕐🕛")) + + try: + for _ in range(32): + await sleep(0.1) + await message.edit("".join(deq)) + deq.rotate(1) + + except Exception: + return + + +@userge.on_cmd("bt$", about="""\ +__Believe me, you will find this useful__ + +**Usage:** + + `.bt [reply to msg]`""") +async def bluetext(message: Message): + """bluetext""" + if message.reply_to_message: + await message.edit( + "/BLUETEXT /MUST /CLICK.\n" + "/ARE /YOU /A /STUPID /ANIMAL /WHICH /IS /ATTRACTED /TO /COLOURS?") + + +@userge.on_cmd("f (.+)", about="""\ +__Pay Respects__ + +**Usage:** + + `.f [emoji | character]`""") +async def payf_(message: Message): + """payf""" + paytext = message.input_str + + pay = "{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}".format( + paytext * 8, paytext * 8, paytext * 2, paytext * 2, paytext * 2, + paytext * 6, paytext * 6, paytext * 2, paytext * 2, paytext * 2, + paytext * 2, paytext * 2) + + await message.edit(pay) + + +@userge.on_cmd("clap", about="""\ +__Praise people!__ + +**Usage:** + + .clap [input | reply to msg]""") +async def clap_(message: Message): + """clap""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`Hah, I don't clap pointlessly!`") + return + + reply_text = "👏 " + reply_text += input_str.replace(" ", " 👏 ") + reply_text += " 👏" + + await message.edit(reply_text) + + +@userge.on_cmd("(\\w+)say (.+)", about=f"""\ +__cow which says things__ + +**Usage:** + + `.[any cowacter]say [text]` + + __cowacters:__ {['`' + x + '`' for x in cow.COWACTERS]}""", name="cowsay") +async def cowsay_(message: Message): + """cowsay""" + arg = message.matches[0].group(1).lower() + text = message.matches[0].group(2) + + if arg == "cow": + arg = "default" + + if arg not in cow.COWACTERS: + await message.err("cowacter not found!") + return + + cheese = cow.get_cow(arg) + cheese = cheese() + + await message.edit(f"`{cheese.milk(text).replace('`', '´')}`") + + +@userge.on_cmd("coinflip", about="""\ +__Flip a coin !!__ + +**Usage:** + + `.coinflip [heads | tails]`""") +async def coin_(message: Message): + """coin""" + r = choice(["heads", "tails"]) + input_str = message.input_str + + if not input_str: + return + + input_str = input_str.lower() + + if r == "heads": + if input_str == "heads": + await message.edit( + "The coin landed on: **Heads**.\nYou were correct.") + + elif input_str == "tails": + await message.edit( + "The coin landed on: **Heads**.\nYou weren't correct, try again ...") + + else: + await message.edit("The coin landed on: **Heads**.") + + elif r == "tails": + if input_str == "tails": + await message.edit( + "The coin landed on: **Tails**.\nYou were correct.") + + elif input_str == "heads": + await message.edit( + "The coin landed on: **Tails**.\nYou weren't correct, try again ...") + + else: + await message.edit("The coin landed on: **Tails**.") + + +@userge.on_cmd("slap", about="""\ +__reply to slap them with random objects !!__ + +**Usage:** + + .slap [input | reply to msg]""") +async def slap_(message: Message): + """slap""" + u_id = message.input_str + if message.reply_to_message: + u_id = message.reply_to_message.from_user.id + + if not u_id: + await message.err("no input found!") + return + + info_dict = await userge.get_user_dict(u_id) + + temp = choice(SLAP_TEMPLATES) + item = choice(ITEMS) + hit = choice(HIT) + throw = choice(THROW) + where = choice(WHERE) + + caption = "..." + temp.format(victim=info_dict['uname'], + item=item, hits=hit, + throws=throw, where=where) + + try: + await message.edit(caption) + + except Exception: + await message.edit( + "`Can't slap this person, need to fetch some sticks and stones !!`") + + +@userge.on_cmd("(yes|no|maybe|decide)$", about="""\ +__Make a quick decision__ + +**Usage:** + + `.decide` + `.yes` + `.no` + `.maybe`""", name="decide") +async def decide_(message: Message): + """decide""" + decision = message.matches[0].group(1).lower() + + if decision != "decide": + r = requests.get(f"https://yesno.wtf/api?force={decision}").json() + + else: + r = requests.get(f"https://yesno.wtf/api").json() + + path = wget.download(r["image"]) + + chat_id = message.chat.id + message_id = None + if message.reply_to_message: + message_id = message.reply_to_message.message_id + + await message.delete() + + await userge.send_photo(chat_id=chat_id, + photo=path, + caption=str(r["answer"]).upper(), + reply_to_message_id=message_id) + + os.remove(path) + + +@userge.on_cmd("cp", about="""\ +__Copypasta the famous meme__ + +**Usage:** + + .cp [input | reply to msg]""") +async def copypasta(message: Message): + """copypasta""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`😂🅱️IvE👐sOME👅text👅for✌️Me👌tO👐MAkE👀iT💞funNy!💦`") + return + + reply_text = choice(EMOJIS) + # choose a random character in the message to be substituted with 🅱️ + b_char = choice(input_str).lower() + + for owo in input_str: + if owo == " ": + reply_text += choice(EMOJIS) + + elif owo in EMOJIS: + reply_text += owo + reply_text += choice(EMOJIS) + + elif owo.lower() == b_char: + reply_text += "🅱️" + + else: + if bool(getrandbits(1)): + reply_text += owo.upper() + + else: + reply_text += owo.lower() + + reply_text += choice(EMOJIS) + await message.edit(reply_text) + + +@userge.on_cmd("vapor", about="""\ +__Vaporize everything!__ + +**Usage:** + + .vapor [input | reply to msg]""") +async def vapor_(message: Message): + """vapor""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`Give some text for vapor!`") + return + + reply_text = [] + + for charac in input_str: + if 0x21 <= ord(charac) <= 0x7F: + reply_text.append(chr(ord(charac) + 0xFEE0)) + + elif ord(charac) == 0x20: + reply_text.append(chr(0x3000)) + + else: + reply_text.append(charac) + + await message.edit("".join(reply_text)) + + +@userge.on_cmd("str", about="""\ +__Stretch it__ + +**Usage:** + + .str [input | reply to msg]""") +async def stretch(message: Message): + """stretch""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`GiiiiiiiB sooooooomeeeeeee teeeeeeext!`") + return + + await message.edit( + sub(r"([aeiouAEIOUaeiouAEIOUаеиоуюяыэё])", (r"\1" * randint(3, 10)), input_str)) + + +@userge.on_cmd("zal", about="""\ +__Invoke the feeling of chaos__ + +**Usage:** + + .zal [input | reply to msg]""") +async def zal_(message: Message): + """zal""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`gͫ ̆ i̛ ̺ v͇̆ ȅͅ a̢ͦ s̴̪ c̸̢ ä̸ rͩͣ y͖͞ t̨͚ é̠ x̢͖ t͔͛`") + return + + reply_text = [] + + for charac in input_str: + if not charac.isalpha(): + reply_text.append(charac) + continue + + for _ in range(0, 3): + randint_ = randint(0, 2) + if randint_ == 0: + charac = charac.strip() + choice(ZALG_LIST[0]).strip() + + elif randint_ == 1: + charac = charac.strip() + choice(ZALG_LIST[1]).strip() + + else: + charac = charac.strip() + choice(ZALG_LIST[2]).strip() + + reply_text.append(charac) + + await message.edit("".join(reply_text)) + + +@userge.on_cmd("owo", about="""\ +__UwU__ + +**Usage:** + + .owo [input | reply to msg]""") +async def owo_(message: Message): + """owo""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("` UwU no text given! `") + return + + reply_text = sub(r"(r|l)", "w", input_str) + reply_text = sub(r"(R|L)", "W", reply_text) + reply_text = sub(r"n([aeiou])", r"ny\1", reply_text) + reply_text = sub(r"N([aeiouAEIOU])", r"Ny\1", reply_text) + reply_text = sub(r"\!+", " " + choice(UWUS), reply_text) + reply_text = reply_text.replace("ove", "uv") + reply_text += " " + choice(UWUS) + + await message.edit(reply_text) + + +@userge.on_cmd("mock", about="""\ +__Do it and find the real fun__ + +**Usage:** + + .mock [input | reply to msg]""") +async def mock_(message: Message): + """mock""" + input_str = message.input_or_reply_str + + if not input_str: + await message.edit("`gIvE sOMEtHInG tO MoCk!`") + return + + reply_text = [] + + for charac in input_str: + if charac.isalpha() and randint(0, 1): + to_app = charac.upper() if charac.islower() else charac.lower() + reply_text.append(to_app) + + else: + reply_text.append(charac) + + await message.edit("".join(reply_text)) + + +@userge.on_cmd("lfy", about="""\ +__Let me Google that for you real quick !!__ + +**Usage:** + + `.lfy [query | reply to msg]`""") +async def lfy_(message: Message): + """lfy_""" + query = message.input_or_reply_str + + if not query: + await message.edit("`gIvE sOMEtHInG tO lFy!`") + return + + query_encoded = query.replace(" ", "+") + lfy_url = f"http://lmgtfy.com/?s=g&iie=1&q={query_encoded}" + payload = {'format': 'json', 'url': lfy_url} + + r = requests.get('http://is.gd/create.php', params=payload) + + await message.edit(f"Here you are, help yourself.\n[{query}]({r.json()['shorturl']})") + + +@userge.on_cmd("scam", about="""\ +__Create fake chat actions, for fun.__ + +**Available Actions:** + + `typing` (default), `playing`, + `upload_photo`, `upload_video`, + `upload_audio`, `upload_document`, + `upload_video_note`, `record_video`, + `record_audio`, `record_video_note`, + `find_location`, `choose_contact` + +**Usage:** + + `.scam` + `.scam [action]` + `.scam [time]` + `.scam [action] [time]`""") +async def scam_(message: Message): + """scam""" + options = ('typing', 'upload_photo', 'record_video', 'upload_video', 'record_audio', + 'upload_audio', 'upload_document', 'find_location', 'record_video_note', + 'upload_video_note', 'choose_contact', 'playing') + + input_str = message.input_str + args = input_str.split() + + if len(args) == 0: # Let bot decide action and time + scam_action = choice(options) + scam_time = randint(30, 60) + + elif len(args) == 1: # User decides time/action, bot decides the other. + try: + scam_action = str(args[0]).lower() + scam_time = randint(30, 60) + + except ValueError: + scam_action = choice(options) + scam_time = int(args[0]) + + elif len(args) == 2: # User decides both action and time + scam_action = str(args[0]).lower() + scam_time = int(args[1]) + + else: + await message.edit("`Invalid Syntax !!`") + return + + try: + if (scam_time > 0): + chat_id = message.chat.id + await message.delete() + + count = 0 + while count <= scam_time: + await userge.send_chat_action(chat_id, scam_action) + await sleep(5) + count += 5 + + except Exception: + return diff --git a/userge/plugins/fun/reacts.py b/userge/plugins/fun/reacts.py deleted file mode 100644 index ba8247432..000000000 --- a/userge/plugins/fun/reacts.py +++ /dev/null @@ -1,228 +0,0 @@ -import re -import time -import random -from userge import userge, Message - -UWUS = ( - 'ÓwÓ', - 'ÕwÕ', - '@w@', - 'ØwØ', - 'øwø', - 'uwu', - '◕w◕', - '◔w◔', - 'ʘwʘ', - '⓪w⓪', - '(owo)', - '(。O ω O。)', - '(。O⁄ ⁄ω⁄ ⁄ O。)', - '(O ᵕ O)', - '(O꒳O)', - 'ღ(O꒳Oღ)', - '♥(。ᅌ ω ᅌ。)', - '(ʘωʘ)', - '(⁄ʘ⁄ ⁄ ω⁄ ⁄ ʘ⁄)♡', - '( ͡o ω ͡o )', - '( ͡o ᵕ ͡o )', - '( ͡o ꒳ ͡o )', - '( o͡ ꒳ o͡ )', - '( °꒳° )', - '( °ᵕ° )', - '( °﹏° )', - '( °ω° )', - '̷(ⓞ̷ ̷꒳̷ ̷ⓞ̷)', - '( ゜ω 。)' -) - -FACEREACTS = ( - "ʘ‿ʘ", - "ヾ(-_- )ゞ", - "(っ˘ڡ˘ς)", - "(´ж`ς)", - "( ಠ ʖ̯ ಠ)", - "(° ͜ʖ͡°)╭∩╮", - "(ᵟຶ︵ ᵟຶ)", - "(งツ)ว", - "ʚ(•`", - "(っ▀¯▀)つ", - "(◠﹏◠)", - "( ͡ಠ ʖ̯ ͡ಠ)", - "( ఠ ͟ʖ ఠ)", - "(∩`-´)⊃━☆゚.*・。゚", - "(⊃。•́‿•̀。)⊃", - "(._.)", - "{•̃_•̃}", - "(ᵔᴥᵔ)", - "♨_♨", - "⥀.⥀", - "ح˚௰˚づ ", - "(҂◡_◡)", - "ƪ(ړײ)‎ƪ​​", - "(っ•́。•́)♪♬", - "◖ᵔᴥᵔ◗ ♪ ♫ ", - "(☞゚ヮ゚)☞", - "[¬º-°]¬", - "(Ծ‸ Ծ)", - "(•̀ᴗ•́)و ̑̑", - "ヾ(´〇`)ノ♪♪♪", - "(ง'̀-'́)ง", - "ლ(•́•́ლ)", - "ʕ •́؈•̀ ₎", - "♪♪ ヽ(ˇ∀ˇ )ゞ", - "щ(゚Д゚щ)", - "( ˇ෴ˇ )", - "눈_눈", - "(๑•́ ₃ •̀๑) ", - "( ˘ ³˘)♥ ", - "ԅ(≖‿≖ԅ)", - "♥‿♥", - "◔_◔", - "⁽⁽ଘ( ˊᵕˋ )ଓ⁾⁾", - "乁( ◔ ౪◔)「 ┑( ̄Д  ̄)┍", - "( ఠൠఠ )ノ", - "٩(๏_๏)۶", - "┌(ㆆ㉨ㆆ)ʃ", - "ఠ_ఠ", - "(づ。◕‿‿◕。)づ", - "(ノಠ ∩ಠ)ノ彡( \\o°o)\\", - "“ヽ(´▽`)ノ”", - "༼ ༎ຶ ෴ ༎ຶ༽", - "。゚( ゚இ‸இ゚)゚。", - "(づ ̄ ³ ̄)づ", - "(⊙.☉)7", - "ᕕ( ᐛ )ᕗ", - "t(-_-t)", - "(ಥ⌣ಥ)", - "ヽ༼ ಠ益ಠ ༽ノ", - "༼∵༽ ༼⍨༽ ༼⍢༽ ༼⍤༽", - "ミ●﹏☉ミ", - "(⊙_◎)", - "¿ⓧ_ⓧﮌ", - "ಠ_ಠ", - "(´・_・`)", - "ᕦ(ò_óˇ)ᕤ", - "⊙﹏⊙", - "(╯°□°)╯︵ ┻━┻", - "¯\\_(⊙︿⊙)_/¯", - "٩◔̯◔۶", - "°‿‿°", - "ᕙ(⇀‸↼‶)ᕗ", - "⊂(◉‿◉)つ", - "V•ᴥ•V", - "q(❂‿❂)p", - "ಥ_ಥ", - "ฅ^•ﻌ•^ฅ", - "ಥ﹏ಥ", - "( ^_^)o自自o(^_^ )", - "ಠ‿ಠ", - "ヽ(´▽`)/", - "ᵒᴥᵒ#", - "( ͡° ͜ʖ ͡°)", - "┬─┬ ノ( ゜-゜ノ)", - "ヽ(´ー`)ノ", - "☜(⌒▽⌒)☞", - "ε=ε=ε=┌(;*´Д`)ノ", - "(╬ ಠ益ಠ)", - "┬─┬⃰͡ (ᵔᵕᵔ͜ )", - "┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻", - "¯\\_(ツ)_/¯", - "ʕᵔᴥᵔʔ", - "(`・ω・´)", - "ʕ•ᴥ•ʔ", - "ლ(`ー´ლ)", - "ʕʘ̅͜ʘ̅ʔ", - "( ゚Д゚)", - "¯\\(°_o)/¯", - "(。◕‿◕。)", -) - - -@userge.on_cmd("[Ss]hg", - about="__shrugger__", - name="shg", - trigger='') -async def shg_(message: Message): - - await message.edit("¯¯\\__(ツ)__/¯¯", parse_mode='html') - - -@userge.on_cmd("react", about="__React to a message__") -async def react_(message: Message): - - await message.edit(random.choice(FACEREACTS), parse_mode='html') - - -@userge.on_cmd("[Kk]ek", - about="__:/__", - name="kek", - trigger='') -async def kek_(message: Message): - uio = ["/", "\\"] - for i in range(1, 15): - time.sleep(0.3) - - await message.edit(":" + uio[i % 2]) - - -@userge.on_cmd("[Ll]ol", - about="__-_-__", - name="lol", - trigger='') -async def lol_(message: Message): - okay = r"-_ " - for _ in range(10): - okay = okay[:-1] + r"_-" - - await message.edit(okay, parse_mode='html') - - -@userge.on_cmd("[Oo]of", - about="__`oof`s more dramatic__", - name="oof", - trigger='') -async def oof_(message: Message): - t = "Oo " - for _ in range(10): - t = t[:-1] + "of" - - await message.edit(t) - - -@userge.on_cmd("clap", about="""\ -__Claps for the selected message__ - -**Usage:** - - `.clap [text | reply to msg]`""") -async def clap_(message: Message): - text = message.input_str - if message.reply_to_message: - text = message.reply_to_message.text - - await message.edit(f"👏 {re.sub(r' +', ' 👏 ', text)} 👏") - - -@userge.on_cmd("[Oo]wo", - about="""\ -__UwU's you OwO__ - -**Usage:** - - `owo [text | reply to msg]`""", - name="owo", - trigger='') -async def faces_(message: Message): - text = message.input_str - if message.reply_to_message: - text = message.reply_to_message.text - - text = re.sub(r"([rl])", "w", text) - text = re.sub(r"([RL])", "W", text) - text = re.sub(r"n([aeiou])", r"ny\1", text) - text = re.sub(r"N([aeiouAEIOU])", r"Ny\1", text) - text = re.sub(r"!", " " + random.choice(UWUS), text) - text = text.replace("ove", "uv") - text += " " + random.choice(UWUS) - - await message.edit(text.strip(), parse_mode='html') diff --git a/userge/plugins/fun/type.py b/userge/plugins/fun/type.py index 51704c915..051ee33b7 100644 --- a/userge/plugins/fun/type.py +++ b/userge/plugins/fun/type.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import time import random from pyrogram.errors.exceptions import FloodWait diff --git a/userge/plugins/help.py b/userge/plugins/help.py index c3d535ec3..c85bea63b 100644 --- a/userge/plugins/help.py +++ b/userge/plugins/help.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/misc/__init__.py b/userge/plugins/misc/__init__.py index e69de29bb..4bba28ab4 100644 --- a/userge/plugins/misc/__init__.py +++ b/userge/plugins/misc/__init__.py @@ -0,0 +1,7 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. \ No newline at end of file diff --git a/userge/plugins/misc/download.py b/userge/plugins/misc/download.py index 867c71801..d52a5fae4 100644 --- a/userge/plugins/misc/download.py +++ b/userge/plugins/misc/download.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import asyncio import math import os @@ -5,7 +14,7 @@ from datetime import datetime from pySmartDL import SmartDL from userge import userge, Message, Config -from userge.utils import progress, CANCEL_LIST, humanbytes +from userge.utils import progress, humanbytes LOGGER = userge.getLogger(__name__) @@ -36,8 +45,7 @@ async def down_load_media(message: Message): ) # await userge.send_chat_action(message.chat.id, "cancel") - if message.message_id in CANCEL_LIST: - CANCEL_LIST.remove(message.message_id) + if message.process_is_canceled: await message.edit("`Process Canceled!`", del_in=5) else: diff --git a/userge/plugins/misc/gdrive.py b/userge/plugins/misc/gdrive.py index a3c923701..3ad34903c 100644 --- a/userge/plugins/misc/gdrive.py +++ b/userge/plugins/misc/gdrive.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os import io import time @@ -14,10 +23,21 @@ from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload from oauth2client.client import OAuth2WebServerFlow from oauth2client.client import HttpAccessTokenRefreshError, FlowExchangeError -from pyrogram.errors.exceptions import MessageTooLong -from pyrogram.errors.exceptions.bad_request_400 import MessageNotModified from userge import userge, Message, Config, get_collection -from userge.utils import humanbytes, time_formatter, CANCEL_LIST +from userge.utils import humanbytes, time_formatter + +CREDS: object = None +AUTH_FLOW: object = None +PARENT_ID = "" + +OAUTH_SCOPE = "https://www.googleapis.com/auth/drive" +REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob" +G_DRIVE_DIR_MIME_TYPE = "application/vnd.google-apps.folder" +G_DRIVE_FILE_LINK = "📄 {} __({})__" +G_DRIVE_FOLDER_LINK = "📁 {} __(folder)__" + +LOG = userge.getLogger(__name__) +GDRIVE_COLLECTION = get_collection("gdrive") class ProcessCanceled(Exception): @@ -31,44 +51,31 @@ class DBase: Database Class for GDrive. """ - CREDS = None - - _LOG = userge.getLogger(__name__) - __GDRIVE_COLLECTION = get_collection("gdrive") - def __init__(self, id_: str) -> None: - self.__id = id_ - self._LOG.info("Setting GDrive DBase...") - self.__load_creds() - - @property - def _creds(self) -> object: - return self.CREDS - - @_creds.setter - def _creds(self, creds: object) -> None: - self.__class__.CREDS = creds + global CREDS - def __load_creds(self) -> None: + self.__id = id_ + LOG.info("Setting GDrive DBase...") - if not self._creds: - result = self.__GDRIVE_COLLECTION.find_one({'_id': self.__id}, {'creds': 1}) - self._creds = pickle.loads(result['creds']) if result else None + if not CREDS: + result = GDRIVE_COLLECTION.find_one({'_id': self.__id}, {'creds': 1}) + CREDS = pickle.loads(result['creds']) if result else None - if self._creds: + if CREDS: try: - self._LOG.info("Refreshing Creds...") - self._creds.refresh(Http()) + LOG.info("Refreshing Creds...") + CREDS.refresh(Http()) except HttpAccessTokenRefreshError: self._clear_creds() def _set_creds(self, creds) -> str: + global CREDS - self._LOG.info("Setting Creds...") - self._creds = creds + LOG.info("Setting Creds...") + CREDS = creds - result = self.__GDRIVE_COLLECTION.update_one( + result = GDRIVE_COLLECTION.update_one( {'_id': self.__id}, {"$set": {'creds': pickle.dumps(creds)}}, upsert=True) if result.upserted_id: @@ -77,11 +84,12 @@ def _set_creds(self, creds) -> str: return "`Creds Updated`" def _clear_creds(self) -> str: + global CREDS - self._creds = None - self._LOG.info("Creds Cleared!") + CREDS = None + LOG.info("Creds Cleared!") - if self.__GDRIVE_COLLECTION.find_one_and_delete({'_id': self.__id}): + if GDRIVE_COLLECTION.find_one_and_delete({'_id': self.__id}): return "`Creds Cleared`" return "`Creds Not Found`" @@ -92,17 +100,8 @@ class GDrive(DBase): GDrive Class For Search, Upload, Download, Copy, Move, Delete, EmptyTrash, ... """ - AUTH_FLOW = None - PARENT_ID = "" - - __OAUTH_SCOPE = "https://www.googleapis.com/auth/drive" - __REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob" - __G_DRIVE_DIR_MIME_TYPE = "application/vnd.google-apps.folder" - __G_DRIVE_FILE_LINK = "📄 {} __({})__" - __G_DRIVE_FOLDER_LINK = "📁 {} " + \ - "__(folder)__" - def __init__(self, id_: str) -> None: + self._parent_id = PARENT_ID or Config.G_DRIVE_PARENT_ID self.__completed = 0 self.__list = 1 self.__progress = None @@ -110,34 +109,9 @@ def __init__(self, id_: str) -> None: self.__is_canceled = False self.__is_finished = False - self._LOG.info("Setting GDrive...") + LOG.info("Setting GDrive...") super().__init__(id_) - @property - def _auth_flow(self) -> object: - return self.AUTH_FLOW - - @_auth_flow.setter - def _auth_flow(self, flow: object) -> None: - self.__class__.AUTH_FLOW = flow - - def _set_auth_flow(self) -> None: - self._auth_flow = OAuth2WebServerFlow(Config.G_DRIVE_CLIENT_ID, - Config.G_DRIVE_CLIENT_SECRET, - self.__OAUTH_SCOPE, - redirect_uri=self.__REDIRECT_URI) - - def _reset_auth_flow(self) -> None: - self._auth_flow = None - - @property - def _parent_id(self) -> str: - return self.PARENT_ID or Config.G_DRIVE_PARENT_ID - - @_parent_id.setter - def _parent_id(self, id_: str) -> None: - self.__class__.PARENT_ID = id_ - def _cancel(self) -> None: self.__is_canceled = True @@ -162,7 +136,7 @@ def _output(self) -> str: @property def __service(self) -> object: - return build("drive", "v3", credentials=self._creds, cache_discovery=False) + return build("drive", "v3", credentials=CREDS, cache_discovery=False) @userge.new_thread def _search(self, @@ -200,11 +174,12 @@ def _search(self, if len(results) >= limit: break - if file_.get('mimeType') == self.__G_DRIVE_DIR_MIME_TYPE: - msg += self.__G_DRIVE_FOLDER_LINK.format(file_.get('id'), file_.get('name')) + if file_.get('mimeType') == G_DRIVE_DIR_MIME_TYPE: + msg += G_DRIVE_FOLDER_LINK.format(file_.get('id'), file_.get('name')) else: - msg += self.__G_DRIVE_FILE_LINK.format(file_.get('id'), file_.get('name'), - humanbytes(int(file_.get('size', 0)))) + msg += G_DRIVE_FILE_LINK.format( + file_.get('id'), file_.get('name'), humanbytes(int(file_.get('size', 0)))) + msg += '\n' results.append(file_) @@ -238,7 +213,7 @@ def __set_permission(self, file_id: str) -> None: self.__service.permissions().create(fileId=file_id, body=permissions, supportsTeamDrives=True).execute() - self._LOG.info(f"Set Permission : {permissions} for Google-Drive File : {file_id}") + LOG.info(f"Set Permission : {permissions} for Google-Drive File : {file_id}") def __upload_file(self, file_path: str, parent_id: str) -> str: @@ -319,18 +294,18 @@ def __upload_file(self, file_path: str, parent_id: str) -> str: file_name = drive_file.get("name") file_size = humanbytes(int(drive_file.get('size', 0))) - self._LOG.info( + LOG.info( "Created Google-Drive File => Name: {} ID: {} Size: {}".format( file_name, file_id, file_size)) - return self.__G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) + return G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) def __create_drive_dir(self, dir_name: str, parent_id: str) -> str: if self._is_canceled: raise ProcessCanceled - body = {"name": dir_name, "mimeType": self.__G_DRIVE_DIR_MIME_TYPE} + body = {"name": dir_name, "mimeType": G_DRIVE_DIR_MIME_TYPE} if parent_id: body["parents"] = [parent_id] @@ -345,7 +320,7 @@ def __create_drive_dir(self, dir_name: str, parent_id: str) -> str: self.__completed += 1 - self._LOG.info("Created Google-Drive Folder => Name: {} ID: {} ".format(file_name, file_id)) + LOG.info("Created Google-Drive Folder => Name: {} ID: {} ".format(file_name, file_id)) return file_id @@ -381,7 +356,7 @@ def _upload(self, file_name: str) -> None: folder_name = os.path.basename(os.path.abspath(file_name)) dir_id = self.__create_drive_dir(folder_name, self._parent_id) self.__upload_dir(file_name, dir_id) - self.__output = self.__G_DRIVE_FOLDER_LINK.format(dir_id, folder_name) + self.__output = G_DRIVE_FOLDER_LINK.format(dir_id, folder_name) except HttpError as h_e: self.__output = h_e @@ -439,7 +414,7 @@ def __download_file(self, path: str, name: str, **kwargs) -> None: time_formatter(eta)) self.__completed += 1 - self._LOG.info( + LOG.info( "Downloaded Google-Drive File => Name: {} ID: {} ".format(name, kwargs['id'])) def __list_drive_dir(self, file_id: str) -> list: @@ -475,7 +450,7 @@ def __create_server_dir(self, current_path: str, folder_name: str) -> str: if not os.path.exists(path): os.mkdir(path) - self._LOG.info("Created Folder => Name: {} ".format(folder_name)) + LOG.info("Created Folder => Name: {} ".format(folder_name)) self.__completed += 1 return path @@ -492,7 +467,7 @@ def __download_dir(self, path: str, **kwargs) -> None: self.__list += len(files) for file_ in files: - if file_['mimeType'] == self.__G_DRIVE_DIR_MIME_TYPE: + if file_['mimeType'] == G_DRIVE_DIR_MIME_TYPE: path_ = self.__create_server_dir(path, file_['name']) self.__download_dir(path_, **file_) else: @@ -503,7 +478,7 @@ def _download(self, file_id: str) -> None: drive_file = self.__service.files().get(fileId=file_id, fields="id, name, mimeType", supportsTeamDrives=True).execute() - if drive_file['mimeType'] == self.__G_DRIVE_DIR_MIME_TYPE: + if drive_file['mimeType'] == G_DRIVE_DIR_MIME_TYPE: path = self.__create_server_dir(Config.DOWN_PATH, drive_file['name']) self.__download_dir(path, **drive_file) else: @@ -548,7 +523,7 @@ def __copy_file(self, file_id: str, parent_id: str) -> str: self.__completed += 1 - self._LOG.info( + LOG.info( "Copied Google-Drive File => Name: {} ID: {} ".format( drive_file['name'], drive_file['id'])) @@ -567,7 +542,7 @@ def __copy_dir(self, file_id: str, parent_id: str) -> str: new_id = None for file_ in files: - if file_['mimeType'] == self.__G_DRIVE_DIR_MIME_TYPE: + if file_['mimeType'] == G_DRIVE_DIR_MIME_TYPE: dir_id = self.__create_drive_dir(file_['name'], parent_id) new_id = self.__copy_dir(file_['id'], dir_id) else: @@ -581,7 +556,7 @@ def _copy(self, file_id: str) -> None: drive_file = self.__service.files().get( fileId=file_id, fields="id, name, mimeType", supportsTeamDrives=True).execute() - if drive_file['mimeType'] == self.__G_DRIVE_DIR_MIME_TYPE: + if drive_file['mimeType'] == G_DRIVE_DIR_MIME_TYPE: dir_id = self.__create_drive_dir(drive_file['name'], self._parent_id) self.__copy_dir(file_id, dir_id) ret_id = dir_id @@ -595,11 +570,11 @@ def _copy(self, file_id: str) -> None: file_name = drive_file['name'] file_id = drive_file['id'] - if mime_type == self.__G_DRIVE_DIR_MIME_TYPE: - self.__output = self.__G_DRIVE_FOLDER_LINK.format(file_id, file_name) + if mime_type == G_DRIVE_DIR_MIME_TYPE: + self.__output = G_DRIVE_FOLDER_LINK.format(file_id, file_name) else: file_size = humanbytes(int(drive_file.get('size', 0))) - self.__output = self.__G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) + self.__output = G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) except HttpError as h_e: self.__output = h_e @@ -622,32 +597,32 @@ def _move(self, file_id: str) -> str: fields="id, name, mimeType, size, parents", supportsTeamDrives=True).execute() - self._LOG.info(f"Moved file : {file_id} => " + \ + LOG.info(f"Moved file : {file_id} => " + \ f"from : {previous_parents} to : {drive_file['parents']} in Google-Drive") mime_type = drive_file['mimeType'] file_name = drive_file['name'] file_id = drive_file['id'] - if mime_type == self.__G_DRIVE_DIR_MIME_TYPE: - return self.__G_DRIVE_FOLDER_LINK.format(file_id, file_name) + if mime_type == G_DRIVE_DIR_MIME_TYPE: + return G_DRIVE_FOLDER_LINK.format(file_id, file_name) file_size = humanbytes(int(drive_file.get('size', 0))) - return self.__G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) + return G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) @userge.new_thread def _delete(self, file_id: str) -> None: self.__service.files().delete(fileId=file_id, supportsTeamDrives=True).execute() - self._LOG.info(f"Deleted Google-Drive File : {file_id}") + LOG.info(f"Deleted Google-Drive File : {file_id}") @userge.new_thread def _empty_trash(self) -> None: self.__service.files().emptyTrash().execute() - self._LOG.info("Empty Google-Drive Trash") + LOG.info("Empty Google-Drive Trash") @userge.new_thread def _get(self, file_id: str) -> str: @@ -659,7 +634,7 @@ def _get(self, file_id: str) -> str: drive_file['quotaBytesUsed'] = humanbytes(int(drive_file.get('quotaBytesUsed', 0))) drive_file = dumps(drive_file, sort_keys=True, indent=4) - self._LOG.info("Getting Google-Drive File Details => {}".format(drive_file)) + LOG.info("Getting Google-Drive File Details => {}".format(drive_file)) return drive_file @@ -676,7 +651,7 @@ def _get_perms(self, file_id: str) -> str: all_perms[perm_id] = perm all_perms = dumps(all_perms, sort_keys=True, indent=4) - self._LOG.info(f"All Permissions: {all_perms} for Google-Drive File : {file_id}") + LOG.info(f"All Permissions: {all_perms} for Google-Drive File : {file_id}") return all_perms @@ -688,18 +663,18 @@ def _set_perms(self, file_id: str) -> str: drive_file = self.__service.files().get(fileId=file_id, supportsTeamDrives=True, fields="id, name, mimeType, size").execute() - self._LOG.info( + LOG.info( f"Set Permission : for Google-Drive File : {file_id}\n{drive_file}") mime_type = drive_file['mimeType'] file_name = drive_file['name'] file_id = drive_file['id'] - if mime_type == self.__G_DRIVE_DIR_MIME_TYPE: - return self.__G_DRIVE_FOLDER_LINK.format(file_id, file_name) + if mime_type == G_DRIVE_DIR_MIME_TYPE: + return G_DRIVE_FOLDER_LINK.format(file_id, file_name) file_size = humanbytes(int(drive_file.get('size', 0))) - return self.__G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) + return G_DRIVE_FILE_LINK.format(file_id, file_name, file_size) @userge.new_thread def _del_perms(self, file_id: str) -> str: @@ -718,7 +693,7 @@ def _del_perms(self, file_id: str) -> str: removed_perms[perm_id] = perm removed_perms = dumps(removed_perms, sort_keys=True, indent=4) - self._LOG.info( + LOG.info( f"Remove Permission: {removed_perms} for Google-Drive File : {file_id}") return removed_perms @@ -771,13 +746,17 @@ async def setup(self) -> None: """ Setup GDrive. """ + global AUTH_FLOW - if self._creds: + if CREDS: await self.__message.edit("`Already Setup!`", del_in=5) else: - self._set_auth_flow() + AUTH_FLOW = OAuth2WebServerFlow(Config.G_DRIVE_CLIENT_ID, + Config.G_DRIVE_CLIENT_SECRET, + OAUTH_SCOPE, + redirect_uri=REDIRECT_URI) - reply_string = f"please visit {self._auth_flow.step1_get_authorize_url()} and " + reply_string = f"please visit {AUTH_FLOW.step1_get_authorize_url()} and " reply_string += "send back " reply_string += ".gconf [auth_code]" @@ -787,21 +766,22 @@ async def confirm_setup(self) -> None: """ Finalize GDrive setup. """ + global AUTH_FLOW - if self._auth_flow is None: + if AUTH_FLOW is None: await self.__message.edit("Please run `.gsetup` first", del_in=5) return await self.__message.edit("Checking Auth Code...") try: - cred = self._auth_flow.step2_exchange(self.__message.input_str) + cred = AUTH_FLOW.step2_exchange(self.__message.input_str) except FlowExchangeError as c_i: await self.__message.err(c_i) else: self._set_creds(cred) - self._reset_auth_flow() + AUTH_FLOW = None await self.__message.edit("`Saved GDrive Creds!`", del_in=3) @@ -816,6 +796,7 @@ async def set_parent(self) -> None: """ Set Parent id. """ + global PARENT_ID file_id, file_type = self.__get_file_id() @@ -823,7 +804,7 @@ async def set_parent(self) -> None: await self.__message.err("Please send me a folder link") else: - self._parent_id = file_id + PARENT_ID = file_id await self.__message.edit( f"Parents set as `{file_id}` successfully", del_in=5) @@ -832,8 +813,9 @@ async def reset_parent(self) -> None: """ Reset parent id. """ + global PARENT_ID - self._parent_id = "" + PARENT_ID = "" await self.__message.edit("`Parents Reset successfully`", del_in=5) @@ -842,7 +824,7 @@ async def search(self) -> None: Search files in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Search...`") try: out = await self._search( @@ -852,12 +834,9 @@ async def search(self) -> None: await self.__message.err(h_e) return - try: - await self.__message.edit(out, disable_web_page_preview=True) - - except MessageTooLong: - await self.__message.send_as_file( - out, caption=f"search results for `{self.__message.filtered_input_str}`") + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, + caption=f"search results for `{self.__message.filtered_input_str}`") else: await self.__message.edit("Please run `.gsetup` first", del_in=5) @@ -877,7 +856,7 @@ async def list_folder(self) -> None: await self.__message.err("Please send me a folder link") return - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive List...`") root = not bool(file_id) @@ -889,12 +868,8 @@ async def list_folder(self) -> None: await self.__message.err(h_e) return - try: - await self.__message.edit(out, disable_web_page_preview=True) - - except MessageTooLong: - await self.__message.send_as_file( - out, caption=f"list results for `{file_id}`") + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, caption=f"list results for `{file_id}`") else: await self.__message.edit("Please run `.gsetup` first", del_in=5) @@ -904,7 +879,7 @@ async def upload(self) -> None: Upload file/folder to GDrive. """ - if self._creds: + if CREDS: upload_file_name = self.__message.input_str if not os.path.exists(upload_file_name): @@ -917,15 +892,11 @@ async def upload(self) -> None: start_t = datetime.now() while not self._is_finished: - if self.__message.message_id in CANCEL_LIST: + if self.__message.process_is_canceled: self._cancel() - CANCEL_LIST.remove(self.__message.message_id) if self._progress is not None: - try: - await self.__message.edit(self._progress) - except MessageNotModified: - pass + await self.__message.try_to_edit(self._progress) await asyncio.sleep(3) @@ -951,7 +922,7 @@ async def download(self) -> None: Download file/folder from GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Download...`") file_id, _ = self.__get_file_id() @@ -960,15 +931,11 @@ async def download(self) -> None: start_t = datetime.now() while not self._is_finished: - if self.__message.message_id in CANCEL_LIST: + if self.__message.process_is_canceled: self._cancel() - CANCEL_LIST.remove(self.__message.message_id) if self._progress is not None: - try: - await self.__message.edit(self._progress) - except MessageNotModified: - pass + await self.__message.try_to_edit(self._progress) await asyncio.sleep(3) @@ -998,7 +965,7 @@ async def copy(self) -> None: await self.__message.edit("First set parent path by `.gset`", del_in=5) return - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Copy...`") file_id, _ = self.__get_file_id() @@ -1007,15 +974,11 @@ async def copy(self) -> None: start_t = datetime.now() while not self._is_finished: - if self.__message.message_id in CANCEL_LIST: + if self.__message.process_is_canceled: self._cancel() - CANCEL_LIST.remove(self.__message.message_id) if self._progress is not None: - try: - await self.__message.edit(self._progress) - except MessageNotModified: - pass + await self.__message.try_to_edit(self._progress) await asyncio.sleep(3) @@ -1045,7 +1008,7 @@ async def move(self) -> None: await self.__message.edit("First set parent path by `.gset`", del_in=5) return - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Move...`") file_id, _ = self.__get_file_id() @@ -1068,7 +1031,7 @@ async def delete(self) -> None: Delete file/folder in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Delete...`") file_id, _ = self.__get_file_id() @@ -1091,7 +1054,7 @@ async def empty(self) -> None: Empty GDrive Trash. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive Empty Trash...`") try: await self._empty_trash() @@ -1110,7 +1073,7 @@ async def get(self) -> None: Get details for file/folder in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive GetDetails...`") file_id, _ = self.__get_file_id() @@ -1122,13 +1085,10 @@ async def get(self) -> None: await self.__message.err(h_e) return - try: - out = f"**I Found these Details for** `{file_id}`\n\n{meta_data}" - await self.__message.edit(out, disable_web_page_preview=True) + out = f"**I Found these Details for** `{file_id}`\n\n{meta_data}" - except MessageTooLong: - await self.__message.send_as_file( - meta_data, caption=f"metadata for `{file_id}`") + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, caption=f"metadata for `{file_id}`") else: await self.__message.edit("Please run `.gsetup` first", del_in=5) @@ -1138,7 +1098,7 @@ async def get_perms(self) -> None: Get all Permissions of file/folder in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive GetPermissions...`") file_id, _ = self.__get_file_id() @@ -1150,13 +1110,10 @@ async def get_perms(self) -> None: await self.__message.err(h_e) return - try: - out = f"**I Found these Permissions for** `{file_id}`\n\n{out}" - await self.__message.edit(out, disable_web_page_preview=True) + out = f"**I Found these Permissions for** `{file_id}`\n\n{out}" - except MessageTooLong: - await self.__message.send_as_file( - out, caption=f"view perm results for `{file_id}`") + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, caption=f"view perm results for `{file_id}`") else: await self.__message.edit("Please run `.gsetup` first", del_in=5) @@ -1166,7 +1123,7 @@ async def set_perms(self) -> None: Set Permissions to file/folder in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive SetPermissions...`") file_id, _ = self.__get_file_id() @@ -1189,7 +1146,7 @@ async def del_perms(self) -> None: Remove all permisiions of file/folder in GDrive. """ - if self._creds: + if CREDS: await self.__message.edit("`Loading GDrive DelPermissions...`") file_id, _ = self.__get_file_id() @@ -1201,14 +1158,10 @@ async def del_perms(self) -> None: await self.__message.err(h_e) return - try: - out = "**Removed These Permissions successfully from**" + \ - f"`{file_id}`\n\n{out}" - await self.__message.edit(out, disable_web_page_preview=True) + out = f"**Removed These Permissions successfully from** `{file_id}`\n\n{out}" - except MessageTooLong: - await self.__message.send_as_file( - out, caption=f"removed perm results for `{file_id}`") + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, caption=f"removed perm results for `{file_id}`") else: await self.__message.edit("Please run `.gsetup` first", del_in=5) diff --git a/userge/plugins/misc/notes.py b/userge/plugins/misc/notes.py index 91ad44872..a4a52dee0 100644 --- a/userge/plugins/misc/notes.py +++ b/userge/plugins/misc/notes.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message, get_collection NOTES_COLLECTION = get_collection("notes") diff --git a/userge/plugins/misc/thumbnail.py b/userge/plugins/misc/thumbnail.py index 17c200844..bbcc5a388 100644 --- a/userge/plugins/misc/thumbnail.py +++ b/userge/plugins/misc/thumbnail.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os import time from datetime import datetime diff --git a/userge/plugins/misc/upload.py b/userge/plugins/misc/upload.py index 2ca424f90..0f15f6456 100644 --- a/userge/plugins/misc/upload.py +++ b/userge/plugins/misc/upload.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os import time from datetime import datetime @@ -6,7 +15,7 @@ from hachoir.parser import createParser from pyrogram.errors.exceptions import FloodWait from userge import userge, Config, Message -from userge.utils import progress, CANCEL_LIST, take_screen_shot +from userge.utils import progress, take_screen_shot LOGGER = userge.getLogger(__name__) @@ -73,8 +82,7 @@ async def doc_upload(chat_id, path): ) await userge.send_chat_action(chat_id, "cancel") - if message.message_id in CANCEL_LIST: - CANCEL_LIST.remove(message.message_id) + if message.process_is_canceled: await message.edit("`Process Canceled!`", del_in=5) else: @@ -107,10 +115,9 @@ async def vid_upload(chat_id, path): ) ) await userge.send_chat_action(chat_id, "cancel") - os.remove(thumb) + await remove_thumb(thumb) - if message.message_id in CANCEL_LIST: - CANCEL_LIST.remove(message.message_id) + if message.process_is_canceled: await message.edit("`Process Canceled!`", del_in=5) else: @@ -131,3 +138,10 @@ async def get_thumb(path: str = '') -> str: path, metadata.get("duration").seconds) return LOGO_PATH + + +async def remove_thumb(thumb: str) -> None: + if os.path.exists(thumb) and \ + thumb != LOGO_PATH and \ + thumb != THUMB_PATH: + os.remove(thumb) diff --git a/userge/plugins/misc/welcome.py b/userge/plugins/misc/welcome.py index 8301ac298..3f8d9dc7c 100644 --- a/userge/plugins/misc/welcome.py +++ b/userge/plugins/misc/welcome.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Filters, Message, get_collection from userge.utils import SafeDict diff --git a/userge/plugins/misc/zip.py b/userge/plugins/misc/zip.py index caf1636af..01e07974a 100644 --- a/userge/plugins/misc/zip.py +++ b/userge/plugins/misc/zip.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from asyncio import sleep from datetime import datetime from math import floor @@ -7,11 +16,11 @@ from zipfile import ZipFile from threading import Thread from multiprocessing import Pool, Lock -from pyrogram.errors.exceptions.bad_request_400 import MessageNotModified from userge import userge, Message, Config -from userge.utils import CANCEL_LIST, humanbytes +from userge.utils import humanbytes LOGGER = userge.getLogger(__name__) +COUNTER_LOCK = Lock() class ProcessCanceled(Exception): @@ -25,8 +34,6 @@ class Zip: Class for ZIP / UNZIP (files / folders). """ - __COUNTER_LOCK = Lock() - def __init__(self, file_path: str) -> None: self.__file_path = file_path self.__final_file_path = "" @@ -140,7 +147,7 @@ def __counter(self, out_tpl: tuple) -> None: self.__finish() raise Exception(error) - with self.__COUNTER_LOCK: + with COUNTER_LOCK: self.__current += c_out if self.__is_canceled: @@ -265,19 +272,15 @@ async def zip_(message: Message): "**Completed** : `{}/{}`" while not z_obj.finished: - if message.message_id in CANCEL_LIST: + if message.process_is_canceled: z_obj.cancel() - CANCEL_LIST.remove(message.message_id) - - try: - await message.edit(tmp.format(z_obj.progress, - z_obj.percentage, - file_path, - z_obj.final_file_path, - z_obj.completed_files, - z_obj.total_files)) - except MessageNotModified: - pass + + await message.try_to_edit(tmp.format(z_obj.progress, + z_obj.percentage, + file_path, + z_obj.final_file_path, + z_obj.completed_files, + z_obj.total_files)) await sleep(3) @@ -323,19 +326,15 @@ async def unzip_(message: Message): "**Completed** : `{}/{}`" while not z_obj.finished: - if message.message_id in CANCEL_LIST: + if message.process_is_canceled: z_obj.cancel() - CANCEL_LIST.remove(message.message_id) - - try: - await message.edit(tmp.format(z_obj.progress, - z_obj.percentage, - file_path, - z_obj.final_file_path, - z_obj.completed_files, - z_obj.total_files)) - except MessageNotModified: - pass + + await message.try_to_edit(tmp.format(z_obj.progress, + z_obj.percentage, + file_path, + z_obj.final_file_path, + z_obj.completed_files, + z_obj.total_files)) await sleep(3) @@ -377,8 +376,4 @@ async def zipinfo_(message: Message): for file_ in infos: output += f"📄 {file_.filename} __({humanbytes(file_.file_size)})__\n" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption=file_path) - - else: - await message.edit(output) + await message.edit_or_send_as_file(text=output, caption=file_path) diff --git a/userge/plugins/temp/__init__.py b/userge/plugins/temp/__init__.py index 09745c4b1..b590d84f5 100644 --- a/userge/plugins/temp/__init__.py +++ b/userge/plugins/temp/__init__.py @@ -1 +1,10 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + # tmp path to save loaded plugins \ No newline at end of file diff --git a/userge/plugins/tools/__init__.py b/userge/plugins/tools/__init__.py index e69de29bb..4bba28ab4 100644 --- a/userge/plugins/tools/__init__.py +++ b/userge/plugins/tools/__init__.py @@ -0,0 +1,7 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. \ No newline at end of file diff --git a/userge/plugins/tools/all.py b/userge/plugins/tools/all.py index 717b0e658..bf0786c96 100644 --- a/userge/plugins/tools/all.py +++ b/userge/plugins/tools/all.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message from .. import get_all_plugins diff --git a/userge/plugins/tools/cancel.py b/userge/plugins/tools/cancel.py index bd96b4010..e73f6e169 100644 --- a/userge/plugins/tools/cancel.py +++ b/userge/plugins/tools/cancel.py @@ -1,5 +1,13 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message -from userge.utils import CANCEL_LIST @userge.on_cmd("cancel", about="\ @@ -8,10 +16,8 @@ async def cancel_(message: Message): replied = message.reply_to_message if replied: - CANCEL_LIST.append(replied.message_id) - await message.edit( - "`added your request to cancel list`", del_in=5) + replied.cancel_the_process() + await message.edit("`added your request to the cancel list`", del_in=5) else: - await message.edit( - "`reply to the message you want to cancel`", del_in=5) + await message.edit("`reply to the message you want to cancel`", del_in=5) diff --git a/userge/plugins/tools/delete.py b/userge/plugins/tools/delete.py index 81f9e7817..1dfb5c35f 100644 --- a/userge/plugins/tools/delete.py +++ b/userge/plugins/tools/delete.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/tools/ids.py b/userge/plugins/tools/ids.py index c0927a775..39476c538 100644 --- a/userge/plugins/tools/ids.py +++ b/userge/plugins/tools/ids.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/tools/json.py b/userge/plugins/tools/json.py index b144d8f1d..1167e07d4 100644 --- a/userge/plugins/tools/json.py +++ b/userge/plugins/tools/json.py @@ -1,4 +1,13 @@ -from userge import userge, Message, Config +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + +from userge import userge, Message @userge.on_cmd("json", about="""\ @@ -11,10 +20,6 @@ async def jsonify(message: Message): the_real_message = str(message.reply_to_message) if message.reply_to_message \ else str(message) - if len(the_real_message) > Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=the_real_message, - filename="json.txt", - caption="Too Large") - - else: - await message.edit(the_real_message) + await message.edit_or_send_as_file(text=the_real_message, + filename="json.txt", + caption="Too Large") diff --git a/userge/plugins/tools/ping.py b/userge/plugins/tools/ping.py index 912ee8866..914f91f32 100644 --- a/userge/plugins/tools/ping.py +++ b/userge/plugins/tools/ping.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from datetime import datetime from userge import userge, Message diff --git a/userge/plugins/tools/sd.py b/userge/plugins/tools/sd.py index 28b0c55d6..10e3a71e9 100644 --- a/userge/plugins/tools/sd.py +++ b/userge/plugins/tools/sd.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/tools/search.py b/userge/plugins/tools/search.py index f6b9c1bd3..7b27f1b89 100644 --- a/userge/plugins/tools/search.py +++ b/userge/plugins/tools/search.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/utils/__init__.py b/userge/plugins/utils/__init__.py index e69de29bb..4bba28ab4 100644 --- a/userge/plugins/utils/__init__.py +++ b/userge/plugins/utils/__init__.py @@ -0,0 +1,7 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. \ No newline at end of file diff --git a/userge/plugins/utils/admins.py b/userge/plugins/utils/admins.py index 9e2a421c0..cc9680154 100644 --- a/userge/plugins/utils/admins.py +++ b/userge/plugins/utils/admins.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from userge import userge, Message diff --git a/userge/plugins/utils/executor.py b/userge/plugins/utils/executor.py index 9fa289658..8389f3203 100644 --- a/userge/plugins/utils/executor.py +++ b/userge/plugins/utils/executor.py @@ -1,9 +1,18 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import io import sys import traceback from getpass import getuser from os import geteuid -from userge import userge, Config, Message +from userge import userge, Message from userge.utils import runcmd @@ -64,13 +73,9 @@ async def aexec(code, userge, message): output = "**EVAL**:\n```{}```\n\n\ **OUTPUT**:\n```{}```".format(cmd, evaluation.strip()) - if len(output) > Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, - filename="eval.txt", - caption=cmd) - - else: - await message.edit(output) + await message.edit_or_send_as_file(text=output, + filename="eval.txt", + caption=cmd) @userge.on_cmd("exec", about="""\ @@ -100,13 +105,9 @@ async def exec_(message: Message): __Command:__\n`{cmd}`\n__PID:__\n`{pid}`\n__RETURN:__\n`{ret}`\n\n\ **stderr:**\n`{err}`\n\n**stdout:**\n``{out}`` " - if len(output) > Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, - filename="exec.txt", - caption=cmd) - - else: - await message.edit(output) + await message.edit_or_send_as_file(text=output, + filename="exec.txt", + caption=cmd) @userge.on_cmd("term", about="""\ @@ -126,28 +127,23 @@ async def term_(message: Message): return out, err, _, _ = await runcmd(cmd) + curruser = getuser() - output = str(out) + str(err) - - if len(output) > Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, - filename="term.txt", - caption=cmd) - - else: - try: - uid = geteuid() + try: + uid = geteuid() - except ImportError: - uid = 1 + except ImportError: + uid = 1 - curruser = getuser() + if uid == 0: + output = f"`{curruser}:~# {cmd}\n{str(out) + str(err)}`" - if uid == 0: - await message.edit(f"`{curruser}:~# {cmd}\n{output}`") + else: + output = f"`{curruser}:~$ {cmd}\n{str(out) + str(err)}`" - else: - await message.edit(f"`{curruser}:~$ {cmd}\n{output}`") + await message.edit_or_send_as_file(text=output, + filename="term.txt", + caption=cmd) async def init_func(message: Message): diff --git a/userge/plugins/utils/google.py b/userge/plugins/utils/google.py index c5852e6ff..d62465cae 100644 --- a/userge/plugins/utils/google.py +++ b/userge/plugins/utils/google.py @@ -1,5 +1,14 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from search_engine_parser import GoogleSearch -from userge import userge, Message, Config +from userge import userge, Message @userge.on_cmd("google", about="""\ @@ -55,8 +64,4 @@ async def gsearch(message: Message): output = f"**Google Search:**\n`{query}`\n\n**Results:**\n{output}" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption=query) - - else: - await message.edit(output, disable_web_page_preview=True) + await message.edit_or_send_as_file(text=output, caption=query, disable_web_page_preview=True) diff --git a/userge/plugins/utils/header.py b/userge/plugins/utils/header.py index 85d9c2ba3..aef380763 100644 --- a/userge/plugins/utils/header.py +++ b/userge/plugins/utils/header.py @@ -1,5 +1,14 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import requests -from userge import userge, Message, Config +from userge import userge, Message @userge.on_cmd("head", about="""\ @@ -47,8 +56,4 @@ async def req_head(message: Message): for k, v in cd.headers.items(): output += f" 🏷 __{k.lower()}__ : `{v}`\n\n" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption=link) - - else: - await message.edit(output, disable_web_page_preview=True) + await message.edit_or_send_as_file(text=output, caption=link, disable_web_page_preview=True) diff --git a/userge/plugins/utils/loader.py b/userge/plugins/utils/loader.py index 596579211..38a1985d5 100644 --- a/userge/plugins/utils/loader.py +++ b/userge/plugins/utils/loader.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os from userge import userge, Message from userge.utils import get_import_path diff --git a/userge/plugins/utils/purge.py b/userge/plugins/utils/purge.py index f75942da6..02e0f5a3e 100644 --- a/userge/plugins/utils/purge.py +++ b/userge/plugins/utils/purge.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from datetime import datetime from userge import userge, Message @@ -9,9 +18,9 @@ **Usage:** -reply `.purge` to the start message to purge + reply `.purge` to the start message to purge. use `.purge [user_id | user_name]` to purge messages from that user - or use `-u` flag to get user_id from replied message + or use `-u` flag to get user_id from replied message. **Example:** diff --git a/userge/plugins/utils/restart.py b/userge/plugins/utils/restart.py index f5719747f..676a71141 100644 --- a/userge/plugins/utils/restart.py +++ b/userge/plugins/utils/restart.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import asyncio from userge import userge, Message diff --git a/userge/plugins/utils/speedtest.py b/userge/plugins/utils/speedtest.py index 46c5f3270..2d73ff722 100644 --- a/userge/plugins/utils/speedtest.py +++ b/userge/plugins/utils/speedtest.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os import wget import speedtest diff --git a/userge/plugins/utils/translate.py b/userge/plugins/utils/translate.py index 3abdee6aa..f03c7e199 100644 --- a/userge/plugins/utils/translate.py +++ b/userge/plugins/utils/translate.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from json import dumps from emoji import get_emoji_regexp from googletrans import Translator, LANGUAGES @@ -70,8 +79,4 @@ async def translateme(message: Message): output = f"**Source ({source_lan.title()}):**`\n{text}`\n\n\ **Translation ({transl_lan.title()}):**\n`{reply_text.text}`" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption="translated") - - else: - await message.edit(output) + await message.edit_or_send_as_file(text=output, caption="translated") diff --git a/userge/plugins/utils/ub.py b/userge/plugins/utils/ub.py index cde575c36..7f985c467 100644 --- a/userge/plugins/utils/ub.py +++ b/userge/plugins/utils/ub.py @@ -1,6 +1,15 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from urllib.error import HTTPError import urbandict -from userge import userge, Message, Config +from userge import userge, Message @userge.on_cmd("ub", about="""\ @@ -8,7 +17,7 @@ **Usage:** - `.ub query` + `.ub [query]` **Exaple:** @@ -38,8 +47,4 @@ async def urban_dict(message: Message): **Meaning:** __{mean[0]['def']}__\n\n\ **Example:**\n__{mean[0]['example']}__" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption=query) - - else: - await message.edit(output) + await message.edit_or_send_as_file(text=output, caption=query) diff --git a/userge/plugins/utils/webss.py b/userge/plugins/utils/webss.py index ee7eacf26..ef2651338 100644 --- a/userge/plugins/utils/webss.py +++ b/userge/plugins/utils/webss.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os from time import time import requests diff --git a/userge/plugins/utils/whois.py b/userge/plugins/utils/whois.py index f30a31707..3c2a8a997 100644 --- a/userge/plugins/utils/whois.py +++ b/userge/plugins/utils/whois.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os from userge import userge, Message diff --git a/userge/plugins/utils/wikipedia.py b/userge/plugins/utils/wikipedia.py index 0ad02646b..e8cd589be 100644 --- a/userge/plugins/utils/wikipedia.py +++ b/userge/plugins/utils/wikipedia.py @@ -1,5 +1,14 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import wikipedia -from userge import userge, Message, Config +from userge import userge, Message @userge.on_cmd("wiki", about="""\ @@ -51,8 +60,4 @@ async def wiki_pedia(message: Message): output = f"**Wikipedia Search:**\n`{query}`\n\n**Results:**\n{output}" - if len(output) >= Config.MAX_MESSAGE_LENGTH: - await message.send_as_file(text=output, caption=query) - - else: - await message.edit(output, disable_web_page_preview=True) + await message.edit_or_send_as_file(text=output, caption=query, disable_web_page_preview=True) diff --git a/userge/utils/__init__.py b/userge/utils/__init__.py index bbecfce15..c8ba3fced 100644 --- a/userge/utils/__init__.py +++ b/userge/utils/__init__.py @@ -1,6 +1,15 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + from .config import Config from .logger import logging -from .progress import progress, CANCEL_LIST +from .progress import progress from .tools import ( take_screen_shot, diff --git a/userge/utils/config.py b/userge/utils/config.py index bc4be44f6..14779624f 100644 --- a/userge/utils/config.py +++ b/userge/utils/config.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import os from dotenv import load_dotenv from .logger import logging diff --git a/userge/utils/logger.py b/userge/utils/logger.py index 4e9b1fb51..73d604907 100644 --- a/userge/utils/logger.py +++ b/userge/utils/logger.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import logging logging.basicConfig(level=logging.INFO, diff --git a/userge/utils/progress.py b/userge/utils/progress.py index 9558bfe31..c24f6b1bb 100644 --- a/userge/utils/progress.py +++ b/userge/utils/progress.py @@ -1,23 +1,33 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import time -from pyrogram import Client, Message from pyrogram.errors.exceptions import FloodWait -from .tools import humanbytes, time_formatter -CANCEL_LIST = [] +from userge.core._userge.base import BaseClient, BaseMessage +from .tools import humanbytes, time_formatter async def progress(current: int, total: int, ud_type: str, - userge: Client, - message: Message, + userge: BaseClient, + message: BaseMessage, start: int) -> None: - if message.message_id in CANCEL_LIST: + + if message.process_is_canceled: await userge.stop_transmission() now = time.time() diff = now - start - if diff % 10 < 0.1 or current == total: + + if diff % 10 < 0.5 or current == total: percentage = current * 100 // total speed = current // diff time_to_completion = (total - current) // speed diff --git a/userge/utils/tools.py b/userge/utils/tools.py index 8febe0bd4..b199ae8e0 100644 --- a/userge/utils/tools.py +++ b/userge/utils/tools.py @@ -1,3 +1,12 @@ +# Copyright (C) 2020 by UsergeTeam@Telegram, < https://t.me/theUserge >. +# +# This file is part of < https://github.com/uaudith/Userge > project, +# and is released under the "GNU v3.0 License Agreement". +# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE > +# +# All rights reserved. + + import asyncio import shlex from os.path import isfile, relpath @@ -49,10 +58,11 @@ async def runcmd(cmd: str): async def take_screen_shot(video_file: str, duration: int): LOG.info(f'[[[Extracting a frame from {video_file} ||| Video duration => {duration}]]]') + ttl = duration // 2 thumb_image_path = f"{video_file}.jpg" - # -filter:v scale=90:-1 command = f"ffmpeg -ss {ttl} -i '{video_file}' -vframes 1 '{thumb_image_path}'" + _, err, _, _ = await runcmd(command) if err: @@ -68,11 +78,13 @@ def __missing__(self, key): def get_import_path(root: str, path: str): seperator = '\\' if '\\' in root else '/' + if isfile(path): return '.'.join(relpath(path, root).split(seperator))[:-3] else: all_paths = glob(root + path.rstrip(seperator) + f"{seperator}*.py", recursive=True) + return sorted( [ '.'.join(relpath(f, root).split(seperator))[:-3] for f in all_paths