arpakitlib 1.8.85__py3-none-any.whl → 1.8.88__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. arpakitlib/_arpakit_project_template_v_5/arpakitlib_project_template_info.json +1 -1
  2. arpakitlib/_arpakit_project_template_v_5/command/show_arpakitlib_project_template_info.py +9 -0
  3. arpakitlib/_arpakit_project_template_v_5/project/api/router/general/healthcheck.py +2 -2
  4. arpakitlib/_arpakit_project_template_v_5/project/core/settings.py +2 -0
  5. arpakitlib/_arpakit_project_template_v_5/project/sandbox/sandbox_1.py +0 -5
  6. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user.py +14 -5
  7. arpakitlib/_arpakit_project_template_v_5/project/sqladmin_/model_view/user_token.py +10 -1
  8. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/blank/admin.py +7 -7
  9. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/blank/client.py +18 -20
  10. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/callback/admin.py +5 -0
  11. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/callback/client.py +1 -5
  12. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/const.py +5 -3
  13. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/event.py +12 -1
  14. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/filter_/user_roles_has_admin.py +2 -2
  15. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/filter_/user_roles_has_client.py +2 -2
  16. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/inline_/admin/hello_world.py +16 -0
  17. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/inline_/client/support.py +15 -0
  18. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/static_/{client → admin}/hello_world.py +3 -3
  19. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/middleware/common.py +2 -2
  20. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/middleware/init_user.py +14 -14
  21. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/arpakitlib_project_template_info.py +3 -0
  22. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/clear_log_file.py +9 -3
  23. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/current_state.py +31 -0
  24. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/drop_sqlalchemy_db.py +5 -2
  25. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/hello_world.py +73 -0
  26. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/init_sqlalchemy_db.py +5 -2
  27. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/kb_with_not_modified.py +10 -3
  28. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/kb_with_old_cd.py +3 -2
  29. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/kb_with_raise_error.py +6 -2
  30. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/kb_with_remove_message.py +7 -4
  31. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/log_file.py +6 -1
  32. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/me.py +7 -2
  33. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/raise_fake_error.py +4 -2
  34. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/reinit_sqlalchemy_db.py +5 -2
  35. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/admin/set_tg_bot_commands.py +5 -2
  36. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/about.py +8 -5
  37. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/author.py +8 -5
  38. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general/support.py → client/cancel.py} +9 -6
  39. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/error_handler.py +7 -3
  40. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/client/healthcheck.py +21 -0
  41. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/raw_callback_query.py +4 -2
  42. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/raw_inline_query.py +2 -0
  43. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/raw_message.py +5 -2
  44. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/remove_message.py +4 -2
  45. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/start.py +8 -5
  46. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/client/support.py +37 -0
  47. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/main_router.py +16 -12
  48. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/state/__init__.py +0 -0
  49. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/state/admin.py +0 -0
  50. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/state/client.py +5 -0
  51. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/state/common.py +0 -0
  52. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/state/util.py +0 -0
  53. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/tg_bot_dispatcher.py +1 -1
  54. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/notify_admins.py +6 -3
  55. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/util/set_tg_bot_commands.py +14 -15
  56. arpakitlib/_arpakit_project_template_v_5/project/util/etc.py +0 -0
  57. arpakitlib/ar_blank_util.py +59 -2
  58. arpakitlib/ar_json_util.py +1 -1
  59. {arpakitlib-1.8.85.dist-info → arpakitlib-1.8.88.dist-info}/METADATA +1 -1
  60. {arpakitlib-1.8.85.dist-info → arpakitlib-1.8.88.dist-info}/RECORD +65 -55
  61. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/kb/inline_/client/hello_world.py +0 -16
  62. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/healthcheck.py +0 -18
  63. arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/general/hello_world.py +0 -47
  64. /arpakitlib/_arpakit_project_template_v_5/project/tg_bot/middleware/{middleware.py → uil.py} +0 -0
  65. /arpakitlib/_arpakit_project_template_v_5/project/tg_bot/router/{general → client}/__init__.py +0 -0
  66. {arpakitlib-1.8.85.dist-info → arpakitlib-1.8.88.dist-info}/LICENSE +0 -0
  67. {arpakitlib-1.8.85.dist-info → arpakitlib-1.8.88.dist-info}/WHEEL +0 -0
  68. {arpakitlib-1.8.85.dist-info → arpakitlib-1.8.88.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "arpakitlib_project_template_version": "5",
3
- "arpakitlib_project_template_subversion": "19"
3
+ "arpakitlib_project_template_subversion": "20"
4
4
  }
@@ -0,0 +1,9 @@
1
+ from project.util.arpakitlib_project_template import get_arpakitlib_project_template_info
2
+
3
+
4
+ def __command():
5
+ print(get_arpakitlib_project_template_info())
6
+
7
+
8
+ if __name__ == '__main__':
9
+ __command()
@@ -3,9 +3,9 @@ import datetime as dt
3
3
  import fastapi
4
4
  from fastapi import APIRouter
5
5
 
6
+ from arpakitlib.ar_datetime_util import now_utc_dt
6
7
  from project.api.schema.common import BaseSO
7
8
  from project.api.schema.out.common.error import ErrorCommonSO
8
- from project.core.util import now_local_dt
9
9
 
10
10
 
11
11
  class _HealthcheckGeneralRouteSO(BaseSO):
@@ -27,4 +27,4 @@ async def _(
27
27
  request: fastapi.requests.Request,
28
28
  response: fastapi.responses.Response
29
29
  ):
30
- return _HealthcheckGeneralRouteSO(is_ok=True, datetime=now_local_dt())
30
+ return _HealthcheckGeneralRouteSO(is_ok=True, datetime=now_utc_dt())
@@ -152,6 +152,8 @@ class Settings(SimpleSettings):
152
152
 
153
153
  tg_bot_admin_tg_ids: list[int] = [269870432]
154
154
 
155
+ tg_bot_set_commands: bool = True
156
+
155
157
  var_dirpath: str | None = os.path.join(ProjectPaths.base_dirpath, "var")
156
158
 
157
159
  log_filepath: str | None = os.path.join(var_dirpath, "story.log")
@@ -1,10 +1,5 @@
1
1
  import asyncio
2
2
 
3
- from pydantic import BaseModel
4
-
5
- from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
6
- from project.sqlalchemy_db_.sqlalchemy_model import ApiKeyDBM
7
-
8
3
 
9
4
  def __sandbox():
10
5
  pass
@@ -7,7 +7,18 @@ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
7
7
  class UserMV(SimpleMV, model=UserDBM):
8
8
  name = "User"
9
9
  name_plural = "Users"
10
- column_list = sqlalchemy.inspect(UserDBM).columns
10
+ column_list = [
11
+ UserDBM.id,
12
+ UserDBM.long_id,
13
+ UserDBM.slug,
14
+ UserDBM.creation_dt,
15
+ UserDBM.email,
16
+ UserDBM.username,
17
+ UserDBM.roles,
18
+ UserDBM.is_active,
19
+ UserDBM.password,
20
+ UserDBM.extra_data
21
+ ]
11
22
  form_columns = [
12
23
  UserDBM.slug,
13
24
  UserDBM.email,
@@ -15,9 +26,6 @@ class UserMV(SimpleMV, model=UserDBM):
15
26
  UserDBM.roles,
16
27
  UserDBM.is_active,
17
28
  UserDBM.password,
18
- UserDBM.tg_id,
19
- UserDBM.tg_bot_last_action_dt,
20
- UserDBM.tg_data,
21
29
  UserDBM.extra_data
22
30
  ]
23
31
  column_sortable_list = sqlalchemy.inspect(UserDBM).columns
@@ -28,6 +36,7 @@ class UserMV(SimpleMV, model=UserDBM):
28
36
  UserDBM.id,
29
37
  UserDBM.long_id,
30
38
  UserDBM.slug,
31
- UserDBM.tg_id,
39
+ UserDBM.email,
40
+ UserDBM.username,
32
41
  UserDBM.password
33
42
  ]
@@ -7,7 +7,16 @@ from project.sqlalchemy_db_.sqlalchemy_model import UserTokenDBM
7
7
  class UserTokenMV(SimpleMV, model=UserTokenDBM):
8
8
  name = "UserToken"
9
9
  name_plural = "UserTokens"
10
- column_list = sqlalchemy.inspect(UserTokenDBM).columns
10
+ column_list = [
11
+ UserTokenDBM.id,
12
+ UserTokenDBM.long_id,
13
+ UserTokenDBM.slug,
14
+ UserTokenDBM.creation_dt,
15
+ UserTokenDBM.value,
16
+ UserTokenDBM.user,
17
+ UserTokenDBM.is_active,
18
+ UserTokenDBM.extra_data,
19
+ ]
11
20
  form_columns = [
12
21
  UserTokenDBM.slug,
13
22
  UserTokenDBM.creation_dt,
@@ -8,8 +8,12 @@ from project.tg_bot.blank.common import SimpleBlankTgBot
8
8
 
9
9
 
10
10
  class AdminTgBotBlank(SimpleBlankTgBot):
11
+ def but_hello_world(self) -> str:
12
+ res = "hello_world"
13
+ return emojize(res.strip())
14
+
11
15
  def good(self) -> str:
12
- res = "good"
16
+ res = "Good"
13
17
  return emojize(res.strip())
14
18
 
15
19
  def user_dbm(self, *, user_dbm: UserDBM | None) -> str:
@@ -18,13 +22,9 @@ class AdminTgBotBlank(SimpleBlankTgBot):
18
22
  return transfer_data_to_json_str(user_dbm.simple_dict(), beautify=True)
19
23
 
20
24
 
21
- def create_admin_tg_bot_blank() -> AdminTgBotBlank:
22
- return AdminTgBotBlank()
23
-
24
-
25
25
  @lru_cache()
26
- def get_cached_admin_tg_bot_blank() -> AdminTgBotBlank:
27
- return AdminTgBotBlank()
26
+ def get_cached_eng_admin_tg_bot_blank() -> AdminTgBotBlank:
27
+ return AdminTgBotBlank(lang=AdminTgBotBlank.Languages.rus)
28
28
 
29
29
 
30
30
  def __example():
@@ -3,30 +3,27 @@ from functools import lru_cache
3
3
  from emoji import emojize
4
4
 
5
5
  from project.tg_bot.blank.common import SimpleBlankTgBot
6
- from project.tg_bot.const import GeneralTgBotCommands
6
+ from project.tg_bot.const import ClientTgBotCommands
7
7
 
8
8
 
9
9
  class ClientTgBotBlank(SimpleBlankTgBot):
10
10
  def command_to_desc(self) -> dict[str, str]:
11
11
  return {
12
- GeneralTgBotCommands.start: emojize(":waving_hand: Начать"),
13
- GeneralTgBotCommands.about: emojize(":information: О проекте"),
14
- GeneralTgBotCommands.author: emojize(":bust_in_silhouette: Авторы"),
15
- GeneralTgBotCommands.support: emojize(":red_heart: Поддержка"),
12
+ ClientTgBotCommands.start: emojize(":waving_hand: Начать"),
13
+ ClientTgBotCommands.about: emojize(":information: О проекте"),
14
+ ClientTgBotCommands.author: emojize(":bust_in_silhouette: Авторы"),
15
+ ClientTgBotCommands.support: emojize(":red_heart: Поддержка"),
16
+ ClientTgBotCommands.cancel: emojize(":right_arrow_curving_left: Отмена"),
16
17
  }
17
18
 
18
- def but_hello_world(self) -> str:
19
- res = "hello_world"
19
+ def but_support(self) -> str:
20
+ res = ":red_heart: Поддержка"
20
21
  return emojize(res.strip())
21
22
 
22
23
  def error(self) -> str:
23
- res = ":warning: <b>Произошла неполадка</b> :warning:"
24
- res += "\n\n:wrench: Мы уже работаем над исправлением"
25
- res += "\n\n:red_heart: Просим прощения :red_heart:"
26
- return emojize(res.strip())
27
-
28
- def hello_world(self) -> str:
29
- res = ":waving_hand: <b>Hello world</b> :waving_hand:"
24
+ res = ":warning: <b>Упс! Что-то пошло не так...</b> :warning:"
25
+ res += "\n\n:wrench: Мы уже работаем над решением проблемы"
26
+ res += "\n\n:red_heart: Приносим извинения за неудобства :red_heart:"
30
27
  return emojize(res.strip())
31
28
 
32
29
  def healthcheck(self) -> str:
@@ -54,24 +51,25 @@ class ClientTgBotBlank(SimpleBlankTgBot):
54
51
 
55
52
  def support(self) -> str:
56
53
  res = ":red_heart: <b>Поддержка</b> :red_heart:"
54
+ res += f"\n\n:link: https://t.me/arpakit"
57
55
  return emojize(res.strip())
58
56
 
59
57
  def keyboard_is_old(self) -> str:
60
58
  res = ":information: Эта клавиатура устарела :information:"
61
59
  return emojize(res.strip())
62
60
 
63
-
64
- def create_client_tg_bot_blank() -> ClientTgBotBlank:
65
- return ClientTgBotBlank()
61
+ def cancel(self) -> str:
62
+ res = ":right_arrow_curving_left: <b>Отмена</b>"
63
+ return emojize(res.strip())
66
64
 
67
65
 
68
66
  @lru_cache()
69
- def get_cached_client_tg_bot_blank() -> ClientTgBotBlank:
70
- return ClientTgBotBlank()
67
+ def get_cached_rus_client_tg_bot_blank() -> ClientTgBotBlank:
68
+ return ClientTgBotBlank(lang=ClientTgBotBlank.Languages.rus)
71
69
 
72
70
 
73
71
  def __example():
74
- print(get_cached_client_tg_bot_blank().author())
72
+ print(get_cached_rus_client_tg_bot_blank().author())
75
73
 
76
74
 
77
75
  if __name__ == '__main__':
@@ -0,0 +1,5 @@
1
+ from project.tg_bot.callback.common import BaseCD
2
+
3
+
4
+ class HelloWorldAdminCD(BaseCD):
5
+ hello_world: bool = True
@@ -1,9 +1,5 @@
1
1
  from project.tg_bot.callback.common import BaseCD
2
2
 
3
3
 
4
- class HelloWorldClientCD(BaseCD):
5
- hello_world: bool = True
6
-
7
-
8
- class RemoveMessageCD(BaseCD):
4
+ class RemoveMessageClientCD(BaseCD):
9
5
  pass
@@ -1,13 +1,13 @@
1
1
  from arpakitlib.ar_enumeration_util import Enumeration
2
2
 
3
3
 
4
- class GeneralTgBotCommands(Enumeration):
4
+ class ClientTgBotCommands(Enumeration):
5
5
  start = "start"
6
6
  about = "about"
7
7
  author = "author"
8
8
  support = "support"
9
9
  healthcheck = "healthcheck"
10
- hello_world = "hello_world"
10
+ cancel = "cancel"
11
11
 
12
12
 
13
13
  class AdminTgBotCommands(Enumeration):
@@ -24,11 +24,13 @@ class AdminTgBotCommands(Enumeration):
24
24
  kb_with_not_modified = "kb_with_not_modified"
25
25
  kb_with_raise_error = "kb_with_raise_error"
26
26
  kb_with_remove_message = "kb_with_remove_message"
27
+ current_state = "current_state"
28
+ hello_world = "hello_world"
27
29
 
28
30
 
29
31
  def __example():
30
32
  print("ClientCommandsTgBot:")
31
- for v in GeneralTgBotCommands.values_list():
33
+ for v in ClientTgBotCommands.values_list():
32
34
  print(f"- {v}")
33
35
  print()
34
36
  print("AdminCommandsTgBot:")
@@ -1,9 +1,11 @@
1
+ import asyncio
1
2
  import logging
2
3
  from typing import Callable
3
4
 
4
5
  from aiogram import Dispatcher
5
6
 
6
7
  from arpakitlib.ar_base_worker_util import safe_run_worker_in_background, SafeRunInBackgroundModes
8
+ from arpakitlib.ar_datetime_util import now_utc_dt
7
9
  from project.core.cache_file_storage_in_dir import get_cached_cache_file_storage_in_dir
8
10
  from project.core.dump_file_storage_in_dir import get_cached_dump_file_storage_in_dir
9
11
  from project.core.media_file_storage_in_dir import get_cached_media_file_storage_in_dir
@@ -13,6 +15,8 @@ from project.operation_execution.operation_executor_worker import create_operati
13
15
  from project.operation_execution.scheduled_operation_creator_worker import create_scheduled_operation_creator_worker
14
16
  from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
15
17
  from project.tg_bot.tg_bot import get_cached_tg_bot
18
+ from project.tg_bot.util.notify_admins import notify_admins
19
+ from project.tg_bot.util.set_tg_bot_commands import set_all_tg_bot_commands
16
20
 
17
21
  _logger = logging.getLogger(__name__)
18
22
 
@@ -23,6 +27,8 @@ _logger = logging.getLogger(__name__)
23
27
  async def startup_tg_bot_event():
24
28
  _logger.info("start")
25
29
 
30
+ _ = asyncio.create_task(notify_admins(text=f"Start\n{now_utc_dt().isoformat()}"))
31
+
26
32
  if get_cached_media_file_storage_in_dir() is not None:
27
33
  get_cached_media_file_storage_in_dir().init()
28
34
 
@@ -44,6 +50,9 @@ async def startup_tg_bot_event():
44
50
  ):
45
51
  get_cached_json_db().init()
46
52
 
53
+ if get_cached_settings().tg_bot_set_commands:
54
+ await set_all_tg_bot_commands()
55
+
47
56
  if get_cached_settings().tg_bot_drop_pending_updates:
48
57
  await get_cached_tg_bot().delete_webhook(drop_pending_updates=True)
49
58
 
@@ -89,6 +98,8 @@ async def shutdown_tg_bot_event(*args, **kwargs):
89
98
  if get_cached_settings().tg_bot_webhook_enabled:
90
99
  await get_cached_tg_bot().delete_webhook(drop_pending_updates=True)
91
100
 
101
+ await notify_admins(text=f"Finish\n{now_utc_dt().isoformat()}")
102
+
92
103
  _logger.info("finish")
93
104
 
94
105
 
@@ -97,7 +108,7 @@ def get_shutdown_tg_bot_events() -> list[Callable]:
97
108
  return res
98
109
 
99
110
 
100
- #
111
+ # MAIN
101
112
 
102
113
 
103
114
  def add_events_to_tg_bot_dispatcher(*, tg_bot_dispatcher: Dispatcher):
@@ -12,7 +12,7 @@ class UserRolesHasAdminTgBotFilter(Filter):
12
12
  middleware_data_tg_bot: MiddlewareDataTgBot,
13
13
  **kwargs
14
14
  ) -> bool:
15
- if middleware_data_tg_bot.user_dbm is not None:
16
- if middleware_data_tg_bot.user_dbm.roles_has_admin:
15
+ if middleware_data_tg_bot.current_user_dbm is not None:
16
+ if middleware_data_tg_bot.current_user_dbm.roles_has_admin:
17
17
  return True
18
18
  return False
@@ -12,7 +12,7 @@ class UserRolesHasClientTgBotFilter(Filter):
12
12
  middleware_data_tg_bot: MiddlewareDataTgBot,
13
13
  **kwargs
14
14
  ) -> bool:
15
- if middleware_data_tg_bot.user_dbm is not None:
16
- if middleware_data_tg_bot.user_dbm.roles_has_client:
15
+ if middleware_data_tg_bot.current_user_dbm is not None:
16
+ if middleware_data_tg_bot.current_user_dbm.roles_has_client:
17
17
  return True
18
18
  return False
@@ -0,0 +1,16 @@
1
+ from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
2
+ from aiogram.utils.keyboard import InlineKeyboardBuilder
3
+
4
+ from project.tg_bot.blank.admin import get_cached_eng_admin_tg_bot_blank
5
+ from project.tg_bot.callback.admin import HelloWorldAdminCD
6
+
7
+
8
+ def hello_world_admin_inline_kb_tg_bot() -> InlineKeyboardMarkup:
9
+ kb_builder = InlineKeyboardBuilder()
10
+
11
+ kb_builder.row(InlineKeyboardButton(
12
+ text=get_cached_eng_admin_tg_bot_blank().but_hello_world(),
13
+ callback_data=HelloWorldAdminCD(hello_world=True).pack()
14
+ ))
15
+
16
+ return kb_builder.as_markup()
@@ -0,0 +1,15 @@
1
+ from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
2
+ from aiogram.utils.keyboard import InlineKeyboardBuilder
3
+
4
+ from project.tg_bot.blank.client import get_cached_rus_client_tg_bot_blank
5
+
6
+
7
+ def support_client_inline_kb_tg_bot() -> InlineKeyboardMarkup:
8
+ return InlineKeyboardBuilder(markup=[
9
+ [
10
+ InlineKeyboardButton(
11
+ text=get_cached_rus_client_tg_bot_blank().but_support(),
12
+ url="https://t.me/arpakit"
13
+ )
14
+ ]
15
+ ]).as_markup()
@@ -1,14 +1,14 @@
1
1
  from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
2
2
  from aiogram.utils.keyboard import ReplyKeyboardBuilder
3
3
 
4
- from project.tg_bot.blank.client import get_cached_client_tg_bot_blank
4
+ from project.tg_bot.blank.admin import get_cached_eng_admin_tg_bot_blank
5
5
 
6
6
 
7
- def hello_world_client_static_kb_tg_bot() -> ReplyKeyboardMarkup:
7
+ def hello_world_admin_static_kb_tg_bot() -> ReplyKeyboardMarkup:
8
8
  kb_builder = ReplyKeyboardBuilder()
9
9
 
10
10
  kb_builder.row(KeyboardButton(
11
- text=get_cached_client_tg_bot_blank().but_hello_world()
11
+ text=get_cached_eng_admin_tg_bot_blank().but_hello_world()
12
12
  ))
13
13
 
14
14
  return kb_builder.as_markup(resize_keyboard=True, one_time_keyboard=False)
@@ -8,6 +8,6 @@ from project.sqlalchemy_db_.sqlalchemy_model import UserDBM
8
8
  class MiddlewareDataTgBot(BaseModel):
9
9
  model_config = ConfigDict(extra="forbid", arbitrary_types_allowed=True, from_attributes=True)
10
10
 
11
- user_dbm: UserDBM | None = None
12
- user_dbm_just_created: bool | None = None
11
+ current_user_dbm: UserDBM | None = None
12
+ current_user_dbm_just_created: bool | None = None
13
13
  additional_data: dict[str, Any] = {}
@@ -47,38 +47,38 @@ class InitUserTgBotMiddleware(BaseMiddleware):
47
47
 
48
48
  if tg_user is not None and get_cached_sqlalchemy_db() is not None:
49
49
  async with get_cached_sqlalchemy_db().new_async_session() as async_session:
50
- middleware_data_tg_bot.user_dbm = await async_session.scalar(
50
+ middleware_data_tg_bot.current_user_dbm = await async_session.scalar(
51
51
  sqlalchemy.select(UserDBM).filter(UserDBM.tg_id == tg_user.id)
52
52
  )
53
- if middleware_data_tg_bot.user_dbm is None:
53
+ if middleware_data_tg_bot.current_user_dbm is None:
54
54
  roles = [UserDBM.Roles.client]
55
55
  if tg_user.id in get_cached_settings().tg_bot_admin_tg_ids:
56
56
  roles.append(UserDBM.Roles.admin)
57
- middleware_data_tg_bot.user_dbm = UserDBM(
57
+ middleware_data_tg_bot.current_user_dbm = UserDBM(
58
58
  creation_dt=now_utc_dt_,
59
59
  roles=roles,
60
60
  tg_id=tg_user.id,
61
61
  tg_data=tg_user.model_dump(mode="json"),
62
62
  tg_bot_last_action_dt=now_utc_dt_
63
63
  )
64
- async_session.add(middleware_data_tg_bot.user_dbm)
64
+ async_session.add(middleware_data_tg_bot.current_user_dbm)
65
65
  await async_session.commit()
66
- await async_session.refresh(middleware_data_tg_bot.user_dbm)
67
- middleware_data_tg_bot.user_dbm_just_created = True
68
- _logger.info(f"user_dbm was added, {middleware_data_tg_bot.user_dbm}")
66
+ await async_session.refresh(middleware_data_tg_bot.current_user_dbm)
67
+ middleware_data_tg_bot.current_user_dbm_just_created = True
68
+ _logger.info(f"user_dbm was added, {middleware_data_tg_bot.current_user_dbm}")
69
69
  else:
70
- middleware_data_tg_bot.user_dbm.tg_data = tg_user.model_dump(mode="json")
71
- middleware_data_tg_bot.user_dbm.tg_bot_last_action_dt = now_utc_dt_
70
+ middleware_data_tg_bot.current_user_dbm.tg_data = tg_user.model_dump(mode="json")
71
+ middleware_data_tg_bot.current_user_dbm.tg_bot_last_action_dt = now_utc_dt_
72
72
  if (
73
73
  tg_user.id in get_cached_settings().tg_bot_admin_tg_ids
74
- and UserDBM.Roles.admin not in middleware_data_tg_bot.user_dbm.roles
74
+ and UserDBM.Roles.admin not in middleware_data_tg_bot.current_user_dbm.roles
75
75
  ):
76
- middleware_data_tg_bot.user_dbm.roles = (
77
- middleware_data_tg_bot.user_dbm.roles + [UserDBM.Roles.admin]
76
+ middleware_data_tg_bot.current_user_dbm.roles = (
77
+ middleware_data_tg_bot.current_user_dbm.roles + [UserDBM.Roles.admin]
78
78
  )
79
79
  await async_session.commit()
80
- await async_session.refresh(middleware_data_tg_bot.user_dbm)
81
- middleware_data_tg_bot.user_dbm_just_created = False
80
+ await async_session.refresh(middleware_data_tg_bot.current_user_dbm)
81
+ middleware_data_tg_bot.current_user_dbm_just_created = False
82
82
 
83
83
  _logger.info("finish")
84
84
 
@@ -1,4 +1,5 @@
1
1
  import aiogram.filters
2
+ from aiogram.fsm.context import FSMContext
2
3
 
3
4
  from arpakitlib.ar_aiogram_util import as_tg_command
4
5
  from arpakitlib.ar_json_util import transfer_data_to_json_str
@@ -19,9 +20,11 @@ tg_bot_router = aiogram.Router()
19
20
  @as_tg_command()
20
21
  async def _(
21
22
  m: aiogram.types.Message,
23
+ state: FSMContext,
22
24
  middleware_data_tg_bot: MiddlewareDataTgBot,
23
25
  **kwargs
24
26
  ):
27
+ await state.clear()
25
28
  await m.answer(
26
29
  text=transfer_data_to_json_str(get_arpakitlib_project_template_info(), beautify=True)
27
30
  )
@@ -1,13 +1,15 @@
1
1
  import aiogram
2
2
  from aiogram import Router, types
3
3
  from aiogram.filters import Command
4
+ from aiogram.fsm.context import FSMContext
4
5
 
5
6
  from arpakitlib.ar_aiogram_util import as_tg_command
6
7
  from project.core.settings import get_cached_settings
7
- from project.tg_bot.blank.admin import get_cached_admin_tg_bot_blank
8
+ from project.tg_bot.blank.admin import get_cached_eng_admin_tg_bot_blank
8
9
  from project.tg_bot.const import AdminTgBotCommands
9
10
  from project.tg_bot.filter_.is_private_chat import IsPrivateChatTgBotFilter
10
11
  from project.tg_bot.filter_.user_roles_has_admin import UserRolesHasAdminTgBotFilter
12
+ from project.tg_bot.middleware.common import MiddlewareDataTgBot
11
13
 
12
14
  tg_bot_router = Router()
13
15
 
@@ -20,14 +22,18 @@ tg_bot_router = Router()
20
22
  @as_tg_command(passwd_validator=get_cached_settings().tg_bot_command_passwd)
21
23
  async def _(
22
24
  m: types.Message,
25
+ state: FSMContext,
26
+ middleware_data_tg_bot: MiddlewareDataTgBot,
23
27
  **kwargs
24
28
  ):
29
+ await state.clear()
30
+
25
31
  with open(get_cached_settings().log_filepath, mode="r") as f:
26
32
  if not f.read():
27
- await m.answer(get_cached_admin_tg_bot_blank().good())
33
+ await m.answer(get_cached_eng_admin_tg_bot_blank().good())
28
34
  return
29
35
 
30
36
  with open(get_cached_settings().log_filepath, mode="w") as f:
31
37
  f.write("")
32
38
 
33
- await m.answer(get_cached_admin_tg_bot_blank().good())
39
+ await m.answer(get_cached_eng_admin_tg_bot_blank().good())
@@ -0,0 +1,31 @@
1
+ import aiogram
2
+ from aiogram import Router, types
3
+ from aiogram.filters import Command
4
+ from aiogram.fsm.context import FSMContext
5
+
6
+ from arpakitlib.ar_aiogram_util import as_tg_command
7
+ from project.tg_bot.const import AdminTgBotCommands
8
+ from project.tg_bot.filter_.is_private_chat import IsPrivateChatTgBotFilter
9
+ from project.tg_bot.filter_.user_roles_has_admin import UserRolesHasAdminTgBotFilter
10
+ from project.tg_bot.middleware.common import MiddlewareDataTgBot
11
+
12
+ tg_bot_router = Router()
13
+
14
+
15
+ @tg_bot_router.message(
16
+ IsPrivateChatTgBotFilter(),
17
+ UserRolesHasAdminTgBotFilter(),
18
+ aiogram.filters.Command(AdminTgBotCommands.current_state)
19
+ )
20
+ @as_tg_command()
21
+ async def _(
22
+ m: types.Message,
23
+ state: FSMContext,
24
+ middleware_data_tg_bot: MiddlewareDataTgBot,
25
+ **kwargs
26
+ ):
27
+ state = await state.get_state()
28
+ await m.answer(text=(
29
+ f"State:"
30
+ f"\n<code>{state}</code>"
31
+ ))
@@ -1,9 +1,10 @@
1
1
  import aiogram.filters
2
+ from aiogram.fsm.context import FSMContext
2
3
 
3
4
  from arpakitlib.ar_aiogram_util import as_tg_command
4
5
  from project.core.settings import get_cached_settings
5
6
  from project.sqlalchemy_db_.sqlalchemy_db import get_cached_sqlalchemy_db
6
- from project.tg_bot.blank.admin import get_cached_admin_tg_bot_blank
7
+ from project.tg_bot.blank.admin import get_cached_eng_admin_tg_bot_blank
7
8
  from project.tg_bot.const import AdminTgBotCommands
8
9
  from project.tg_bot.filter_.is_private_chat import IsPrivateChatTgBotFilter
9
10
  from project.tg_bot.filter_.not_prod_mode_filter import NotProdModeTgBotFilter
@@ -22,10 +23,12 @@ tg_bot_router = aiogram.Router()
22
23
  @as_tg_command(passwd_validator=get_cached_settings().tg_bot_command_passwd)
23
24
  async def _(
24
25
  m: aiogram.types.Message,
26
+ state: FSMContext,
25
27
  middleware_data_tg_bot: MiddlewareDataTgBot,
26
28
  **kwargs
27
29
  ):
30
+ await state.clear()
28
31
  get_cached_sqlalchemy_db().drop()
29
32
  await m.answer(
30
- text=get_cached_admin_tg_bot_blank().good()
33
+ text=get_cached_eng_admin_tg_bot_blank().good()
31
34
  )
@@ -0,0 +1,73 @@
1
+ import aiogram.filters
2
+ from aiogram.filters import or_f
3
+ from aiogram.fsm.context import FSMContext
4
+
5
+ from arpakitlib.ar_str_util import remove_html
6
+ from project.tg_bot.blank.admin import get_cached_eng_admin_tg_bot_blank
7
+ from project.tg_bot.blank.client import get_cached_rus_client_tg_bot_blank
8
+ from project.tg_bot.callback.admin import HelloWorldAdminCD
9
+ from project.tg_bot.const import AdminTgBotCommands
10
+ from project.tg_bot.filter_.is_private_chat import IsPrivateChatTgBotFilter
11
+ from project.tg_bot.filter_.message_text import MessageTextTgBotFilter
12
+ from project.tg_bot.filter_.user_roles_has_admin import UserRolesHasAdminTgBotFilter
13
+ from project.tg_bot.kb.inline_.admin.hello_world import hello_world_admin_inline_kb_tg_bot
14
+ from project.tg_bot.kb.static_.admin.hello_world import hello_world_admin_static_kb_tg_bot
15
+ from project.tg_bot.middleware.common import MiddlewareDataTgBot
16
+ from project.tg_bot.state.client import HelloWorldClientStates
17
+
18
+ tg_bot_router = aiogram.Router()
19
+
20
+
21
+ @tg_bot_router.message(
22
+ IsPrivateChatTgBotFilter(),
23
+ UserRolesHasAdminTgBotFilter(),
24
+ or_f(
25
+ aiogram.filters.Command(AdminTgBotCommands.hello_world),
26
+ MessageTextTgBotFilter(get_cached_eng_admin_tg_bot_blank().but_hello_world())
27
+ ),
28
+
29
+ )
30
+ async def _(
31
+ m: aiogram.types.Message,
32
+ state: FSMContext,
33
+ middleware_data_tg_bot: MiddlewareDataTgBot,
34
+ **kwargs
35
+ ):
36
+ await state.clear()
37
+ await m.answer(
38
+ text=get_cached_rus_client_tg_bot_blank().hello_world(),
39
+ reply_markup=hello_world_admin_inline_kb_tg_bot()
40
+ )
41
+ await m.answer(
42
+ text=get_cached_rus_client_tg_bot_blank().hello_world(),
43
+ reply_markup=hello_world_admin_static_kb_tg_bot()
44
+ )
45
+ await state.set_state(HelloWorldClientStates.input_text)
46
+
47
+
48
+ @tg_bot_router.callback_query(
49
+ HelloWorldAdminCD.filter()
50
+ )
51
+ async def _(
52
+ cq: aiogram.types.CallbackQuery,
53
+ state: FSMContext,
54
+ middleware_data_tg_bot: MiddlewareDataTgBot,
55
+ **kwargs
56
+ ):
57
+ await cq.message.delete_reply_markup()
58
+ await cq.message.answer(
59
+ text=remove_html(get_cached_rus_client_tg_bot_blank().hello_world())
60
+ )
61
+
62
+
63
+ @tg_bot_router.message(
64
+ HelloWorldClientStates.input_text
65
+ )
66
+ async def _(
67
+ m: aiogram.types.Message,
68
+ state: FSMContext,
69
+ middleware_data_tg_bot: MiddlewareDataTgBot,
70
+ **kwargs
71
+ ):
72
+ await state.clear()
73
+ await m.answer("Hello world")