mirror of
https://github.com/pyrogram/pyrogram
synced 2025-08-28 21:07:59 +00:00
Type hint all Pyrogram types
This commit is contained in:
parent
e8fbae3166
commit
5035daa9d7
@ -19,6 +19,7 @@
|
||||
from base64 import b64encode
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ..user_and_chats import User
|
||||
@ -58,11 +59,11 @@ class CallbackQuery(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
id: str,
|
||||
from_user,
|
||||
from_user: User,
|
||||
chat_instance: str,
|
||||
message=None,
|
||||
message: "pyrogram.Message" = None,
|
||||
inline_message_id: str = None,
|
||||
data: bytes = None,
|
||||
game_short_name: str = None):
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
from pyrogram.api.types import ReplyInlineMarkup, KeyboardButtonRow
|
||||
from . import InlineKeyboardButton
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -30,7 +32,7 @@ class InlineKeyboardMarkup(PyrogramType):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
inline_keyboard: list):
|
||||
inline_keyboard: List[List[InlineKeyboardButton]]):
|
||||
super().__init__(None)
|
||||
|
||||
self.inline_keyboard = inline_keyboard
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
from pyrogram.api.types import KeyboardButtonRow
|
||||
from pyrogram.api.types import ReplyKeyboardMarkup as RawReplyKeyboardMarkup
|
||||
from . import KeyboardButton
|
||||
@ -48,7 +50,7 @@ class ReplyKeyboardMarkup(PyrogramType):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
keyboard: list,
|
||||
keyboard: List[List[KeyboardButton]],
|
||||
resize_keyboard: bool = None,
|
||||
one_time_keyboard: bool = None,
|
||||
selective: bool = None):
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -58,12 +59,12 @@ class Animation(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
duration: int,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
file_name: str = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
@ -82,7 +83,7 @@ class Animation(PyrogramType):
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, animation: types.Document, video_attributes: types.DocumentAttributeVideo,
|
||||
file_name: str) -> "Animation":
|
||||
file_name: str) -> "Animation":
|
||||
return Animation(
|
||||
file_id=encode(
|
||||
pack(
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -58,10 +59,10 @@ class Audio(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
duration: int,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
file_name: str = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
@ -81,7 +82,8 @@ class Audio(PyrogramType):
|
||||
self.title = title
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, audio: types.Document, audio_attributes: types.DocumentAttributeAudio, file_name: str) -> "Audio":
|
||||
def _parse(client, audio: types.Document, audio_attributes: types.DocumentAttributeAudio,
|
||||
file_name: str) -> "Audio":
|
||||
return Audio(
|
||||
file_id=encode(
|
||||
pack(
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
|
||||
@ -42,7 +44,7 @@ class Contact(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
phone_number: str,
|
||||
first_name: str,
|
||||
last_name: str = None,
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -49,9 +50,9 @@ class Document(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
file_name: str = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
|
||||
@ -31,7 +33,11 @@ class Location(PyrogramType):
|
||||
Latitude as defined by sender.
|
||||
"""
|
||||
|
||||
def __init__(self, *, client, longitude: float, latitude: float):
|
||||
def __init__(self,
|
||||
*,
|
||||
client: "pyrogram.Client",
|
||||
longitude: float,
|
||||
latitude: float):
|
||||
super().__init__(client)
|
||||
|
||||
self.longitude = longitude
|
||||
|
@ -337,7 +337,7 @@ class Message(PyrogramType):
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, message: types.Message or types.MessageService or types.MessageEmpty, users: dict, chats: dict,
|
||||
replies: int = 1):
|
||||
replies: int = 1):
|
||||
if isinstance(message, types.MessageEmpty):
|
||||
return Message(message_id=message.id, empty=True, client=client)
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ..user_and_chats.user import User
|
||||
@ -63,12 +65,12 @@ class MessageEntity(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
type: str,
|
||||
offset: int,
|
||||
length: int,
|
||||
url: str = None,
|
||||
user=None):
|
||||
user: User = None):
|
||||
super().__init__(client)
|
||||
|
||||
self.type = type
|
||||
|
@ -16,6 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .message import Message
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -35,9 +38,9 @@ class Messages(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
total_count: int,
|
||||
messages: list):
|
||||
messages: List[Message]):
|
||||
super().__init__(client)
|
||||
|
||||
self.total_count = total_count
|
||||
|
@ -18,7 +18,9 @@
|
||||
|
||||
from base64 import b64encode
|
||||
from struct import pack
|
||||
from typing import List
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -41,10 +43,10 @@ class Photo(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
id: str,
|
||||
date: int,
|
||||
sizes: list):
|
||||
sizes: List[PhotoSize]):
|
||||
super().__init__(client)
|
||||
|
||||
self.id = id
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from pyrogram.client.ext.utils import encode
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -42,7 +43,7 @@ class PhotoSize(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
|
@ -19,6 +19,7 @@
|
||||
from functools import lru_cache
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types, functions
|
||||
from pyrogram.api.errors import StickersetInvalid
|
||||
from .photo_size import PhotoSize
|
||||
@ -65,18 +66,17 @@ class Sticker(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
file_name: str = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
date: int = None,
|
||||
emoji: str = None,
|
||||
set_name: str = None,
|
||||
mask_position=None):
|
||||
set_name: str = None):
|
||||
super().__init__(client)
|
||||
|
||||
self.file_id = file_id
|
||||
@ -89,7 +89,7 @@ class Sticker(PyrogramType):
|
||||
self.height = height
|
||||
self.emoji = emoji
|
||||
self.set_name = set_name
|
||||
self.mask_position = mask_position
|
||||
# self.mask_position = mask_position
|
||||
|
||||
@staticmethod
|
||||
@lru_cache(maxsize=256)
|
||||
@ -105,7 +105,7 @@ class Sticker(PyrogramType):
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, sticker: types.Document, image_size_attributes: types.DocumentAttributeImageSize,
|
||||
sticker_attributes: types.DocumentAttributeSticker, file_name: str) -> "Sticker":
|
||||
sticker_attributes: types.DocumentAttributeSticker, file_name: str) -> "Sticker":
|
||||
sticker_set = sticker_attributes.stickerset
|
||||
|
||||
if isinstance(sticker_set, types.InputStickerSetID):
|
||||
|
@ -16,6 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
import pyrogram
|
||||
from .photo import Photo
|
||||
from ..pyrogram_type import PyrogramType
|
||||
|
||||
@ -33,9 +36,9 @@ class UserProfilePhotos(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
total_count: int,
|
||||
photos: list):
|
||||
photos: List[Photo]):
|
||||
super().__init__(client)
|
||||
|
||||
self.total_count = total_count
|
||||
|
@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .location import Location
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -45,8 +46,8 @@ class Venue(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
location,
|
||||
client: "pyrogram.Client",
|
||||
location: Location,
|
||||
title: str,
|
||||
address: str,
|
||||
foursquare_id: str = None,
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -58,12 +59,12 @@ class Video(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
duration: int,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
file_name: str = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
@ -81,7 +82,8 @@ class Video(PyrogramType):
|
||||
self.duration = duration
|
||||
|
||||
@staticmethod
|
||||
def _parse(client, video: types.Document, video_attributes: types.DocumentAttributeVideo, file_name: str) -> "Video":
|
||||
def _parse(client, video: types.Document, video_attributes: types.DocumentAttributeVideo,
|
||||
file_name: str) -> "Video":
|
||||
return Video(
|
||||
file_id=encode(
|
||||
pack(
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .photo_size import PhotoSize
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -52,11 +53,11 @@ class VideoNote(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
length: int,
|
||||
duration: int,
|
||||
thumb=None,
|
||||
thumb: PhotoSize = None,
|
||||
mime_type: str = None,
|
||||
file_size: int = None,
|
||||
date: int = None):
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ...ext.utils import encode
|
||||
@ -48,7 +49,7 @@ class Voice(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
file_id: str,
|
||||
duration: int,
|
||||
waveform: bytes = None,
|
||||
|
@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .chat_photo import ChatPhoto
|
||||
from ..pyrogram_type import PyrogramType
|
||||
@ -78,7 +79,7 @@ class Chat(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
id: int,
|
||||
type: str,
|
||||
title: str = None,
|
||||
@ -86,7 +87,7 @@ class Chat(PyrogramType):
|
||||
first_name: str = None,
|
||||
last_name: str = None,
|
||||
all_members_are_administrators: bool = None,
|
||||
photo=None,
|
||||
photo: ChatPhoto = None,
|
||||
description: str = None,
|
||||
invite_link: str = None,
|
||||
pinned_message=None,
|
||||
@ -175,7 +176,7 @@ class Chat(PyrogramType):
|
||||
@staticmethod
|
||||
def _parse_full(client, chat_full: types.messages.ChatFull or types.UserFull) -> "Chat":
|
||||
if isinstance(chat_full, types.UserFull):
|
||||
_parsed_chat = Chat.parse_user_chat(client, chat_full.user)
|
||||
parsed_chat = Chat._parse_user_chat(client, chat_full.user)
|
||||
parsed_chat.description = chat_full.about
|
||||
else:
|
||||
full_chat = chat_full.full_chat
|
||||
@ -186,12 +187,12 @@ class Chat(PyrogramType):
|
||||
chat = i
|
||||
|
||||
if isinstance(full_chat, types.ChatFull):
|
||||
_parsed_chat = Chat.parse_chat_chat(client, chat)
|
||||
parsed_chat = Chat._parse_chat_chat(client, chat)
|
||||
|
||||
if isinstance(full_chat.participants, types.ChatParticipants):
|
||||
parsed_chat.members_count = len(full_chat.participants.participants)
|
||||
else:
|
||||
_parsed_chat = Chat.parse_channel_chat(client, chat)
|
||||
parsed_chat = Chat._parse_channel_chat(client, chat)
|
||||
parsed_chat.members_count = full_chat.participants_count
|
||||
parsed_chat.description = full_chat.about or None
|
||||
# TODO: Add StickerSet type
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
|
||||
@ -81,8 +83,8 @@ class ChatMember(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
user,
|
||||
client: "pyrogram.Client",
|
||||
user: "pyrogram.User",
|
||||
status: str,
|
||||
until_date: int = None,
|
||||
can_be_edited: bool = None,
|
||||
|
@ -16,6 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .chat_member import ChatMember
|
||||
from .user import User
|
||||
@ -35,9 +38,9 @@ class ChatMembers(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
total_count: int,
|
||||
chat_members: list):
|
||||
chat_members: List[ChatMember]):
|
||||
super().__init__(client)
|
||||
|
||||
self.total_count = total_count
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
from struct import pack
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ...ext.utils import encode
|
||||
@ -36,7 +37,7 @@ class ChatPhoto(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
small_file_id: str,
|
||||
big_file_id: str):
|
||||
super().__init__(client)
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
from ..user_and_chats import Chat
|
||||
@ -46,9 +48,9 @@ class Dialog(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
chat,
|
||||
top_message,
|
||||
client: "pyrogram.Client",
|
||||
chat: Chat,
|
||||
top_message: "pyrogram.Message",
|
||||
unread_messages_count: int,
|
||||
unread_mentions_count: int,
|
||||
unread_mark: bool,
|
||||
|
@ -16,6 +16,9 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import List
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .dialog import Dialog
|
||||
from ..messages_and_media import Message
|
||||
@ -35,9 +38,9 @@ class Dialogs(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
total_count: int,
|
||||
dialogs: list):
|
||||
dialogs: List[Dialog]):
|
||||
super().__init__(client)
|
||||
|
||||
self.total_count = total_count
|
||||
|
@ -16,6 +16,7 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
from pyrogram.api import types
|
||||
from .chat_photo import ChatPhoto
|
||||
from .user_status import UserStatus
|
||||
@ -71,7 +72,7 @@ class User(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
id: int,
|
||||
is_self: bool,
|
||||
is_contact: bool,
|
||||
@ -80,11 +81,11 @@ class User(PyrogramType):
|
||||
is_bot: bool,
|
||||
first_name: str,
|
||||
last_name: str = None,
|
||||
status=None,
|
||||
status: UserStatus = None,
|
||||
username: str = None,
|
||||
language_code: str = None,
|
||||
phone_number: str = None,
|
||||
photo=None,
|
||||
photo: ChatPhoto = None,
|
||||
restriction_reason: str = None):
|
||||
super().__init__(client)
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pyrogram
|
||||
|
||||
from pyrogram.api import types
|
||||
from ..pyrogram_type import PyrogramType
|
||||
|
||||
@ -64,7 +66,7 @@ class UserStatus(PyrogramType):
|
||||
|
||||
def __init__(self,
|
||||
*,
|
||||
client,
|
||||
client: "pyrogram.Client",
|
||||
user_id: int,
|
||||
online: bool = None,
|
||||
offline: bool = None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user