2
2
3
3
from __future__ import annotations
4
4
5
- from typing import TYPE_CHECKING , Dict , List , Optional , cast
5
+ from typing import TYPE_CHECKING , Dict , List , Optional , Sequence , cast
6
6
7
7
from . import utils
8
- from .asset import Asset
8
+ from .asset import Asset , AssetBytes
9
9
from .enums import ApplicationEventWebhookStatus , try_enum
10
10
from .flags import ApplicationFlags
11
11
from .permissions import Permissions
12
+ from .utils import MISSING
12
13
13
14
if TYPE_CHECKING :
14
15
from .guild import Guild
17
18
AppInfo as AppInfoPayload ,
18
19
ApplicationIntegrationType as ApplicationIntegrationTypeLiteral ,
19
20
ApplicationIntegrationTypeConfiguration as ApplicationIntegrationTypeConfigurationPayload ,
21
+ EditAppInfo as EditAppInfoPayload ,
20
22
InstallParams as InstallParamsPayload ,
21
23
PartialAppInfo as PartialAppInfoPayload ,
22
24
Team as TeamPayload ,
23
25
)
24
26
from .user import User
25
27
28
+
26
29
__all__ = (
27
30
"AppInfo" ,
28
31
"PartialAppInfo" ,
@@ -36,6 +39,9 @@ class InstallParams:
36
39
37
40
.. versionadded:: 2.5
38
41
42
+ .. versionchanged:: |vnext|
43
+ This class can now be created by users.
44
+
39
45
Attributes
40
46
----------
41
47
scopes: List[:class:`str`]
@@ -53,27 +59,46 @@ class InstallParams:
53
59
54
60
def __init__ (
55
61
self ,
62
+ * ,
63
+ scopes : List [str ],
64
+ permissions : Permissions = MISSING ,
65
+ ) -> None :
66
+ self .scopes = scopes
67
+ if permissions is MISSING :
68
+ permissions = Permissions .none ()
69
+ self .permissions = permissions
70
+ self ._app_id : Optional [int ] = None
71
+ self ._install_type : Optional [ApplicationIntegrationTypeLiteral ] = None
72
+
73
+ @classmethod
74
+ def _from_data (
75
+ cls ,
56
76
data : InstallParamsPayload ,
57
77
parent : AppInfo ,
58
78
* ,
59
79
install_type : Optional [ApplicationIntegrationTypeLiteral ] = None ,
60
- ) -> None :
61
- self . _app_id = parent . id
62
- self ._install_type : Optional [ ApplicationIntegrationTypeLiteral ] = install_type
63
- self . scopes = data [ "scopes" ]
64
- self . permissions = Permissions ( int ( data [ "permissions" ]))
80
+ ) -> InstallParams :
81
+ instance = cls ( permissions = Permissions ( int ( data [ "permissions" ])), scopes = data [ "scopes" ])
82
+ instance ._install_type = install_type
83
+ instance . _app_id = parent . id
84
+ return instance
65
85
66
86
def __repr__ (self ) -> str :
67
87
return f"<InstallParams scopes={ self .scopes !r} permissions={ self .permissions !r} >"
68
88
69
89
def to_url (self ) -> str :
70
90
"""Returns a string that can be used to install this application.
71
91
92
+ .. note:: This method can only be used on InstallParams that have been created by :meth:`.Client.application_info`
93
+
72
94
Returns
73
95
-------
74
96
:class:`str`
75
97
The invite url.
76
98
"""
99
+ if self ._app_id is None :
100
+ msg = "This InstallParams instance is not linked to an application."
101
+ raise ValueError (msg )
77
102
return utils .oauth_url (
78
103
self ._app_id ,
79
104
scopes = self .scopes ,
@@ -83,12 +108,22 @@ def to_url(self) -> str:
83
108
),
84
109
)
85
110
111
+ def to_dict (self ) -> InstallParamsPayload :
112
+ return {
113
+ "scopes" : self .scopes ,
114
+ "permissions" : str (self .permissions .value ),
115
+ }
116
+
86
117
87
118
class InstallTypeConfiguration :
88
119
"""Represents the configuration for a particular application installation type.
89
120
90
121
.. versionadded:: 2.10
91
122
123
+ .. versionchanged:: |vnext|
124
+
125
+ This class can now be created by users.
126
+
92
127
Attributes
93
128
----------
94
129
install_params: Optional[:class:`InstallParams`]
@@ -97,19 +132,31 @@ class InstallTypeConfiguration:
97
132
98
133
__slots__ = ("install_params" ,)
99
134
100
- def __init__ (
101
- self ,
135
+ def __init__ (self , * , install_params : Optional [InstallParams ] = None ) -> None :
136
+ self .install_params : Optional [InstallParams ] = install_params
137
+
138
+ @classmethod
139
+ def _from_data (
140
+ cls ,
102
141
data : ApplicationIntegrationTypeConfigurationPayload ,
103
142
* ,
104
143
parent : AppInfo ,
105
144
install_type : ApplicationIntegrationTypeLiteral ,
106
- ) -> None :
107
- self .install_params : Optional [InstallParams ] = (
108
- InstallParams (install_params , parent = parent , install_type = install_type )
145
+ ) -> InstallTypeConfiguration :
146
+ return cls (
147
+ install_params = InstallParams ._from_data (
148
+ install_params , parent = parent , install_type = install_type
149
+ )
109
150
if (install_params := data .get ("oauth2_install_params" ))
110
151
else None
111
152
)
112
153
154
+ def to_dict (self ) -> ApplicationIntegrationTypeConfigurationPayload :
155
+ payload : ApplicationIntegrationTypeConfigurationPayload = {}
156
+ if self .install_params :
157
+ payload ["oauth2_install_params" ] = self .install_params .to_dict ()
158
+ return payload
159
+
113
160
def __repr__ (self ) -> str :
114
161
return f"<InstallTypeConfiguration install_params={ self .install_params !r} >"
115
162
@@ -310,7 +357,9 @@ def __init__(self, state: ConnectionState, data: AppInfoPayload) -> None:
310
357
)
311
358
self .tags : Optional [List [str ]] = data .get ("tags" )
312
359
self .install_params : Optional [InstallParams ] = (
313
- InstallParams (data ["install_params" ], parent = self ) if "install_params" in data else None
360
+ InstallParams ._from_data (data ["install_params" ], parent = self )
361
+ if "install_params" in data
362
+ else None
314
363
)
315
364
self .custom_install_url : Optional [str ] = data .get ("custom_install_url" )
316
365
self .redirect_uris : Optional [List [str ]] = data .get ("redirect_uris" )
@@ -335,7 +384,7 @@ def __init__(self, state: ConnectionState, data: AppInfoPayload) -> None:
335
384
] = {}
336
385
for type_str , config in (data .get ("integration_types_config" ) or {}).items ():
337
386
install_type = cast ("ApplicationIntegrationTypeLiteral" , int (type_str ))
338
- self ._install_types_config [install_type ] = InstallTypeConfiguration (
387
+ self ._install_types_config [install_type ] = InstallTypeConfiguration . _from_data (
339
388
config or {},
340
389
parent = self ,
341
390
install_type = install_type ,
@@ -405,6 +454,193 @@ def user_install_type_config(self) -> Optional[InstallTypeConfiguration]:
405
454
"""
406
455
return self ._install_types_config .get (1 )
407
456
457
+ async def edit (
458
+ self ,
459
+ * ,
460
+ custom_install_url : Optional [str ] = MISSING ,
461
+ description : Optional [str ] = MISSING ,
462
+ role_connections_verification_url : Optional [str ] = MISSING ,
463
+ install_params : Optional [InstallParams ] = MISSING ,
464
+ guild_install_type_config : Optional [InstallTypeConfiguration ] = MISSING ,
465
+ user_install_type_config : Optional [InstallTypeConfiguration ] = MISSING ,
466
+ flags : ApplicationFlags = MISSING ,
467
+ icon : Optional [AssetBytes ] = MISSING ,
468
+ cover_image : Optional [AssetBytes ] = MISSING ,
469
+ interactions_endpoint_url : Optional [str ] = MISSING ,
470
+ tags : Sequence [str ] = MISSING ,
471
+ event_webhooks_url : Optional [str ] = MISSING ,
472
+ event_webhooks_status : ApplicationEventWebhookStatus = MISSING ,
473
+ event_webhooks_types : Sequence [str ] = MISSING ,
474
+ ) -> AppInfo :
475
+ """|coro|
476
+
477
+ Edit's the application's information.
478
+
479
+ All parameters are optional.
480
+
481
+ .. versionadded:: |vnext|
482
+
483
+ Parameters
484
+ ----------
485
+ custom_install_url: Optional[:class:`str`]
486
+ The custom installation url for this application.
487
+ description: Optional[:class:`str`]
488
+ The application's description.
489
+ role_connections_verification_url: Optional[:class:`str`]
490
+ The application's role connection verification entry point,
491
+ which when configured will render the app as a verification method
492
+ in the guild role verification configuration.
493
+ install_params: Optional[:class:`InstallParams`]
494
+ The installation parameters for this application.
495
+
496
+ If provided with ``custom_install_url``, must be set to ``None``.
497
+
498
+ It's recommended to use :attr:`guild_install_type_config` and :attr:`user_install_type_config`
499
+ instead of this parameter, as this parameter is soft-deprecated by Discord.
500
+
501
+ :attr:`bot_public` **must** be ``True`` if this parameter is provided.
502
+ guild_install_type_config: Optional[:class:`InstallTypeConfiguration`]
503
+ The guild installation type configuration for this application.
504
+ If set to ``None``, guild installations will be disabled.
505
+ You cannot disable both user and guild installations.
506
+
507
+ Note the only valid scopes for guild installations are ``applications.commands`` and ``bot``.
508
+
509
+ user_install_type_config: Optional[:class:`InstallTypeConfiguration`]
510
+ The user installation type configuration for this application.
511
+ If set to ``None``, user installations will be disabled.
512
+ You cannot disable both user and guild installations.
513
+
514
+ Note the only valid scopes for user installations are ``applications.commands``.
515
+ flags: :class:`ApplicationFlags`
516
+ The application's public flags.
517
+
518
+ This is restricted to only affecting the limited intent flags:
519
+ :attr:`~ApplicationFlags.gateway_guild_members_limited`,
520
+ :attr:`~ApplicationFlags.gateway_presence_limited`, and
521
+ :attr:`~ApplicationFlags.gateway_message_content_limited`.
522
+
523
+ .. warning::
524
+ Disabling an intent that you are currently requesting during your current session
525
+ will cause you to be disconnected from the gateway. Take caution when providing this parameter.
526
+
527
+ icon: Optional[|resource_type|]
528
+ Update the application's icon asset, if any.
529
+ cover_image: Optional[|resource_type|]
530
+ Update the cover_image for rich presence integrations.
531
+ interactions_endpoint_url: Optional[:class:`str`]
532
+ The application's interactions endpoint URL.
533
+ tags: List[:class:`str`]
534
+ The application's tags.
535
+ event_webhooks_url: Optional[:class:`str`]
536
+ The application's event webhooks URL.
537
+ event_webhooks_status: :class:`ApplicationEventWebhookStatus`
538
+ The application's event webhooks status.
539
+ event_webhooks_types: Optional[List[:class:`str`]]
540
+ The application's event webhook types. See `webhook event types <https://discord.com/developers/docs/events/webhook-events#event-types>`_
541
+ for a list of valid events.
542
+
543
+ Raises
544
+ ------
545
+ HTTPException
546
+ Editing the application information failed.
547
+
548
+ Returns
549
+ -------
550
+ :class:`.AppInfo`
551
+ The new application information.
552
+
553
+ Examples
554
+ --------
555
+
556
+ .. code-block:: python
557
+
558
+ >>> app_info = await client.application_info()
559
+ >>> await app_info.edit(description="A new description!")
560
+
561
+ To enable user installations while using custom install URL.
562
+
563
+ .. code-block:: python
564
+
565
+ >>> from disnake import InstallTypeConfiguration
566
+ >>> await app_info.edit(
567
+ ... user_install_type_config=InstallTypeConfiguration()
568
+ ... )
569
+
570
+ To disable user installations and guild installations.
571
+ Note, both cannot be disabled simultaneously.
572
+
573
+ .. code-block:: python
574
+
575
+ >>> await app_info.edit(
576
+ ... custom_install_url="https://example.com/install",
577
+ ... # to disable user installations
578
+ ... user_install_type_config=None,
579
+ ... # to disable guild installations
580
+ ... guild_install_type_config=None,
581
+ ... )
582
+ """
583
+ fields : EditAppInfoPayload = {}
584
+
585
+ if custom_install_url is not MISSING :
586
+ fields ["custom_install_url" ] = custom_install_url
587
+
588
+ if description is not MISSING :
589
+ fields ["description" ] = description or ""
590
+
591
+ if role_connections_verification_url is not MISSING :
592
+ fields ["role_connections_verification_url" ] = role_connections_verification_url
593
+
594
+ if install_params is not MISSING :
595
+ fields ["install_params" ] = install_params .to_dict () if install_params else None
596
+
597
+ if guild_install_type_config is not MISSING or user_install_type_config is not MISSING :
598
+ integration_types_config : Dict [str , ApplicationIntegrationTypeConfigurationPayload ] = {}
599
+
600
+ if guild_install_type_config is MISSING :
601
+ guild_install_type_config = self .guild_install_type_config
602
+ if guild_install_type_config :
603
+ integration_types_config ["0" ] = guild_install_type_config .to_dict ()
604
+
605
+ if user_install_type_config is MISSING :
606
+ user_install_type_config = self .user_install_type_config
607
+ if user_install_type_config :
608
+ integration_types_config ["1" ] = user_install_type_config .to_dict ()
609
+
610
+ fields ["integration_types_config" ] = integration_types_config
611
+
612
+ if flags is not MISSING :
613
+ fields ["flags" ] = flags .value
614
+
615
+ if icon is not MISSING :
616
+ fields ["icon" ] = await utils ._assetbytes_to_base64_data (icon )
617
+
618
+ if cover_image is not MISSING :
619
+ fields ["cover_image" ] = await utils ._assetbytes_to_base64_data (cover_image )
620
+
621
+ if interactions_endpoint_url is not MISSING :
622
+ fields ["interactions_endpoint_url" ] = interactions_endpoint_url
623
+
624
+ if tags is not MISSING :
625
+ fields ["tags" ] = list (tags ) if tags else None
626
+
627
+ if event_webhooks_url is not MISSING :
628
+ fields ["event_webhooks_url" ] = event_webhooks_url
629
+
630
+ if event_webhooks_status is not MISSING :
631
+ if event_webhooks_status is ApplicationEventWebhookStatus .disabled_by_discord :
632
+ msg = f"cannot set 'event_webhooks_status' to { event_webhooks_status !r} "
633
+ raise ValueError (msg )
634
+ fields ["event_webhooks_status" ] = event_webhooks_status .value
635
+
636
+ if event_webhooks_types is not MISSING :
637
+ fields ["event_webhooks_types" ] = (
638
+ list (event_webhooks_types ) if event_webhooks_types else None
639
+ )
640
+
641
+ data = await self ._state .http .edit_application_info (** fields )
642
+ return AppInfo (self ._state , data )
643
+
408
644
409
645
class PartialAppInfo :
410
646
"""Represents a partial AppInfo given by :func:`~disnake.abc.GuildChannel.create_invite`.
0 commit comments