#410 #439

Merged
edraft merged 10 commits from #410 into dev 2023-11-19 12:57:44 +01:00
16 changed files with 338 additions and 3 deletions
Showing only changes of commit e8cc42e155 - Show all commits

View File

@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS `ScheduledEventsHistory`
`ChannelId` BIGINT NULL,
`StartTime` DATETIME(6) NOT NULL,
`EndTime` DATETIME(6) NULL,
`EntityType` ENUM (1,2,3) NOT NULL,
`EntityType` ENUM ('1','2','3') NOT NULL,
`Location` VARCHAR(255) NULL,
`ServerId` BIGINT(20) DEFAULT NULL,
`Deleted` BOOL DEFAULT FALSE,

View File

@ -26,7 +26,7 @@ class ScheduledEventMigration(MigrationABC):
`ChannelId` BIGINT NULL,
`StartTime` DATETIME(6) NOT NULL,
`EndTime` DATETIME(6) NULL,
`EntityType` ENUM(1,2,3) NOT NULL,
`EntityType` ENUM('1','2','3') NOT NULL,
`Location` VARCHAR(255) NULL,
`ServerId` BIGINT,
`CreatedAt` DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),

View File

@ -1,8 +1,10 @@
import functools
from abc import ABC, abstractmethod
from inspect import signature, Parameter
from typing import Callable
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_core.type import R, T
from cpl_query.extension import List
@ -52,3 +54,16 @@ class FilterABC(ABC):
return f(*args, **kwargs)
return decorator
def _get_attributes_from_dict(self, attrs: list[tuple[str, type]], values: dict):
for key_pair in attrs:
attr = key_pair[0]
attr_type = key_pair[1]
if attr in values:
self.__setattr__(f"_{attr}", attr_type(values[attr]))
@staticmethod
def _filter_by_attributes(attrs: list[Callable], values: List[T]) -> List[R]:
for attr in attrs:
values = values.where(attr)
return values

View File

@ -20,6 +20,7 @@ from bot_data.model.auto_role_rule import AutoRoleRule
from bot_data.model.client import Client
from bot_data.model.known_user import KnownUser
from bot_data.model.level import Level
from bot_data.model.scheduled_event import ScheduledEvent
from bot_data.model.server import Server
from bot_data.model.server_config import ServerConfig
from bot_data.model.short_role_name import ShortRoleName
@ -213,6 +214,16 @@ class QueryABC(ObjectType):
access = True
break
elif type(element) == ScheduledEvent:
element: ScheduledEvent = element
for u in user.users:
u: User = u
guild = bot.get_guild(u.server.discord_id)
member = guild.get_member(u.discord_id)
if permissions.is_member_moderator(member) and u.server.id == element.server.id:
access = True
break
elif type(element) == dict and "key" in element and element["key"] in [e.value for e in FeatureFlagsEnum]:
for u in user.users:
u: User = u

View File

@ -0,0 +1,71 @@
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_data.model.scheduled_event import ScheduledEvent
from bot_graphql.abc.filter_abc import FilterABC
class ScheduledEventFilter(FilterABC):
def __init__(self, bot: DiscordBotServiceABC, services: ServiceProviderABC):
FilterABC.__init__(self)
self._bot = bot
self._services = services
self._id = None
self._interval = None
self._name = None
self._description = None
self._channel_id = None
self._start_time = None
self._end_time = None
self._entity_type = None
self._location = None
self._server = None
def from_dict(self, values: dict):
self._get_attributes_from_dict(
[
("id", int),
("interval", str),
("name", str),
("description", str),
("channel_id", str),
("start_time", str),
("end_time", str),
("entity_type", str),
("location", str),
],
values,
)
if "server" in values:
from bot_graphql.filter.server_filter import ServerFilter
self._server: ServerFilter = self._services.get_service(ServerFilter)
self._server.from_dict(values["server"])
def filter(self, query: List[ScheduledEvent]) -> List[ScheduledEvent]:
if self._id is not None:
query = query.where(lambda x: x.id == self._id)
query = self._filter_by_attributes(
[
lambda x: x.id == self._id,
lambda x: x.interval == self._interval,
lambda x: x.name == self._name,
lambda x: x.description == self._description,
lambda x: x.channel_id == self._channel_id,
lambda x: x.start_time == self._start_time,
lambda x: x.end_time == self._end_time,
lambda x: x.entity_type == self._entity_type,
lambda x: x.location == self._location,
],
query,
)
if self._server is not None:
servers = self._server.filter(query.select(lambda x: x.server)).select(lambda x: x.id)
query = query.where(lambda x: x.server.id in servers)
return query

View File

@ -1,3 +1,4 @@
from cpl_core.dependency_injection import ServiceProviderABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
@ -8,9 +9,10 @@ from bot_graphql.abc.filter_abc import FilterABC
class ShortRoleNameFilter(FilterABC):
def __init__(self, bot: DiscordBotServiceABC):
def __init__(self, bot: DiscordBotServiceABC, services: ServiceProviderABC):
FilterABC.__init__(self)
self._bot = bot
self._services = services
self._id = None
self._short_name = None

View File

@ -6,6 +6,7 @@ type Mutation {
userJoinedGameServer: UserJoinedGameServerMutation
achievement: AchievementMutation
shortRoleName: ShortRoleNameMutation
scheduledEvent: ScheduledEventMutation
technicianConfig: TechnicianConfigMutation
serverConfig: ServerConfigMutation
}

View File

@ -41,6 +41,9 @@ type Query {
shortRoleNames(filter: ShortRoleNameFilter, page: Page, sort: Sort): [ShortRoleName]
shortRoleNamePositions: [String]
scheduledEventCount: Int
scheduledEvents(filter: ScheduledEventFilter, page: Page, sort: Sort): [ScheduledEvent]
userWarningCount: Int
userWarnings(filter: UserWarningFilter, page: Page, sort: Sort): [UserWarning]

View File

@ -0,0 +1,68 @@
type ScheduledEvent implements TableWithHistoryQuery {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: Server
createdAt: String
modifiedAt: String
history: [ScheduledEventHistory]
}
type ScheduledEventHistory implements HistoryTableQuery {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: ID
deleted: Boolean
dateFrom: String
dateTo: String
}
input ScheduledEventFilter {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
server: ServerFilter
}
type ScheduledEventMutation {
createScheduledEvent(input: ScheduledEventInput!): ScheduledEvent
updateScheduledEvent(input: ScheduledEventInput!): ScheduledEvent
deleteScheduledEvent(id: ID): ScheduledEvent
}
input ScheduledEventInput {
id: ID
interval: String
name: String
description: String
channelId: String
startTime: String
endTime: String
entityType: Int
location: String
serverId: ID
}

View File

@ -35,6 +35,9 @@ type Server implements TableWithHistoryQuery {
shortRoleNameCount: Int
shortRoleNames(filter: ShortRoleNameFilter, page: Page, sort: Sort): [ShortRoleName]
scheduledEventCount: Int
scheduledEvents(filter: ScheduledEventFilter, page: Page, sort: Sort): [ScheduledEvent]
config: ServerConfig
hasFeatureFlag(flag: String): FeatureFlag

View File

@ -12,6 +12,7 @@ from bot_graphql.filter.auto_role_filter import AutoRoleFilter
from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter
from bot_graphql.filter.client_filter import ClientFilter
from bot_graphql.filter.level_filter import LevelFilter
from bot_graphql.filter.scheduled_event_filter import ScheduledEventFilter
from bot_graphql.filter.server_filter import ServerFilter
from bot_graphql.filter.short_role_name_filter import ShortRoleNameFilter
from bot_graphql.filter.user_filter import UserFilter
@ -27,6 +28,7 @@ from bot_graphql.mutations.achievement_mutation import AchievementMutation
from bot_graphql.mutations.auto_role_mutation import AutoRoleMutation
from bot_graphql.mutations.auto_role_rule_mutation import AutoRoleRuleMutation
from bot_graphql.mutations.level_mutation import LevelMutation
from bot_graphql.mutations.scheduled_event_mutation import ScheduledEventMutation
from bot_graphql.mutations.server_config_mutation import ServerConfigMutation
from bot_graphql.mutations.short_role_name_mutation import ShortRoleNameMutation
from bot_graphql.mutations.technician_config_mutation import TechnicianConfigMutation
@ -54,6 +56,7 @@ from bot_graphql.queries.known_user_history_query import KnownUserHistoryQuery
from bot_graphql.queries.known_user_query import KnownUserQuery
from bot_graphql.queries.level_history_query import LevelHistoryQuery
from bot_graphql.queries.level_query import LevelQuery
from bot_graphql.queries.scheduled_event_query import ScheduledEventQuery
from bot_graphql.queries.server_config_query import ServerConfigQuery
from bot_graphql.queries.server_history_query import ServerHistoryQuery
from bot_graphql.queries.server_query import ServerQuery
@ -140,6 +143,7 @@ class GraphQLModule(ModuleABC):
services.add_transient(QueryABC, UserWarningHistoryQuery)
services.add_transient(QueryABC, UserWarningQuery)
services.add_transient(QueryABC, ServerStatisticQuery)
services.add_transient(QueryABC, ScheduledEventQuery)
services.add_transient(QueryABC, DiscordQuery)
services.add_transient(QueryABC, GuildQuery)
@ -161,6 +165,7 @@ class GraphQLModule(ModuleABC):
services.add_transient(FilterABC, UserJoinedGameServerFilter)
services.add_transient(FilterABC, ShortRoleNameFilter)
services.add_transient(FilterABC, UserWarningFilter)
services.add_transient(FilterABC, ScheduledEventFilter)
# mutations
services.add_transient(QueryABC, AutoRoleMutation)
@ -172,3 +177,4 @@ class GraphQLModule(ModuleABC):
services.add_transient(QueryABC, UserJoinedGameServerMutation)
services.add_transient(QueryABC, TechnicianConfigMutation)
services.add_transient(QueryABC, ServerConfigMutation)
services.add_transient(QueryABC, ScheduledEventMutation)

View File

@ -0,0 +1,92 @@
from cpl_core.database.context import DatabaseContextABC
from cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.model.scheduled_event import ScheduledEvent
from bot_data.model.user_role_enum import UserRoleEnum
from bot_graphql.abc.query_abc import QueryABC
from modules.permission.service.permission_service import PermissionService
class ScheduledEventMutation(QueryABC):
def __init__(
self,
servers: ServerRepositoryABC,
scheduled_events: ScheduledEventRepositoryABC,
bot: DiscordBotServiceABC,
db: DatabaseContextABC,
permissions: PermissionService,
):
QueryABC.__init__(self, "ScheduledEventMutation")
self._servers = servers
self._scheduled_events = scheduled_events
self._bot = bot
self._db = db
self._permissions = permissions
self.set_field("createScheduledEvent", self.resolve_create_scheduled_event)
self.set_field("updateScheduledEvent", self.resolve_update_scheduled_event)
self.set_field("deleteScheduledEvent", self.resolve_delete_scheduled_event)
def resolve_create_scheduled_event(self, *_, input: dict):
server = self._servers.get_server_by_id(input["serverId"])
self._can_user_mutate_data(server, UserRoleEnum.moderator)
scheduled_event = ScheduledEvent(
input["interval"],
input["name"],
input["description"],
input["channel_id"],
input["start_time"],
input["end_time"],
input["entity_type"],
input["location"],
server,
)
self._scheduled_events.add_scheduled_event(scheduled_event)
self._db.save_changes()
def get_new_scheduled_event(srn: ScheduledEvent):
return (
srn.interval == scheduled_event.interval
and srn.name == scheduled_event.name
and srn.description == scheduled_event.description
)
return (
self._scheduled_events.get_scheduled_events_by_server_id(scheduled_event.server.id)
.where(get_new_scheduled_event)
.last()
)
def resolve_update_scheduled_event(self, *_, input: dict):
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(input["id"])
self._can_user_mutate_data(scheduled_event.server, UserRoleEnum.moderator)
scheduled_event.short_name = input["shortName"] if "shortName" in input else scheduled_event.short_name
scheduled_event.interval = input["interval"] if "interval" in input else scheduled_event.interval
scheduled_event.name = input["name"] if "name" in input else scheduled_event.name
scheduled_event.description = input["description"] if "description" in input else scheduled_event.description
scheduled_event.channel_id = input["channel_id"] if "channel_id" in input else scheduled_event.channel_id
scheduled_event.start_time = input["start_time"] if "start_time" in input else scheduled_event.start_time
scheduled_event.end_time = input["end_time"] if "end_time" in input else scheduled_event.end_time
scheduled_event.entity_type = input["entity_type"] if "entity_type" in input else scheduled_event.entity_type
scheduled_event.location = input["location"] if "location" in input else scheduled_event.location
self._scheduled_events.update_scheduled_event(scheduled_event)
self._db.save_changes()
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(input["id"])
return scheduled_event
def resolve_delete_scheduled_event(self, *_, id: int):
scheduled_event = self._scheduled_events.get_scheduled_event_by_id(id)
self._can_user_mutate_data(scheduled_event.server, UserRoleEnum.admin)
self._scheduled_events.delete_scheduled_event(scheduled_event)
self._db.save_changes()
return scheduled_event

View File

@ -0,0 +1,24 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.scheduled_event_history import ScheduledEventHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ScheduledEventHistoryQuery(DataQueryWithHistoryABC):
def __init__(
self,
db: DatabaseContextABC,
):
DataQueryWithHistoryABC.__init__(self, "ScheduledEvent", "ScheduledEventsHistory", ScheduledEventHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("id", lambda x, *_: x.id)
self.set_field("interval", lambda x, *_: x.interval)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("channel_id", lambda x, *_: x.channel_id)
self.set_field("start_time", lambda x, *_: x.start_time)
self.set_field("end_time", lambda x, *_: x.end_time)
self.set_field("entity_type", lambda x, *_: x.entity_type)
self.set_field("location", lambda x, *_: x.location)
self.set_field("server", lambda x, *_: x.server)

View File

@ -0,0 +1,23 @@
from cpl_core.database.context import DatabaseContextABC
from bot_data.model.scheduled_event_history import ScheduledEventHistory
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
class ScheduledEventQuery(DataQueryWithHistoryABC):
def __init__(
self,
db: DatabaseContextABC,
):
DataQueryWithHistoryABC.__init__(self, "ScheduledEvent", "ScheduledEventsHistory", ScheduledEventHistory, db)
self.set_field("id", lambda x, *_: x.id)
self.set_field("interval", lambda x, *_: x.interval)
self.set_field("name", lambda x, *_: x.name)
self.set_field("description", lambda x, *_: x.description)
self.set_field("channelId", lambda x, *_: x.channel_id)
self.set_field("startTime", lambda x, *_: x.start_time)
self.set_field("endTime", lambda x, *_: x.end_time)
self.set_field("entityType", lambda x, *_: x.entity_type)
self.set_field("location", lambda x, *_: x.location)
self.set_field("server", lambda x, *_: x.server)

View File

@ -9,6 +9,7 @@ from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.client_repository_abc import ClientRepositoryABC
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
from bot_data.abc.level_repository_abc import LevelRepositoryABC
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.abc.server_config_repository_abc import ServerConfigRepositoryABC
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC
@ -24,6 +25,7 @@ from bot_graphql.filter.achievement_filter import AchievementFilter
from bot_graphql.filter.auto_role_filter import AutoRoleFilter
from bot_graphql.filter.client_filter import ClientFilter
from bot_graphql.filter.level_filter import LevelFilter
from bot_graphql.filter.scheduled_event_filter import ScheduledEventFilter
from bot_graphql.filter.short_role_name_filter import ShortRoleNameFilter
from bot_graphql.filter.user_filter import UserFilter
from bot_graphql.model.server_statistics import ServerStatistics
@ -44,6 +46,7 @@ class ServerQuery(DataQueryWithHistoryABC):
ujvs: UserJoinedVoiceChannelRepositoryABC,
achievements: AchievementRepositoryABC,
short_role_names: ShortRoleNameRepositoryABC,
scheduled_events: ScheduledEventRepositoryABC,
server_configs: ServerConfigRepositoryABC,
):
DataQueryWithHistoryABC.__init__(self, "Server", "ServersHistory", ServerHistory, db)
@ -100,6 +103,11 @@ class ServerQuery(DataQueryWithHistoryABC):
lambda server, *_: short_role_names.get_short_role_names_by_server_id(server.id),
ShortRoleNameFilter,
)
self.add_collection(
"scheduledEvent",
lambda server, *_: scheduled_events.get_scheduled_events_by_server_id(server.id),
ScheduledEventFilter,
)
self.set_field(
"config",
lambda server, *_: server_configs.get_server_config_by_server(server.id),

View File

@ -8,6 +8,7 @@ from bot_data.abc.client_repository_abc import ClientRepositoryABC
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from bot_data.abc.level_repository_abc import LevelRepositoryABC
from bot_data.abc.scheduled_event_repository_abc import ScheduledEventRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
from bot_data.abc.technician_config_repository_abc import TechnicianConfigRepositoryABC
@ -27,6 +28,7 @@ from bot_graphql.filter.auto_role_filter import AutoRoleFilter
from bot_graphql.filter.auto_role_rule_filter import AutoRoleRuleFilter
from bot_graphql.filter.client_filter import ClientFilter
from bot_graphql.filter.level_filter import LevelFilter
from bot_graphql.filter.scheduled_event_filter import ScheduledEventFilter
from bot_graphql.filter.server_filter import ServerFilter
from bot_graphql.filter.short_role_name_filter import ShortRoleNameFilter
from bot_graphql.filter.user_filter import UserFilter
@ -59,6 +61,7 @@ class Query(QueryABC):
user_warnings: UserWarningsRepositoryABC,
achievement_service: AchievementService,
technician_config: TechnicianConfigRepositoryABC,
scheduled_events: ScheduledEventRepositoryABC,
):
QueryABC.__init__(self, "Query")
@ -95,6 +98,11 @@ class Query(QueryABC):
lambda *_: short_role_names.get_short_role_names(),
ShortRoleNameFilter,
)
self.add_collection(
"scheduledEvent",
lambda server, *_: scheduled_events.get_scheduled_events_by_server_id(server.id),
ScheduledEventFilter,
)
self.add_collection(
"userWarning",
lambda *_: user_warnings.get_user_warnings(),