Skip to content

Commit 980bbad

Browse files
authored
Some admin extensions (#356)
* Adds exec for timed executions & alembic * Alembic revision * Adds endpoint changes * Removes oidc identifier * Submodule merge
1 parent 431bd73 commit 980bbad

File tree

6 files changed

+79
-22
lines changed

6 files changed

+79
-22
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""new org column
2+
3+
Revision ID: 199a0d8aefbe
4+
Revises: c6d1cbcccb41
5+
Create Date: 2025-10-20 07:36:33.488523
6+
7+
"""
8+
9+
from alembic import op
10+
import sqlalchemy as sa
11+
12+
13+
# revision identifiers, used by Alembic.
14+
revision = "199a0d8aefbe"
15+
down_revision = "c6d1cbcccb41"
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
op.add_column(
23+
"user", sa.Column("messages_created_this_month", sa.BigInteger(), nullable=True)
24+
)
25+
26+
op.create_table(
27+
"timed_executions",
28+
sa.Column("time_key", sa.String(), nullable=False),
29+
sa.Column("last_executed_at", sa.DateTime(), nullable=True),
30+
sa.PrimaryKeyConstraint("time_key"),
31+
sa.UniqueConstraint("time_key"),
32+
schema="global",
33+
)
34+
connection = op.get_bind()
35+
36+
update_dataset_sql = """
37+
UPDATE public.user
38+
SET messages_created_this_month = 0
39+
WHERE messages_created_this_month IS NULL
40+
"""
41+
connection.execute(update_dataset_sql)
42+
op.drop_column("user", "oidc_identifier")
43+
op.create_unique_constraint(None, "timed_executions", ["time_key"], schema="global")
44+
# ### end Alembic commands ###
45+
46+
47+
def downgrade():
48+
# ### commands auto generated by Alembic - please adjust! ###
49+
op.drop_column("user", "messages_created_this_month")
50+
op.drop_table("timed_executions", schema="global")
51+
op.drop_constraint(None, "timed_executions", schema="global", type_="unique")
52+
op.add_column(
53+
"user",
54+
sa.Column("oidc_identifier", sa.VARCHAR(), autoincrement=False, nullable=True),
55+
)
56+
# ### end Alembic commands ###

app.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,4 @@
185185
session.start_session_cleanup_thread()
186186
log_storage.start_persist_thread()
187187
sums_table_manager.start_sums_table_thread()
188+
clean_up.start_timed_executions_thread()

controller/user/manager.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Dict, Optional, Any
1+
from typing import Dict, List, Optional, Any
22
from submodules.model import User, daemon, enums
33
from submodules.model.business_objects import user, general
44
from controller.auth import kratos
@@ -118,7 +118,7 @@ def get_active_users_filtered(
118118
sort_direction: Optional[str] = None,
119119
offset: Optional[int] = None,
120120
limit: Optional[int] = None,
121-
) -> User:
121+
) -> List[User]:
122122
now = datetime.now()
123123
last_interaction_range = (now - timedelta(minutes=minutes)) if minutes > 0 else None
124124
return user.get_active_users_after_filter(
@@ -180,22 +180,4 @@ def __migrate_kratos_users():
180180
if user_database.sso_provider != sso_provider:
181181
user_database.sso_provider = sso_provider
182182

183-
if user_database.oidc_identifier is None:
184-
user_search = kratos.__search_kratos_for_user_mail(
185-
user_identity["traits"]["email"]
186-
)
187-
if user_search and user_search["credentials"]:
188-
if user_search["credentials"].get("oidc", None):
189-
oidc = (
190-
user_search["credentials"]
191-
.get("oidc", {})
192-
.get("identifiers", None)[0]
193-
)
194-
if oidc:
195-
oidc = oidc.split(":")
196-
if len(oidc) > 1:
197-
user_database.oidc_identifier = oidc[1]
198-
else:
199-
user_database.oidc_identifier = None
200-
201183
general.commit()

fast_api/routes/organization.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ def get_mapped_sorted_paginated_users(
280280
"created_at": user.created_at.isoformat() if user.created_at else None,
281281
"metadata_public": user.metadata_public,
282282
"sso_provider": user.sso_provider,
283+
"messages_created_this_month": user.messages_created_this_month,
283284
}
284285
for user in active_users
285286
]
@@ -302,7 +303,7 @@ def delete_user(request: Request, body: DeleteUserBody = Body(...)):
302303

303304

304305
# in use admin-dashboard (08.01.25)
305-
@router.post("/missing-users-interaction")
306+
@router.post("/missing-users-interaction-and-message-count")
306307
def get_missing_users_interaction(request: Request, body: MissingUsersBody = Body(...)):
307308
auth_manager.check_admin_access(request.state.info)
308309
data = user.get_missing_users(body.user_ids)

util/clean_up.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from submodules.model.business_objects import upload_task
22
import os
33
import shutil
4+
from submodules.model.daemon import run_without_db_token
5+
from time import sleep
6+
from submodules.model.global_objects import timed_executions
47

58

69
def clean_up_database() -> None:
@@ -21,3 +24,17 @@ def clean_up_disk() -> None:
2124
shutil.rmtree(file_path)
2225
except Exception as e:
2326
print("Failed to delete %s. Reason: %s" % (file_path, e))
27+
28+
29+
def start_timed_executions_thread() -> None:
30+
run_without_db_token(__run_timed_executions)
31+
32+
33+
def __run_timed_executions() -> None:
34+
sleep(10) # wait a bit until app is started
35+
while True:
36+
try:
37+
timed_executions.execute_time_key_update(with_commit=True)
38+
except Exception as e:
39+
print(f"Error during timed executions: {e}")
40+
sleep(3600) # run every hour

0 commit comments

Comments
 (0)