Added user activity score
Some checks reported warnings
Deploy dev on push / on-push-deploy_sh-edraft (push) Has been cancelled

This commit is contained in:
Sven Heidemann 2023-12-04 22:48:05 +01:00
parent 9976c59302
commit 0e3286f3f4
14 changed files with 161 additions and 10 deletions

View File

@ -31,6 +31,10 @@ class UserRepositoryABC(ABC):
def get_users_by_server_id(self, server_id: int) -> List[User]:
pass
@abstractmethod
def get_users_with_activity_by_server_id(self, server_id: int) -> List[User]:
pass
@abstractmethod
def get_user_by_discord_id_and_server_id(self, discord_id: int, server_id: int) -> User:
pass

View File

@ -32,6 +32,8 @@ class User(TableABC):
self._birthday = birthday
self._server = server
self._activity = 0
TableABC.__init__(self)
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
@ -120,6 +122,14 @@ class User(TableABC):
return 0
return float(result)
@property
def activity(self) -> int:
return self._activity
@activity.setter
def activity(self, value: int):
self._activity = value
@property
@ServiceProviderABC.inject
def level(self, services: ServiceProviderABC) -> Level:

View File

@ -1,6 +1,8 @@
import datetime
from typing import Optional
from cpl_core.database.context import DatabaseContextABC
from cpl_core.type import T, R
from cpl_query.extension import List
from bot_core.logging.database_logger import DatabaseLogger
@ -38,7 +40,9 @@ class UserRepositoryService(UserRepositoryABC):
def get_users(self) -> List[User]:
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:
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))],
)
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:
self._logger.trace(
__name__,
@ -109,3 +123,91 @@ class UserRepositoryService(UserRepositoryABC):
def delete_user(self, user: User):
self._logger.trace(__name__, f"Send SQL command: {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

View File

@ -64,11 +64,9 @@ class QueryABC(ObjectType):
if user == "system" or user.auth_role == AuthRoleEnum.admin:
return self._resolve_collection(collection, *args, **kwargs)
for x in collection.to_list():
if not self._can_user_see_element(user, x):
collection.remove(x)
return self._resolve_collection(collection, *args, **kwargs)
return self._resolve_collection(
collection.where(lambda x: self._can_user_see_element(user, x)), *args, **kwargs
)
self.set_field(f"{name}s", wrapper)
self.set_field(f"{name}Count", lambda *args: wrapper(*args).count())

View File

@ -9,6 +9,7 @@ type User implements TableWithHistoryQuery {
ontime: Float
gameOntime: Float
level: Level
activityScore: Int
joinedServers(filter: UserJoinedServerFilter, page: Page, sort: Sort): [UserJoinedServer]
joinedServerCount: Int

View File

@ -86,7 +86,7 @@ class ServerQuery(DataQueryWithHistoryABC):
)
self.add_collection(
"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,
)
self.add_collection(

View File

@ -114,7 +114,9 @@ class ServerStatisticQuery(QueryABC):
def _resolve_voice_channel_ontime(self, server, *_):
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
WHERE Users.ServerId = {server.server.id}
AND UserJoinedVoiceChannel.CreatedAt >= "{self._get_date(**server.kwargs)}";
@ -132,7 +134,10 @@ class ServerStatisticQuery(QueryABC):
def _resolve_game_server_ontime(self, server, *_):
query = f"""
SELECT ROUND(SUM(TIME_TO_SEC(TIMEDIFF(UserJoinedGameServer.LeavedOn, UserJoinedGameServer.JoinedOn)) / 3600),2) 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
WHERE Users.ServerId = {server.server.id}
AND UserJoinedGameServer.CreatedAt >= "{self._get_date(**server.kwargs)}";

View File

@ -59,6 +59,7 @@ class UserQuery(DataQueryWithHistoryABC):
self.set_field("ontime", lambda user, *_: user.ontime)
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(
"joinedServer",
lambda user, *_: self._ujs.get_user_joined_servers_by_user_id(user.id),

View File

@ -362,6 +362,7 @@ export class Queries {
xp
ontime
gameOntime
activityScore
level {
id
name
@ -388,6 +389,7 @@ export class Queries {
birthday
ontime
gameOntime
activityScore
level {
id
name

View File

@ -74,6 +74,13 @@
</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">
<div class="table-header-label">
<div class="table-header-text">{{'common.left_server' | translate}}</div>
@ -127,6 +134,7 @@
<th hideable-th="xp" [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">
<form [formGroup]="filterForm">
<p-dropdown formControlName="leftServer" [options]="leftServerOptions"
@ -213,6 +221,17 @@
</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">
<span class="p-column-title">{{'common.left_server' | translate}}:</span>
<p-cellEditor>

View File

@ -89,7 +89,7 @@ export class MembersComponent extends ComponentWithTable implements OnInit, OnDe
private data: DataService,
private route: ActivatedRoute
) {
super("member", ["id", "discord_id", "name", "xp", "ontime", "game_ontime", "left_server", "level"]);
super("member", ["id", "discord_id", "name", "xp", "ontime", "game_ontime", "activity", "left_server", "level"]);
}
ngOnInit(): void {

View File

@ -75,6 +75,13 @@
</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-column">
<div class="content-data-name">{{'view.server.profile.level' | translate}}:</div>

View File

@ -127,6 +127,7 @@
"abort": "Abbrechen",
"actions": "Aktionen",
"active": "Aktiv",
"activity": "Aktivität",
"add": "Hinzufügen",
"attribute": "Attribut",
"auth_role": "Rolle",

View File

@ -127,6 +127,7 @@
"abort": "Abort",
"actions": "Actions",
"active": "Active",
"activity": "Activity",
"add": "Add",
"attribute": "Attribute",
"auth_role": "Role",