django-slack-tools 0.2.2__py3-none-any.whl → 0.3.1__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 (52) hide show
  1. django_slack_tools/__init__.py +0 -1
  2. django_slack_tools/app_settings.py +54 -90
  3. django_slack_tools/locale/ko_KR/LC_MESSAGES/django.po +150 -186
  4. django_slack_tools/py.typed +0 -0
  5. django_slack_tools/slack_messages/admin/message.py +1 -52
  6. django_slack_tools/slack_messages/admin/message_recipient.py +2 -2
  7. django_slack_tools/slack_messages/admin/messaging_policy.py +5 -5
  8. django_slack_tools/slack_messages/backends/__init__.py +3 -3
  9. django_slack_tools/slack_messages/backends/base.py +39 -203
  10. django_slack_tools/slack_messages/backends/dummy.py +0 -12
  11. django_slack_tools/slack_messages/backends/{logging.py → logging_.py} +0 -6
  12. django_slack_tools/slack_messages/backends/slack.py +21 -75
  13. django_slack_tools/slack_messages/message_templates/__init__.py +5 -0
  14. django_slack_tools/slack_messages/message_templates/base.py +17 -0
  15. django_slack_tools/{utils/template → slack_messages/message_templates}/django.py +30 -25
  16. django_slack_tools/slack_messages/message_templates/python.py +38 -0
  17. django_slack_tools/slack_messages/messenger.py +158 -0
  18. django_slack_tools/slack_messages/middlewares/__init__.py +4 -0
  19. django_slack_tools/slack_messages/middlewares/base.py +34 -0
  20. django_slack_tools/slack_messages/middlewares/django.py +218 -0
  21. django_slack_tools/slack_messages/migrations/0001_initial.py +4 -4
  22. django_slack_tools/slack_messages/migrations/0005_alter_slackmessagingpolicy_template_type.py +46 -0
  23. django_slack_tools/slack_messages/migrations/0006_alter_slackmessage_id.py +26 -0
  24. django_slack_tools/slack_messages/models/mention.py +1 -1
  25. django_slack_tools/slack_messages/models/message.py +5 -2
  26. django_slack_tools/slack_messages/models/message_recipient.py +1 -1
  27. django_slack_tools/slack_messages/models/messaging_policy.py +4 -4
  28. django_slack_tools/slack_messages/request.py +91 -0
  29. django_slack_tools/slack_messages/response.py +21 -0
  30. django_slack_tools/slack_messages/shortcuts.py +78 -0
  31. django_slack_tools/slack_messages/tasks.py +8 -57
  32. django_slack_tools/slack_messages/template_loaders/__init__.py +11 -0
  33. django_slack_tools/slack_messages/template_loaders/base.py +16 -0
  34. django_slack_tools/slack_messages/template_loaders/django.py +74 -0
  35. django_slack_tools/slack_messages/template_loaders/errors.py +9 -0
  36. django_slack_tools/{utils/slack/django.py → slack_messages/validators.py} +1 -1
  37. django_slack_tools/utils/django/__init__.py +0 -0
  38. django_slack_tools/utils/import_helper.py +37 -0
  39. django_slack_tools/utils/repr.py +10 -0
  40. django_slack_tools/utils/slack/__init__.py +1 -9
  41. {django_slack_tools-0.2.2.dist-info → django_slack_tools-0.3.1.dist-info}/METADATA +12 -60
  42. django_slack_tools-0.3.1.dist-info/RECORD +58 -0
  43. {django_slack_tools-0.2.2.dist-info → django_slack_tools-0.3.1.dist-info}/WHEEL +1 -1
  44. django_slack_tools/slack_messages/message.py +0 -110
  45. django_slack_tools/utils/slack/message.py +0 -93
  46. django_slack_tools/utils/template/__init__.py +0 -5
  47. django_slack_tools/utils/template/base.py +0 -17
  48. django_slack_tools/utils/template/dict.py +0 -52
  49. django_slack_tools-0.2.2.dist-info/RECORD +0 -43
  50. /django_slack_tools/utils/{model_mixins.py → django/model_mixins.py} +0 -0
  51. /django_slack_tools/utils/{widgets.py → django/widgets.py} +0 -0
  52. {django_slack_tools-0.2.2.dist-info → django_slack_tools-0.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -1 +0,0 @@
1
- __version__ = "0.2.2"
@@ -1,123 +1,87 @@
1
1
  """Application settings."""
2
+ # flake8: noqa: UP007
2
3
 
3
4
  from __future__ import annotations
4
5
 
5
6
  from logging import getLogger
6
- from typing import TYPE_CHECKING, Any, TypedDict
7
+ from typing import TYPE_CHECKING, TypedDict
7
8
 
8
9
  from django.conf import settings
9
10
  from django.core.exceptions import ImproperlyConfigured
10
11
  from django.utils.module_loading import import_string
11
12
  from slack_bolt import App
13
+ from typing_extensions import NotRequired, Self
12
14
 
13
- from django_slack_tools.slack_messages.backends.base import BaseBackend
15
+ from django_slack_tools.utils.import_helper import LazyInitSpec, lazy_init
14
16
 
15
17
  if TYPE_CHECKING:
16
- from typing import Any
17
-
18
- from typing_extensions import NotRequired
19
-
20
- APP_SETTINGS_KEY = "DJANGO_SLACK_TOOLS"
21
- "Django settings key for this application."
18
+ from django_slack_tools.slack_messages.messenger import Messenger
22
19
 
23
20
  logger = getLogger(__name__)
24
21
 
25
22
 
26
- # TODO(lasuillard): Configuration getting dirty, need refactoring
27
- class AppSettings:
28
- """Application settings."""
29
-
30
- backend: BaseBackend
31
-
32
- def __init__(self, settings_dict: ConfigDict | None = None) -> None:
33
- """Initialize app settings.
34
-
35
- Args:
36
- settings_dict: Settings dictionary. If `None`, try to load from Django settings (const `APP_SETTINGS_KEY`).
37
- Defaults to `None`.
23
+ class SettingsDict(TypedDict):
24
+ """Dictionary input for app settings."""
38
25
 
39
- Raises:
40
- ImproperlyConfigured: Required configuration not provided or is unexpected.
41
- """
42
- if not settings_dict:
43
- settings_dict = getattr(settings, APP_SETTINGS_KEY, None)
26
+ slack_app: str
27
+ messengers: NotRequired[dict[str, LazyInitSpec]]
44
28
 
45
- if settings_dict is None:
46
- msg = "Neither `settings_dict` provided or `django_slack_tools` settings found in Django settings."
47
- raise ImproperlyConfigured(msg)
48
29
 
49
- # Slack app
50
- slack_app = settings_dict["SLACK_APP"]
51
- if isinstance(slack_app, str):
52
- slack_app = import_string(slack_app)
30
+ class AppSettings:
31
+ """Application settings."""
53
32
 
54
- if callable(slack_app):
55
- slack_app = slack_app()
33
+ slack_app: App
34
+ messengers: dict[str, Messenger]
56
35
 
36
+ def __init__(self, slack_app: App, messengers: dict[str, Messenger]) -> None: # noqa: D107
57
37
  if not isinstance(slack_app, App):
58
- msg = "Provided `SLACK_APP` config is not Slack app."
59
- raise ImproperlyConfigured(msg)
60
-
61
- self._slack_app = slack_app
62
-
63
- # Find backend class
64
- messaging_backend = import_string(settings_dict["BACKEND"]["NAME"])
65
- if not issubclass(messaging_backend, BaseBackend):
66
- msg = "Provided backend is not a subclass of `{qualified_path}` class.".format(
67
- qualified_path=f"{BaseBackend.__module__}.{BaseBackend.__name__}",
38
+ msg = f"Expected {App!s} instance, got {type(slack_app)}"
39
+ raise TypeError(msg)
40
+
41
+ self.slack_app = slack_app
42
+ self.messengers = messengers
43
+
44
+ @classmethod
45
+ def from_dict(cls, settings_dict: SettingsDict) -> Self:
46
+ """Initialize settings from a dictionary."""
47
+ try:
48
+ slack_app = import_string(settings_dict["slack_app"])
49
+ messengers = {
50
+ name: cls._create_messenger(spec) for name, spec in settings_dict.get("messengers", {}).items()
51
+ }
52
+ return cls(
53
+ slack_app=slack_app,
54
+ messengers=messengers,
68
55
  )
69
- raise ImproperlyConfigured(msg)
70
-
71
- # Initialize with provided options
72
- self.backend = messaging_backend(**settings_dict["BACKEND"]["OPTIONS"])
73
-
74
- # Message delivery default
75
- self.default_policy_code = settings_dict.get("DEFAULT_POLICY_CODE", "DEFAULT")
76
-
77
- # Lazy policy defaults
78
- self.lazy_policy_enabled = settings_dict.get("LAZY_POLICY_ENABLED", False)
79
- self.default_template = settings_dict.get(
80
- "DEFAULT_POLICY_CODE",
81
- {"text": "No template configured for lazily created policy {policy}"},
82
- )
83
- self.default_recipient = settings_dict.get("DEFAULT_RECIPIENT", "DEFAULT")
84
-
85
- @property
86
- def slack_app(self) -> App:
87
- """Registered Slack app or `None`."""
88
- return self._slack_app
89
-
90
-
91
- app_settings = AppSettings()
92
-
93
-
94
- class ConfigDict(TypedDict):
95
- """Root config dict."""
96
-
97
- SLACK_APP: App | str | None
98
- "Import string to Slack app. Used for workspace-related stuffs."
56
+ except Exception as err:
57
+ msg = f"Couldn't initialize app settings: {err!s}"
58
+ raise ImproperlyConfigured(msg) from err
99
59
 
100
- BACKEND: BackendConfig
101
- "Nested backend config."
60
+ @classmethod
61
+ def _create_messenger(cls, spec: LazyInitSpec) -> Messenger:
62
+ class_ = import_string(spec["class"])
63
+ args, kwargs = spec.get("args", ()), spec.get("kwargs", {})
102
64
 
103
- LAZY_POLICY_ENABLED: NotRequired[bool]
104
- "Whether to enable lazy policy by default."
65
+ # Lazy-init all the things
66
+ kwargs = kwargs.copy()
67
+ kwargs["template_loaders"] = [lazy_init(tl) for tl in kwargs["template_loaders"]]
68
+ kwargs["middlewares"] = [lazy_init(tl) for tl in kwargs["middlewares"]]
69
+ kwargs["messaging_backend"] = lazy_init(kwargs["messaging_backend"])
105
70
 
106
- DEFAULT_POLICY_CODE: NotRequired[str]
107
- "Default policy code used when sending messages via policy with no policy specified."
71
+ # Create the messenger
72
+ return class_(*args, **kwargs) # type: ignore[no-any-return]
108
73
 
109
- DEFAULT_TEMPLATE: NotRequired[Any]
110
- "Default template for lazy policy."
111
74
 
112
- DEFAULT_RECIPIENT: NotRequired[str]
113
- "Default recipient alias for lazy policy."
75
+ def get_settings_from_django(settings_key: str = "DJANGO_SLACK_TOOLS") -> AppSettings:
76
+ """Get application settings."""
77
+ django_settings: SettingsDict = getattr(settings, settings_key)
78
+ return AppSettings.from_dict(django_settings or {})
114
79
 
115
80
 
116
- class BackendConfig(TypedDict):
117
- """Backend config dict."""
81
+ app_settings = get_settings_from_django()
118
82
 
119
- NAME: str
120
- "Import path to backend class."
121
83
 
122
- OPTIONS: dict[str, Any]
123
- "Options to pass to backend class on initialization."
84
+ def get_messenger(name: str | None = None) -> Messenger:
85
+ """Get a messenger instance by name."""
86
+ name = name or "default"
87
+ return app_settings.messengers[name]