Compare commits
14 Commits
6c5b514b41
...
1.2.4
Author | SHA1 | Date | |
---|---|---|---|
560c7650bd | |||
b0fb12f841 | |||
18386339b7 | |||
4d980331e2 | |||
e6667c78c8 | |||
9976c59302 | |||
293c8cd81c | |||
8f4ea56184 | |||
898e005978 | |||
db3e6183ba | |||
0a47393510 | |||
db61a764eb | |||
919eef79f6 | |||
5de6710261 |
Submodule bot/docker updated: b0bacce9f6...abd1708530
@@ -16,7 +16,7 @@
|
|||||||
"LicenseName": "MIT",
|
"LicenseName": "MIT",
|
||||||
"LicenseDescription": "MIT, see LICENSE for more details.",
|
"LicenseDescription": "MIT, see LICENSE for more details.",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"cpl-core==2023.10.0",
|
"cpl-core==2023.10.1",
|
||||||
"cpl-translation==2023.4.0.post1",
|
"cpl-translation==2023.4.0.post1",
|
||||||
"cpl-query==2023.10.0",
|
"cpl-query==2023.10.0",
|
||||||
"cpl-discord==2023.10.0.post1",
|
"cpl-discord==2023.10.0.post1",
|
||||||
|
Submodule bot/src/bot/config updated: c11ca6f2e8...4669bf7c43
@@ -74,7 +74,7 @@ class PermissionService(PermissionServiceABC):
|
|||||||
self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}")
|
self._logger.debug(__name__, f"Checking is member {member.name} {team_member_type.value}")
|
||||||
|
|
||||||
has_permission = True in [
|
has_permission = True in [
|
||||||
member.guild.get_role(x.role_id) not in member.roles
|
member.guild.get_role(x.role_id) in member.roles
|
||||||
for x in self._server_configs.get_server_config_by_server(
|
for x in self._server_configs.get_server_config_by_server(
|
||||||
self._servers.get_server_by_discord_id(member.guild.id).id
|
self._servers.get_server_by_discord_id(member.guild.id).id
|
||||||
).team_role_ids
|
).team_role_ids
|
||||||
|
@@ -31,6 +31,10 @@ class UserRepositoryABC(ABC):
|
|||||||
def get_users_by_server_id(self, server_id: int) -> List[User]:
|
def get_users_by_server_id(self, server_id: int) -> List[User]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]:
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
||||||
pass
|
pass
|
||||||
|
@@ -2,6 +2,7 @@ from datetime import datetime, date
|
|||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from cpl_core.database import TableABC
|
from cpl_core.database import TableABC
|
||||||
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
from cpl_discord.service import DiscordBotServiceABC
|
from cpl_discord.service import DiscordBotServiceABC
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
@@ -31,6 +32,8 @@ class User(TableABC):
|
|||||||
self._birthday = birthday
|
self._birthday = birthday
|
||||||
self._server = server
|
self._server = server
|
||||||
|
|
||||||
|
self._activity = 0
|
||||||
|
|
||||||
TableABC.__init__(self)
|
TableABC.__init__(self)
|
||||||
self._created_at = created_at if created_at is not None else self._created_at
|
self._created_at = created_at if created_at is not None else self._created_at
|
||||||
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
|
||||||
@@ -92,10 +95,40 @@ class User(TableABC):
|
|||||||
@property
|
@property
|
||||||
@ServiceProviderABC.inject
|
@ServiceProviderABC.inject
|
||||||
def ontime(self, services: ServiceProviderABC) -> float:
|
def ontime(self, services: ServiceProviderABC) -> float:
|
||||||
from bot_core.abc.client_utils_abc import ClientUtilsABC
|
db: DatabaseContextABC = services.get_service(DatabaseContextABC)
|
||||||
|
result = db.select(
|
||||||
|
f"""
|
||||||
|
SELECT ROUND(SUM(TIME_TO_SEC(TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)) / 3600),2)
|
||||||
|
FROM UserJoinedVoiceChannel
|
||||||
|
WHERE UserId = {self._user_id};
|
||||||
|
"""
|
||||||
|
)[0][0]
|
||||||
|
if result is None:
|
||||||
|
return 0
|
||||||
|
return float(result)
|
||||||
|
|
||||||
client_utils: ClientUtilsABC = services.get_service(ClientUtilsABC)
|
@property
|
||||||
return client_utils.get_ontime_for_user(self)
|
@ServiceProviderABC.inject
|
||||||
|
def game_ontime(self, services: ServiceProviderABC) -> float:
|
||||||
|
db: DatabaseContextABC = services.get_service(DatabaseContextABC)
|
||||||
|
result = db.select(
|
||||||
|
f"""
|
||||||
|
SELECT ROUND(SUM(TIME_TO_SEC(TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)) / 3600),2)
|
||||||
|
FROM UserJoinedGameServer
|
||||||
|
WHERE UserId = {self._user_id};
|
||||||
|
"""
|
||||||
|
)[0][0]
|
||||||
|
if result is None:
|
||||||
|
return 0
|
||||||
|
return float(result)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def activity(self) -> int:
|
||||||
|
return self._activity
|
||||||
|
|
||||||
|
@activity.setter
|
||||||
|
def activity(self, value: int):
|
||||||
|
self._activity = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ServiceProviderABC.inject
|
@ServiceProviderABC.inject
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
|
import datetime
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from cpl_core.database.context import DatabaseContextABC
|
from cpl_core.database.context import DatabaseContextABC
|
||||||
|
from cpl_core.type import T, R
|
||||||
from cpl_query.extension import List
|
from cpl_query.extension import List
|
||||||
|
|
||||||
from bot_core.logging.database_logger import DatabaseLogger
|
from bot_core.logging.database_logger import DatabaseLogger
|
||||||
@@ -38,7 +40,9 @@ class UserRepositoryService(UserRepositoryABC):
|
|||||||
|
|
||||||
def get_users(self) -> List[User]:
|
def get_users(self) -> List[User]:
|
||||||
self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}")
|
self._logger.trace(__name__, f"Send SQL command: {User.get_select_all_string()}")
|
||||||
return List(User, [self._from_result(user) for user in self._context.select(User.get_select_all_string())])
|
return List(
|
||||||
|
User, [self._from_result(user) for user in self._context.select(User.get_select_all_string())]
|
||||||
|
).for_each(lambda x: self._set_user_activity(x))
|
||||||
|
|
||||||
def get_user_by_id(self, id: int) -> User:
|
def get_user_by_id(self, id: int) -> User:
|
||||||
self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}")
|
self._logger.trace(__name__, f"Send SQL command: {User.get_select_by_id_string(id)}")
|
||||||
@@ -77,6 +81,16 @@ class UserRepositoryService(UserRepositoryABC):
|
|||||||
[self._from_result(user) for user in self._context.select(User.get_select_by_server_id_string(server_id))],
|
[self._from_result(user) for user in self._context.select(User.get_select_by_server_id_string(server_id))],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]:
|
||||||
|
self._logger.trace(
|
||||||
|
__name__,
|
||||||
|
f"Send SQL command: {User.get_select_by_server_id_string(server_id)}",
|
||||||
|
)
|
||||||
|
return List(
|
||||||
|
User,
|
||||||
|
[self._from_result(user) for user in self._context.select(User.get_select_by_server_id_string(server_id))],
|
||||||
|
).for_each(lambda x: self._set_user_activity(x))
|
||||||
|
|
||||||
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
|
||||||
self._logger.trace(
|
self._logger.trace(
|
||||||
__name__,
|
__name__,
|
||||||
@@ -109,3 +123,91 @@ class UserRepositoryService(UserRepositoryABC):
|
|||||||
def delete_user(self, user: User):
|
def delete_user(self, user: User):
|
||||||
self._logger.trace(__name__, f"Send SQL command: {user.delete_string}")
|
self._logger.trace(__name__, f"Send SQL command: {user.delete_string}")
|
||||||
self._context.cursor.execute(user.delete_string)
|
self._context.cursor.execute(user.delete_string)
|
||||||
|
|
||||||
|
def _set_user_activity(self, user):
|
||||||
|
days = (datetime.date.today() - (datetime.date.today() - datetime.timedelta(days=7))).days
|
||||||
|
query = f"""
|
||||||
|
SELECT (
|
||||||
|
(
|
||||||
|
SELECT Count(UserGotAchievements.CreatedAt)
|
||||||
|
FROM UserGotAchievements
|
||||||
|
INNER JOIN Achievements ON UserGotAchievements.AchievementId = Achievements.Id
|
||||||
|
INNER JOIN Users ON UserGotAchievements.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserGotAchievements.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
SELECT SUM(
|
||||||
|
UserMessageCountPerHour.XPCount / (
|
||||||
|
SELECT XpPerMessage
|
||||||
|
FROM CFG_Server
|
||||||
|
WHERE ServerId = {user.server.id}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
FROM UserMessageCountPerHour
|
||||||
|
INNER JOIN Users ON UserMessageCountPerHour.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserMessageCountPerHour.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
SELECT Count(UserJoinedVoiceChannel.CreatedAt)
|
||||||
|
FROM UserJoinedVoiceChannel
|
||||||
|
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserJoinedVoiceChannel.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
SELECT IFNULL(ROUND(SUM(TIME_TO_SEC(
|
||||||
|
TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)
|
||||||
|
) / 3600), 2), 0)
|
||||||
|
FROM UserJoinedVoiceChannel
|
||||||
|
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserJoinedVoiceChannel.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
SELECT Count(UserJoinedGameServer.CreatedAt)
|
||||||
|
FROM UserJoinedGameServer
|
||||||
|
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserJoinedGameServer.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) +
|
||||||
|
(
|
||||||
|
SELECT IFNULL(ROUND(SUM(TIME_TO_SEC(
|
||||||
|
TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)
|
||||||
|
) / 3600), 2), 0)
|
||||||
|
FROM UserJoinedGameServer
|
||||||
|
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserJoinedGameServer.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
) -
|
||||||
|
(
|
||||||
|
SELECT COUNT(UserWarnings.CreatedAt)
|
||||||
|
FROM UserWarnings
|
||||||
|
INNER JOIN Users ON UserWarnings.UserId = Users.UserId
|
||||||
|
WHERE Users.ServerId = {user.server.id}
|
||||||
|
AND Users.UserId = {user.id}
|
||||||
|
AND UserWarnings.CreatedAt >= "{datetime.date.today() - datetime.timedelta(days=7)}"
|
||||||
|
)
|
||||||
|
) / {days} * 1000 as count;
|
||||||
|
"""
|
||||||
|
user.activity = self._cast_query_result(query, int)
|
||||||
|
|
||||||
|
def _cast_query_result(self, query: str, r_type: T) -> Optional[R]:
|
||||||
|
results = self._context.select(query)
|
||||||
|
if len(results) == 0 or len(results[0]) == 0:
|
||||||
|
return None
|
||||||
|
result = results[0][0]
|
||||||
|
default = None
|
||||||
|
if r_type is int or r_type is float:
|
||||||
|
default = 0
|
||||||
|
elif r_type is str:
|
||||||
|
default = ""
|
||||||
|
|
||||||
|
return r_type(result) if result is not None else default
|
||||||
|
@@ -64,11 +64,9 @@ class QueryABC(ObjectType):
|
|||||||
if user == "system" or user.auth_role == AuthRoleEnum.admin:
|
if user == "system" or user.auth_role == AuthRoleEnum.admin:
|
||||||
return self._resolve_collection(collection, *args, **kwargs)
|
return self._resolve_collection(collection, *args, **kwargs)
|
||||||
|
|
||||||
for x in collection.to_list():
|
return self._resolve_collection(
|
||||||
if not self._can_user_see_element(user, x):
|
collection.where(lambda x: self._can_user_see_element(user, x)), *args, **kwargs
|
||||||
collection.remove(x)
|
)
|
||||||
|
|
||||||
return self._resolve_collection(collection, *args, **kwargs)
|
|
||||||
|
|
||||||
self.set_field(f"{name}s", wrapper)
|
self.set_field(f"{name}s", wrapper)
|
||||||
self.set_field(f"{name}Count", lambda *args: wrapper(*args).count())
|
self.set_field(f"{name}Count", lambda *args: wrapper(*args).count())
|
||||||
|
@@ -7,7 +7,9 @@ type User implements TableWithHistoryQuery {
|
|||||||
reactionCount: Int
|
reactionCount: Int
|
||||||
birthday: String
|
birthday: String
|
||||||
ontime: Float
|
ontime: Float
|
||||||
|
gameOntime: Float
|
||||||
level: Level
|
level: Level
|
||||||
|
activityScore: Int
|
||||||
|
|
||||||
joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer]
|
joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer]
|
||||||
joinedServerCount: Int
|
joinedServerCount: Int
|
||||||
|
@@ -86,7 +86,7 @@ class ServerQuery(DataQueryWithHistoryABC):
|
|||||||
)
|
)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"user",
|
"user",
|
||||||
lambda server, *_: self._users.get_users_by_server_id(server.id),
|
lambda server, *_: self._users.get_users_with_activity_by_server_id(server.id),
|
||||||
UserFilter,
|
UserFilter,
|
||||||
)
|
)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
|
@@ -114,7 +114,9 @@ class ServerStatisticQuery(QueryABC):
|
|||||||
|
|
||||||
def _resolve_voice_channel_ontime(self, server, *_):
|
def _resolve_voice_channel_ontime(self, server, *_):
|
||||||
query = f"""
|
query = f"""
|
||||||
SELECT ROUND(SUM(TIME_TO_SEC(TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)) / 3600),{server.server.id}) FROM UserJoinedVoiceChannel
|
SELECT IFNULL(ROUND(SUM(
|
||||||
|
TIME_TO_SEC(TIMEDIFF(UserJoinedVoiceChannel.LeavedOn, UserJoinedVoiceChannel.JoinedOn)) / 3600
|
||||||
|
), 2), 0) FROM UserJoinedVoiceChannel
|
||||||
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
|
INNER JOIN Users ON UserJoinedVoiceChannel.UserId = Users.UserId
|
||||||
WHERE Users.ServerId = {server.server.id}
|
WHERE Users.ServerId = {server.server.id}
|
||||||
AND UserJoinedVoiceChannel.CreatedAt >= "{self._get_date(**server.kwargs)}";
|
AND UserJoinedVoiceChannel.CreatedAt >= "{self._get_date(**server.kwargs)}";
|
||||||
@@ -132,7 +134,10 @@ class ServerStatisticQuery(QueryABC):
|
|||||||
|
|
||||||
def _resolve_game_server_ontime(self, server, *_):
|
def _resolve_game_server_ontime(self, server, *_):
|
||||||
query = f"""
|
query = f"""
|
||||||
SELECT ROUND(SUM(TIME_TO_SEC(TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)) / 3600),{server.server.id}) FROM UserJoinedGameServer
|
SELECT IFNULL(ROUND(SUM(
|
||||||
|
TIME_TO_SEC(TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)) / 3600
|
||||||
|
), 2), 0)
|
||||||
|
FROM UserJoinedGameServer
|
||||||
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
|
INNER JOIN Users ON UserJoinedGameServer.UserId = Users.UserId
|
||||||
WHERE Users.ServerId = {server.server.id}
|
WHERE Users.ServerId = {server.server.id}
|
||||||
AND UserJoinedGameServer.CreatedAt >= "{self._get_date(**server.kwargs)}";
|
AND UserJoinedGameServer.CreatedAt >= "{self._get_date(**server.kwargs)}";
|
||||||
|
@@ -2,6 +2,7 @@ from cpl_core.database.context import DatabaseContextABC
|
|||||||
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_core.abc.permission_service_abc import PermissionServiceABC
|
||||||
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC
|
||||||
from bot_data.abc.user_joined_game_server_repository_abc import (
|
from bot_data.abc.user_joined_game_server_repository_abc import (
|
||||||
UserJoinedGameServerRepositoryABC,
|
UserJoinedGameServerRepositoryABC,
|
||||||
@@ -11,7 +12,6 @@ from bot_data.abc.user_joined_voice_channel_repository_abc import (
|
|||||||
UserJoinedVoiceChannelRepositoryABC,
|
UserJoinedVoiceChannelRepositoryABC,
|
||||||
)
|
)
|
||||||
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
from bot_data.abc.user_warnings_repository_abc import UserWarningsRepositoryABC
|
||||||
from bot_data.model.user import User
|
|
||||||
from bot_data.model.user_history import UserHistory
|
from bot_data.model.user_history import UserHistory
|
||||||
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
|
from bot_graphql.abc.data_query_with_history_abc import DataQueryWithHistoryABC
|
||||||
from bot_graphql.filter.achievement_filter import AchievementFilter
|
from bot_graphql.filter.achievement_filter import AchievementFilter
|
||||||
@@ -22,7 +22,6 @@ from bot_graphql.filter.user_joined_voice_channel_filter import (
|
|||||||
)
|
)
|
||||||
from bot_graphql.filter.user_warning_filter import UserWarningFilter
|
from bot_graphql.filter.user_warning_filter import UserWarningFilter
|
||||||
from modules.level.service.level_service import LevelService
|
from modules.level.service.level_service import LevelService
|
||||||
from bot_core.abc.permission_service_abc import PermissionServiceABC
|
|
||||||
|
|
||||||
|
|
||||||
class UserQuery(DataQueryWithHistoryABC):
|
class UserQuery(DataQueryWithHistoryABC):
|
||||||
@@ -50,15 +49,17 @@ class UserQuery(DataQueryWithHistoryABC):
|
|||||||
self._permissions = permissions
|
self._permissions = permissions
|
||||||
self._achievements = achievements
|
self._achievements = achievements
|
||||||
|
|
||||||
self.set_field("id", self.resolve_id)
|
self.set_field("id", lambda user, *_: user.id)
|
||||||
self.set_field("discordId", self.resolve_discord_id)
|
self.set_field("discordId", lambda user, *_: user.discord_id)
|
||||||
self.set_field("name", self.resolve_name)
|
self.set_field("name", lambda user, *_: user.name)
|
||||||
self.set_field("xp", self.resolve_xp)
|
self.set_field("xp", lambda user, *_: user.xp)
|
||||||
self.set_field("messageCount", lambda x, *_: x.message_count)
|
self.set_field("messageCount", lambda x, *_: x.message_count)
|
||||||
self.set_field("reactionCount", lambda x, *_: x.reaction_count)
|
self.set_field("reactionCount", lambda x, *_: x.reaction_count)
|
||||||
self.set_field("birthday", lambda x, *_: None if x.birthday is None else x.birthday.strftime("%d.%m.%Y"))
|
self.set_field("birthday", lambda x, *_: None if x.birthday is None else x.birthday.strftime("%d.%m.%Y"))
|
||||||
self.set_field("ontime", self.resolve_ontime)
|
self.set_field("ontime", lambda user, *_: user.ontime)
|
||||||
self.set_field("level", self.resolve_level)
|
self.set_field("gameOntime", lambda user, *_: user.game_ontime)
|
||||||
|
self.set_field("level", lambda user, *_: user.level)
|
||||||
|
self.set_field("activityScore", lambda user, *_: user.activity)
|
||||||
self.add_collection(
|
self.add_collection(
|
||||||
"joinedServer",
|
"joinedServer",
|
||||||
lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.id),
|
lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.id),
|
||||||
@@ -85,37 +86,5 @@ class UserQuery(DataQueryWithHistoryABC):
|
|||||||
UserWarningFilter,
|
UserWarningFilter,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.set_field("server", self.resolve_server)
|
self.set_field("server", lambda user, *_: user.server)
|
||||||
self.set_field("leftServer", self.resolve_left_server)
|
self.set_field("leftServer", lambda user, *_: user.left_server)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_id(user: User, *_):
|
|
||||||
return user.id
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_discord_id(user: User, *_):
|
|
||||||
return user.discord_id
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_name(user: User, *_):
|
|
||||||
return user.name
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_xp(user: User, *_):
|
|
||||||
return user.xp
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_ontime(user: User, *_):
|
|
||||||
return user.ontime
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_level(user: User, *_):
|
|
||||||
return user.level
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_server(user: User, *_):
|
|
||||||
return user.server
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def resolve_left_server(user: User, *_):
|
|
||||||
return user.left_server
|
|
||||||
|
@@ -16,7 +16,9 @@ export interface User extends DataWithHistory {
|
|||||||
reactionCount?: number;
|
reactionCount?: number;
|
||||||
birthday?: string;
|
birthday?: string;
|
||||||
ontime?: number;
|
ontime?: number;
|
||||||
|
gameOntime?: number;
|
||||||
level?: Level;
|
level?: Level;
|
||||||
|
activityScore?: number;
|
||||||
server?: Server;
|
server?: Server;
|
||||||
leftServer?: boolean;
|
leftServer?: boolean;
|
||||||
|
|
||||||
|
@@ -361,6 +361,8 @@ export class Queries {
|
|||||||
name
|
name
|
||||||
xp
|
xp
|
||||||
ontime
|
ontime
|
||||||
|
gameOntime
|
||||||
|
activityScore
|
||||||
level {
|
level {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@@ -386,6 +388,8 @@ export class Queries {
|
|||||||
reactionCount
|
reactionCount
|
||||||
birthday
|
birthday
|
||||||
ontime
|
ontime
|
||||||
|
gameOntime
|
||||||
|
activityScore
|
||||||
level {
|
level {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
@@ -3,7 +3,8 @@
|
|||||||
</h1>
|
</h1>
|
||||||
<div class="content-wrapper">
|
<div class="content-wrapper">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<p-table #dt [value]="members" [responsive]="true" responsiveLayout="stack" [breakpoint]="'720px'" dataKey="id" editMode="row" [rowHover]="true" [rows]="10"
|
<p-table #dt [value]="members" [responsive]="true" responsiveLayout="stack" [breakpoint]="'720px'" dataKey="id"
|
||||||
|
editMode="row" [rowHover]="true" [rows]="10"
|
||||||
[rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords"
|
[rowsPerPageOptions]="[10,25,50]" [paginator]="true" [loading]="loading" [totalRecords]="totalRecords"
|
||||||
[lazy]="true" (onLazyLoad)="nextPage($event)">
|
[lazy]="true" (onLazyLoad)="nextPage($event)">
|
||||||
|
|
||||||
@@ -17,7 +18,8 @@
|
|||||||
{{'view.server.members.members' | translate}}
|
{{'view.server.members.members' | translate}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<app-multi-select-columns [table]="name" [columns]="columns" [(hiddenColumns)]="hiddenColumns"></app-multi-select-columns>
|
<app-multi-select-columns [table]="name" [columns]="columns"
|
||||||
|
[(hiddenColumns)]="hiddenColumns"></app-multi-select-columns>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-caption-btn-wrapper btn-wrapper">
|
<div class="table-caption-btn-wrapper btn-wrapper">
|
||||||
@@ -65,6 +67,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
|
<th hideable-th="game_ontime" [parent]="this" [sortable]="true">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.game_ontime' | translate}}</div>
|
||||||
|
<p-sortIcon field="game_ontime" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
|
<th hideable-th="activity" [parent]="this" [sortable]="true">
|
||||||
|
<div class="table-header-label">
|
||||||
|
<div class="table-header-text">{{'common.activity' | translate}}</div>
|
||||||
|
<p-sortIcon field="activityScore" class="table-header-icon"></p-sortIcon>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
|
||||||
<th hideable-th="left_server" [parent]="this" [sortable]="true">
|
<th hideable-th="left_server" [parent]="this" [sortable]="true">
|
||||||
<div class="table-header-label">
|
<div class="table-header-label">
|
||||||
<div class="table-header-text">{{'common.left_server' | translate}}</div>
|
<div class="table-header-text">{{'common.left_server' | translate}}</div>
|
||||||
@@ -106,7 +122,8 @@
|
|||||||
</th>
|
</th>
|
||||||
<th hideable-th="discord_id" [parent]="this" class="table-header-medium">
|
<th hideable-th="discord_id" [parent]="this" class="table-header-medium">
|
||||||
<form [formGroup]="filterForm">
|
<form [formGroup]="filterForm">
|
||||||
<input type="text" pInputText formControlName="discordId" placeholder="{{'common.discord_id' | translate}}">
|
<input type="text" pInputText formControlName="discordId"
|
||||||
|
placeholder="{{'common.discord_id' | translate}}">
|
||||||
</form>
|
</form>
|
||||||
</th>
|
</th>
|
||||||
<th hideable-th="name" [parent]="this">
|
<th hideable-th="name" [parent]="this">
|
||||||
@@ -116,14 +133,18 @@
|
|||||||
</th>
|
</th>
|
||||||
<th hideable-th="xp" [parent]="this"></th>
|
<th hideable-th="xp" [parent]="this"></th>
|
||||||
<th hideable-th="ontime" [parent]="this"></th>
|
<th hideable-th="ontime" [parent]="this"></th>
|
||||||
|
<th hideable-th="game_ontime" [parent]="this"></th>
|
||||||
|
<th hideable-th="activity" [parent]="this"></th>
|
||||||
<th hideable-th="left_server" [parent]="this" class="table-header-small-dropdown">
|
<th hideable-th="left_server" [parent]="this" class="table-header-small-dropdown">
|
||||||
<form [formGroup]="filterForm">
|
<form [formGroup]="filterForm">
|
||||||
<p-dropdown formControlName="leftServer" [options]="leftServerOptions" placeholder="{{'common.left_server' | translate}}"></p-dropdown>
|
<p-dropdown formControlName="leftServer" [options]="leftServerOptions"
|
||||||
|
placeholder="{{'common.left_server' | translate}}"></p-dropdown>
|
||||||
</form>
|
</form>
|
||||||
</th>
|
</th>
|
||||||
<th hideable-th="level" [parent]="this" class="table-header-small-dropdown">
|
<th hideable-th="level" [parent]="this" class="table-header-small-dropdown">
|
||||||
<form [formGroup]="filterForm">
|
<form [formGroup]="filterForm">
|
||||||
<p-dropdown formControlName="level" [options]="levels" placeholder="{{'common.level' | translate}}"></p-dropdown>
|
<p-dropdown formControlName="level" [options]="levels"
|
||||||
|
placeholder="{{'common.level' | translate}}"></p-dropdown>
|
||||||
</form>
|
</form>
|
||||||
</th>
|
</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
@@ -189,6 +210,28 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</p-cellEditor>
|
</p-cellEditor>
|
||||||
</td>
|
</td>
|
||||||
|
<td hideable-th="game_ontime" [parent]="this">
|
||||||
|
<span class="p-column-title">{{'common.game_ontime' | translate}}:</span>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.gameOntime}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.gameOntime}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
|
<td hideable-th="activity" [parent]="this">
|
||||||
|
<span class="p-column-title">{{'common.activity' | translate}}:</span>
|
||||||
|
<p-cellEditor>
|
||||||
|
<ng-template pTemplate="input">
|
||||||
|
{{member.activityScore}}
|
||||||
|
</ng-template>
|
||||||
|
<ng-template pTemplate="output">
|
||||||
|
{{member.activityScore}}
|
||||||
|
</ng-template>
|
||||||
|
</p-cellEditor>
|
||||||
|
</td>
|
||||||
<td hideable-th="left_server" [parent]="this">
|
<td hideable-th="left_server" [parent]="this">
|
||||||
<span class="p-column-title">{{'common.left_server' | translate}}:</span>
|
<span class="p-column-title">{{'common.left_server' | translate}}:</span>
|
||||||
<p-cellEditor>
|
<p-cellEditor>
|
||||||
@@ -204,7 +247,8 @@
|
|||||||
<span class="p-column-title">{{'common.level' | translate}}:</span>
|
<span class="p-column-title">{{'common.level' | translate}}:</span>
|
||||||
<p-cellEditor>
|
<p-cellEditor>
|
||||||
<ng-template pTemplate="input">
|
<ng-template pTemplate="input">
|
||||||
<p-dropdown [options]="levels" [(ngModel)]="member.level" dataKey="id" placeholder="{{'common.level' | translate}}"></p-dropdown>
|
<p-dropdown [options]="levels" [(ngModel)]="member.level" dataKey="id"
|
||||||
|
placeholder="{{'common.level' | translate}}"></p-dropdown>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template pTemplate="output">
|
<ng-template pTemplate="output">
|
||||||
{{member.level.name}}
|
{{member.level.name}}
|
||||||
@@ -235,7 +279,8 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-wrapper">
|
<div class="btn-wrapper">
|
||||||
<app-history-btn *ngIf="!isEditingNew" [id]="member.id" [query]="query" translationKey="view.server.members.header"></app-history-btn>
|
<app-history-btn *ngIf="!isEditingNew" [id]="member.id" [query]="query"
|
||||||
|
translationKey="view.server.members.header"></app-history-btn>
|
||||||
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
|
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-pencil"
|
||||||
(click)="onRowEditInit(dt, member, ri)"></button>
|
(click)="onRowEditInit(dt, member, ri)"></button>
|
||||||
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user"
|
<button *ngIf="!editing" pButton pInitEditableRow class="btn icon-btn" icon="pi pi-user"
|
||||||
|
@@ -89,7 +89,7 @@ export class MembersComponent extends ComponentWithTable implements OnInit, OnDe
|
|||||||
private data: DataService,
|
private data: DataService,
|
||||||
private route: ActivatedRoute
|
private route: ActivatedRoute
|
||||||
) {
|
) {
|
||||||
super("member", ["id", "discord_id", "name", "xp", "ontime", "left_server", "level"]);
|
super("member", ["id", "discord_id", "name", "xp", "ontime", "game_ontime", "activity", "left_server", "level"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@@ -63,11 +63,25 @@
|
|||||||
|
|
||||||
<div class="content-row">
|
<div class="content-row">
|
||||||
<div class="content-column">
|
<div class="content-column">
|
||||||
<div class="content-data-name">{{'view.server.profile.ontime' | translate}}:</div>
|
<div class="content-data-name">{{'common.ontime' | translate}}:</div>
|
||||||
<div class="content-data-value">{{user.ontime}}</div>
|
<div class="content-data-value">{{user.ontime}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="content-row">
|
||||||
|
<div class="content-column">
|
||||||
|
<div class="content-data-name">{{'common.game_ontime' | translate}}:</div>
|
||||||
|
<div class="content-data-value">{{user.gameOntime}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-row">
|
||||||
|
<div class="content-column">
|
||||||
|
<div class="content-data-name">{{'common.activity' | translate}}:</div>
|
||||||
|
<div class="content-data-value">{{user.activityScore}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="content-row">
|
<div class="content-row">
|
||||||
<div class="content-column">
|
<div class="content-column">
|
||||||
<div class="content-data-name">{{'view.server.profile.level' | translate}}:</div>
|
<div class="content-data-name">{{'view.server.profile.level' | translate}}:</div>
|
||||||
@@ -266,7 +280,7 @@
|
|||||||
<div class="content-data-name">{{'common.id' | translate}}:</div>
|
<div class="content-data-name">{{'common.id' | translate}}:</div>
|
||||||
<div class="content-data-value">{{join.id}}</div>
|
<div class="content-data-value">{{join.id}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content-column" style="flex: 0.75;">
|
<div class="content-column" style="flex: 0.75;">
|
||||||
<div class="content-data-name"
|
<div class="content-data-name"
|
||||||
style="flex: 0.35;">{{'view.server.profile.joined_game_server.time' | translate}}:
|
style="flex: 0.35;">{{'view.server.profile.joined_game_server.time' | translate}}:
|
||||||
|
@@ -127,6 +127,7 @@
|
|||||||
"abort": "Abbrechen",
|
"abort": "Abbrechen",
|
||||||
"actions": "Aktionen",
|
"actions": "Aktionen",
|
||||||
"active": "Aktiv",
|
"active": "Aktiv",
|
||||||
|
"activity": "Aktivität",
|
||||||
"add": "Hinzufügen",
|
"add": "Hinzufügen",
|
||||||
"attribute": "Attribut",
|
"attribute": "Attribut",
|
||||||
"auth_role": "Rolle",
|
"auth_role": "Rolle",
|
||||||
@@ -154,6 +155,7 @@
|
|||||||
"uploaded": "Daten wurden erfolgreich importiert."
|
"uploaded": "Daten wurden erfolgreich importiert."
|
||||||
},
|
},
|
||||||
"first_name": "Vorname",
|
"first_name": "Vorname",
|
||||||
|
"game_ontime": "Spiel Ontime",
|
||||||
"hidden_columns": "Ausgeblendete Spalten",
|
"hidden_columns": "Ausgeblendete Spalten",
|
||||||
"history": {
|
"history": {
|
||||||
"attribute": "Attribut",
|
"attribute": "Attribut",
|
||||||
@@ -542,7 +544,6 @@
|
|||||||
"message_count": "Anzahl Nachrichten",
|
"message_count": "Anzahl Nachrichten",
|
||||||
"minecraft_id": "Minecraft Id",
|
"minecraft_id": "Minecraft Id",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ontime": "Ontime",
|
|
||||||
"permission_denied": "Zugriff verweigert!",
|
"permission_denied": "Zugriff verweigert!",
|
||||||
"permission_denied_d": "Du musst Moderator sein, um andere Profile sehen zu können!",
|
"permission_denied_d": "Du musst Moderator sein, um andere Profile sehen zu können!",
|
||||||
"reaction_count": "Anzahl Reaktionen",
|
"reaction_count": "Anzahl Reaktionen",
|
||||||
|
@@ -127,6 +127,7 @@
|
|||||||
"abort": "Abort",
|
"abort": "Abort",
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"active": "Active",
|
"active": "Active",
|
||||||
|
"activity": "Activity",
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
"attribute": "Attribute",
|
"attribute": "Attribute",
|
||||||
"auth_role": "Role",
|
"auth_role": "Role",
|
||||||
@@ -154,6 +155,7 @@
|
|||||||
"uploaded": "Data was imported successfully."
|
"uploaded": "Data was imported successfully."
|
||||||
},
|
},
|
||||||
"first_name": "First name",
|
"first_name": "First name",
|
||||||
|
"game_ontime": "Game ontime",
|
||||||
"hidden_columns": "Hidden columns",
|
"hidden_columns": "Hidden columns",
|
||||||
"history": {
|
"history": {
|
||||||
"attribute": "Attribute",
|
"attribute": "Attribute",
|
||||||
@@ -542,7 +544,6 @@
|
|||||||
"message_count": "Message count",
|
"message_count": "Message count",
|
||||||
"minecraft_id": "Minecraft Id",
|
"minecraft_id": "Minecraft Id",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"ontime": "Ontime",
|
|
||||||
"permission_denied": "Access denied!",
|
"permission_denied": "Access denied!",
|
||||||
"permission_denied_d": "You have to be moderator to see other profiles!",
|
"permission_denied_d": "You have to be moderator to see other profiles!",
|
||||||
"reaction_count": "Reaction count",
|
"reaction_count": "Reaction count",
|
||||||
|
Reference in New Issue
Block a user