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