Added user joined game server gql query #181
This commit is contained in:
parent
0b5acdea58
commit
1e74584e71
@ -16,9 +16,9 @@ class UserJoinedGameServer(TableABC):
|
|||||||
modified_at: datetime = None,
|
modified_at: datetime = None,
|
||||||
id=0,
|
id=0,
|
||||||
):
|
):
|
||||||
self._join_id = id
|
self._id = id
|
||||||
self._game_server = game_server
|
|
||||||
self._user = user
|
self._user = user
|
||||||
|
self._game_server = game_server
|
||||||
self._joined_on = joined_on
|
self._joined_on = joined_on
|
||||||
self._leaved_on = leaved_on
|
self._leaved_on = leaved_on
|
||||||
|
|
||||||
@ -27,17 +27,17 @@ class UserJoinedGameServer(TableABC):
|
|||||||
self._modified_at = modified_at if modified_at is not None else self._modified_at
|
self._modified_at = modified_at if modified_at is not None else self._modified_at
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def join_id(self) -> int:
|
def id(self) -> int:
|
||||||
return self._join_id
|
return self._id
|
||||||
|
|
||||||
@property
|
|
||||||
def game_server(self) -> str:
|
|
||||||
return self._game_server
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def user(self) -> User:
|
def user(self) -> User:
|
||||||
return self._user
|
return self._user
|
||||||
|
|
||||||
|
@property
|
||||||
|
def game_server(self) -> str:
|
||||||
|
return self._game_server
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def joined_on(self) -> datetime:
|
def joined_on(self) -> datetime:
|
||||||
return self._joined_on
|
return self._joined_on
|
||||||
@ -131,7 +131,7 @@ class UserJoinedGameServer(TableABC):
|
|||||||
UPDATE `UserJoinedGameServer`
|
UPDATE `UserJoinedGameServer`
|
||||||
SET `LeavedOn` = '{self._leaved_on}',
|
SET `LeavedOn` = '{self._leaved_on}',
|
||||||
`LastModifiedAt` = '{self._modified_at}'
|
`LastModifiedAt` = '{self._modified_at}'
|
||||||
WHERE `Id` = {self._join_id};
|
WHERE `Id` = {self._id};
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -140,7 +140,7 @@ class UserJoinedGameServer(TableABC):
|
|||||||
return str(
|
return str(
|
||||||
f"""
|
f"""
|
||||||
DELETE FROM `UserJoinedGameServer`
|
DELETE FROM `UserJoinedGameServer`
|
||||||
WHERE `Id` = {self._join_id};
|
WHERE `Id` = {self._id};
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from bot_data.model.known_user import KnownUser
|
|||||||
from bot_data.model.level import Level
|
from bot_data.model.level import Level
|
||||||
from bot_data.model.server import Server
|
from bot_data.model.server import Server
|
||||||
from bot_data.model.user import User
|
from bot_data.model.user import User
|
||||||
|
from bot_data.model.user_joined_game_server import UserJoinedGameServer
|
||||||
from bot_data.model.user_joined_server import UserJoinedServer
|
from bot_data.model.user_joined_server import UserJoinedServer
|
||||||
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
|
||||||
from bot_data.model.user_role_enum import UserRoleEnum
|
from bot_data.model.user_role_enum import UserRoleEnum
|
||||||
@ -141,6 +142,13 @@ class QueryABC(ObjectType):
|
|||||||
access = True
|
access = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
elif type(element) == UserJoinedGameServer:
|
||||||
|
for u in user.users:
|
||||||
|
u: User = u
|
||||||
|
if u.user_id == element.user.user_id:
|
||||||
|
access = True
|
||||||
|
break
|
||||||
|
|
||||||
return access
|
return access
|
||||||
|
|
||||||
@ServiceProviderABC.inject
|
@ServiceProviderABC.inject
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
from cpl_query.extension import List
|
||||||
|
|
||||||
|
from bot_data.model.user_joined_game_server import UserJoinedGameServer
|
||||||
|
from bot_graphql.abc.filter_abc import FilterABC
|
||||||
|
|
||||||
|
|
||||||
|
class UserJoinedGameServerFilter(FilterABC):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
services: ServiceProviderABC,
|
||||||
|
bot: DiscordBotServiceABC,
|
||||||
|
):
|
||||||
|
FilterABC.__init__(self)
|
||||||
|
|
||||||
|
self._services = services
|
||||||
|
self._bot = bot
|
||||||
|
|
||||||
|
self._id = None
|
||||||
|
self._game_server = None
|
||||||
|
self._user = None
|
||||||
|
self._joined_on = None
|
||||||
|
self._leaved_on = None
|
||||||
|
|
||||||
|
def from_dict(self, values: dict):
|
||||||
|
if "id" in values:
|
||||||
|
self._id = int(values["id"])
|
||||||
|
|
||||||
|
if "gameServer" in values:
|
||||||
|
self._game_server = values["gameServer"]
|
||||||
|
|
||||||
|
if "user" in values:
|
||||||
|
from bot_graphql.filter.user_filter import UserFilter
|
||||||
|
|
||||||
|
self._user: UserFilter = self._services.get_service(UserFilter)
|
||||||
|
self._user.from_dict(values["user"])
|
||||||
|
|
||||||
|
if "joinedOn" in values:
|
||||||
|
self._joined_on = values["joinedOn"]
|
||||||
|
|
||||||
|
if "leavedOn" in values:
|
||||||
|
self._leaved_on = values["leavedOn"]
|
||||||
|
|
||||||
|
def filter(self, query: List[UserJoinedGameServer]) -> List[UserJoinedGameServer]:
|
||||||
|
if self._id is not None:
|
||||||
|
query = query.where(lambda x: x.id == self._id)
|
||||||
|
|
||||||
|
if self._game_server is not None:
|
||||||
|
query = query.where(lambda x: x.game_server == self._game_server)
|
||||||
|
|
||||||
|
if self._user is not None:
|
||||||
|
users = self._user.filter(query.select(lambda x: x.user)).select(lambda x: x.user_id)
|
||||||
|
query = query.where(lambda x: x.user.user_id in users)
|
||||||
|
|
||||||
|
if self._joined_on is not None:
|
||||||
|
query = query.where(lambda x: x.joined_on == self._joined_on or self._joined_on in x.joined_on)
|
||||||
|
|
||||||
|
if self._leaved_on is not None:
|
||||||
|
query = query.where(lambda x: x.leaved_on == self._leaved_on or self._leaved_on in x.leaved_on)
|
||||||
|
|
||||||
|
return query
|
@ -14,6 +14,7 @@ from bot_graphql.filter.client_filter import ClientFilter
|
|||||||
from bot_graphql.filter.level_filter import LevelFilter
|
from bot_graphql.filter.level_filter import LevelFilter
|
||||||
from bot_graphql.filter.server_filter import ServerFilter
|
from bot_graphql.filter.server_filter import ServerFilter
|
||||||
from bot_graphql.filter.user_filter import UserFilter
|
from bot_graphql.filter.user_filter import UserFilter
|
||||||
|
from bot_graphql.filter.user_joined_game_server_filter import UserJoinedGameServerFilter
|
||||||
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
||||||
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
||||||
from bot_graphql.graphql_service import GraphQLService
|
from bot_graphql.graphql_service import GraphQLService
|
||||||
@ -28,6 +29,7 @@ from bot_graphql.queries.client_query import ClientQuery
|
|||||||
from bot_graphql.queries.known_user_query import KnownUserQuery
|
from bot_graphql.queries.known_user_query import KnownUserQuery
|
||||||
from bot_graphql.queries.level_query import LevelQuery
|
from bot_graphql.queries.level_query import LevelQuery
|
||||||
from bot_graphql.queries.server_query import ServerQuery
|
from bot_graphql.queries.server_query import ServerQuery
|
||||||
|
from bot_graphql.queries.user_joined_game_server_query import UserJoinedGameServerQuery
|
||||||
from bot_graphql.queries.user_joined_server_query import UserJoinedServerQuery
|
from bot_graphql.queries.user_joined_server_query import UserJoinedServerQuery
|
||||||
from bot_graphql.queries.user_joined_voice_channel_query import UserJoinedVoiceChannelQuery
|
from bot_graphql.queries.user_joined_voice_channel_query import UserJoinedVoiceChannelQuery
|
||||||
from bot_graphql.queries.user_query import UserQuery
|
from bot_graphql.queries.user_query import UserQuery
|
||||||
@ -58,6 +60,7 @@ class GraphQLModule(ModuleABC):
|
|||||||
services.add_transient(QueryABC, UserQuery)
|
services.add_transient(QueryABC, UserQuery)
|
||||||
services.add_transient(QueryABC, UserJoinedServerQuery)
|
services.add_transient(QueryABC, UserJoinedServerQuery)
|
||||||
services.add_transient(QueryABC, UserJoinedVoiceChannelQuery)
|
services.add_transient(QueryABC, UserJoinedVoiceChannelQuery)
|
||||||
|
services.add_transient(QueryABC, UserJoinedGameServerQuery)
|
||||||
|
|
||||||
# filters
|
# filters
|
||||||
services.add_singleton(FilterABC, AutoRoleFilter)
|
services.add_singleton(FilterABC, AutoRoleFilter)
|
||||||
@ -68,6 +71,7 @@ class GraphQLModule(ModuleABC):
|
|||||||
services.add_singleton(FilterABC, UserFilter)
|
services.add_singleton(FilterABC, UserFilter)
|
||||||
services.add_singleton(FilterABC, UserJoinedServerFilter)
|
services.add_singleton(FilterABC, UserJoinedServerFilter)
|
||||||
services.add_singleton(FilterABC, UserJoinedVoiceChannelFilter)
|
services.add_singleton(FilterABC, UserJoinedVoiceChannelFilter)
|
||||||
|
services.add_singleton(FilterABC, UserJoinedGameServerFilter)
|
||||||
|
|
||||||
# mutations
|
# mutations
|
||||||
services.add_transient(QueryABC, AutoRoleMutation)
|
services.add_transient(QueryABC, AutoRoleMutation)
|
||||||
|
@ -18,10 +18,13 @@ type Query {
|
|||||||
servers(filter: ServerFilter, page: Page, sort: Sort): [Server]
|
servers(filter: ServerFilter, page: Page, sort: Sort): [Server]
|
||||||
|
|
||||||
userJoinedServerCount: Int
|
userJoinedServerCount: Int
|
||||||
userJoinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [User]
|
userJoinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer]
|
||||||
|
|
||||||
userJoinedVoiceChannelCount: Int
|
userJoinedVoiceChannelCount: Int
|
||||||
userJoinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [User]
|
userJoinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [UserJoinedVoiceChannel]
|
||||||
|
|
||||||
|
userJoinedGameServerCount: Int
|
||||||
|
userJoinedGameServers(filter: UserJoinedGameServerFilter, page: Page, sort: Sort): [UserJoinedGameServer]
|
||||||
|
|
||||||
userCount: Int
|
userCount: Int
|
||||||
users(filter: UserFilter, page: Page, sort: Sort): [User]
|
users(filter: UserFilter, page: Page, sort: Sort): [User]
|
||||||
|
@ -12,6 +12,9 @@ type User implements TableQuery {
|
|||||||
joinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [UserJoinedVoiceChannel]
|
joinedVoiceChannels(filter: UserJoinedVoiceChannelFilter, page: Page, sort: Sort): [UserJoinedVoiceChannel]
|
||||||
joinedVoiceChannelCount: Int
|
joinedVoiceChannelCount: Int
|
||||||
|
|
||||||
|
userJoinedGameServerCount: Int
|
||||||
|
userJoinedGameServers(filter: UserJoinedGameServerFilter, page: Page, sort: Sort): [UserJoinedGameServer]
|
||||||
|
|
||||||
server: Server
|
server: Server
|
||||||
|
|
||||||
createdAt: String
|
createdAt: String
|
||||||
|
18
kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql
Normal file
18
kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
type UserJoinedGameServer implements TableQuery {
|
||||||
|
id: ID
|
||||||
|
gameServer: String
|
||||||
|
user: User
|
||||||
|
joinedOn: String
|
||||||
|
leavedOn: String
|
||||||
|
|
||||||
|
createdAt: String
|
||||||
|
modifiedAt: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input UserJoinedGameServerFilter {
|
||||||
|
id: ID
|
||||||
|
gameServer: String
|
||||||
|
user: UserFilter
|
||||||
|
joinedOn: String
|
||||||
|
leavedOn: String
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
|
from bot_data.model.user_joined_game_server import UserJoinedGameServer
|
||||||
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
|
||||||
|
|
||||||
|
class UserJoinedGameServerQuery(DataQueryABC):
|
||||||
|
def __init__(self, bot: DiscordBotServiceABC):
|
||||||
|
DataQueryABC.__init__(self, "UserJoinedGameServer")
|
||||||
|
|
||||||
|
self._bot = bot
|
||||||
|
|
||||||
|
self.set_field("id", self.resolve_id)
|
||||||
|
self.set_field("gameServer", self.resolve_game_server)
|
||||||
|
self.set_field("user", self.resolve_user)
|
||||||
|
self.set_field("joinedOn", self.resolve_joined_on)
|
||||||
|
self.set_field("leavedOn", self.resolve_leaved_on)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_id(x: UserJoinedGameServer, *_):
|
||||||
|
return x.id
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_game_server(x: UserJoinedGameServer, *_):
|
||||||
|
return x.game_server
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_user(x: UserJoinedGameServer, *_):
|
||||||
|
return x.user
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_joined_on(x: UserJoinedGameServer, *_):
|
||||||
|
return x.joined_on
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def resolve_leaved_on(x: UserJoinedGameServer, *_):
|
||||||
|
return x.leaved_on
|
@ -1,10 +1,12 @@
|
|||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
|
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
||||||
|
from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC
|
||||||
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
||||||
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
|
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
|
||||||
from bot_data.model.user import User
|
from bot_data.model.user import User
|
||||||
from bot_graphql.abc.data_query_abc import DataQueryABC
|
from bot_graphql.abc.data_query_abc import DataQueryABC
|
||||||
|
from bot_graphql.filter.user_joined_game_server_filter import UserJoinedGameServerFilter
|
||||||
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
||||||
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
||||||
from modules.level.service.level_service import LevelService
|
from modules.level.service.level_service import LevelService
|
||||||
@ -18,12 +20,14 @@ class UserQuery(DataQueryABC):
|
|||||||
client_utils: ClientUtilsABC,
|
client_utils: ClientUtilsABC,
|
||||||
ujs: UserJoinedServerRepositoryABC,
|
ujs: UserJoinedServerRepositoryABC,
|
||||||
ujvs: UserJoinedVoiceChannelRepositoryABC,
|
ujvs: UserJoinedVoiceChannelRepositoryABC,
|
||||||
|
user_joined_game_server: UserJoinedGameServerRepositoryABC,
|
||||||
):
|
):
|
||||||
DataQueryABC.__init__(self, "User")
|
DataQueryABC.__init__(self, "User")
|
||||||
|
|
||||||
self._bot = bot
|
self._bot = bot
|
||||||
self._levels = levels
|
self._levels = levels
|
||||||
self._client_utils = client_utils
|
self._client_utils = client_utils
|
||||||
|
self._user_joined_game_server = user_joined_game_server
|
||||||
self._ujs = ujs
|
self._ujs = ujs
|
||||||
self._ujvs = ujvs
|
self._ujvs = ujvs
|
||||||
|
|
||||||
@ -43,6 +47,11 @@ class UserQuery(DataQueryABC):
|
|||||||
lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id),
|
lambda user, *_: self._ujvs.get_user_joined_voice_channels_by_user_id(user.user_id),
|
||||||
UserJoinedVoiceChannelFilter,
|
UserJoinedVoiceChannelFilter,
|
||||||
)
|
)
|
||||||
|
self.add_collection(
|
||||||
|
"userJoinedGameServer",
|
||||||
|
lambda user, *_: self._user_joined_game_server.get_user_joined_game_servers_by_user_id(user.user_id),
|
||||||
|
UserJoinedGameServerFilter,
|
||||||
|
)
|
||||||
self.set_field("server", self.resolve_server)
|
self.set_field("server", self.resolve_server)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -3,6 +3,7 @@ from bot_data.abc.client_repository_abc import ClientRepositoryABC
|
|||||||
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
|
||||||
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
from bot_data.abc.level_repository_abc import LevelRepositoryABC
|
||||||
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
from bot_data.abc.server_repository_abc import ServerRepositoryABC
|
||||||
|
from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC
|
||||||
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
|
||||||
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
|
from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC
|
||||||
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
from bot_data.abc.user_repository_abc import UserRepositoryABC
|
||||||
@ -13,6 +14,7 @@ from bot_graphql.filter.client_filter import ClientFilter
|
|||||||
from bot_graphql.filter.level_filter import LevelFilter
|
from bot_graphql.filter.level_filter import LevelFilter
|
||||||
from bot_graphql.filter.server_filter import ServerFilter
|
from bot_graphql.filter.server_filter import ServerFilter
|
||||||
from bot_graphql.filter.user_filter import UserFilter
|
from bot_graphql.filter.user_filter import UserFilter
|
||||||
|
from bot_graphql.filter.user_joined_game_server_filter import UserJoinedGameServerFilter
|
||||||
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
from bot_graphql.filter.user_joined_server_filter import UserJoinedServerFilter
|
||||||
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
from bot_graphql.filter.user_joined_voice_channel_filter import UserJoinedVoiceChannelFilter
|
||||||
|
|
||||||
@ -27,6 +29,7 @@ class Query(QueryABC):
|
|||||||
servers: ServerRepositoryABC,
|
servers: ServerRepositoryABC,
|
||||||
user_joined_servers: UserJoinedServerRepositoryABC,
|
user_joined_servers: UserJoinedServerRepositoryABC,
|
||||||
user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC,
|
user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC,
|
||||||
|
user_joined_game_server: UserJoinedGameServerRepositoryABC,
|
||||||
users: UserRepositoryABC,
|
users: UserRepositoryABC,
|
||||||
):
|
):
|
||||||
QueryABC.__init__(self, "Query")
|
QueryABC.__init__(self, "Query")
|
||||||
@ -37,6 +40,7 @@ class Query(QueryABC):
|
|||||||
self._servers = servers
|
self._servers = servers
|
||||||
self._user_joined_servers = user_joined_servers
|
self._user_joined_servers = user_joined_servers
|
||||||
self._user_joined_voice_channels = user_joined_voice_channel
|
self._user_joined_voice_channels = user_joined_voice_channel
|
||||||
|
self._user_joined_game_server = user_joined_game_server
|
||||||
self._users = users
|
self._users = users
|
||||||
|
|
||||||
self.add_collection("autoRole", lambda *_: self._auto_roles.get_auto_roles(), AutoRoleFilter)
|
self.add_collection("autoRole", lambda *_: self._auto_roles.get_auto_roles(), AutoRoleFilter)
|
||||||
@ -53,4 +57,9 @@ class Query(QueryABC):
|
|||||||
lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels(),
|
lambda *_: self._user_joined_voice_channels.get_user_joined_voice_channels(),
|
||||||
UserJoinedVoiceChannelFilter,
|
UserJoinedVoiceChannelFilter,
|
||||||
)
|
)
|
||||||
|
self.add_collection(
|
||||||
|
"userJoinedGameServer",
|
||||||
|
lambda *_: self._user_joined_game_server.get_user_joined_game_servers(),
|
||||||
|
UserJoinedGameServerFilter,
|
||||||
|
)
|
||||||
self.add_collection("user", lambda *_: self._users.get_users(), UserFilter)
|
self.add_collection("user", lambda *_: self._users.get_users(), UserFilter)
|
||||||
|
Loading…
Reference in New Issue
Block a user