Habiticalib 0.3.7rc1__py3-none-any.whl → 0.4.0rc1__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.
habiticalib/__init__.py CHANGED
@@ -46,14 +46,22 @@ from .typedefs import (
46
46
  GearItems,
47
47
  GearItemsAvatar,
48
48
  GearType,
49
+ GlobalActivity,
50
+ GlobalActivityWebhook,
51
+ GroupChatReceived,
52
+ GroupChatReceivedOptions,
53
+ GroupChatReceivedWebhook,
49
54
  GroupTask,
50
55
  HabiticaCastSkillResponse,
51
56
  HabiticaClass,
52
57
  HabiticaClassSystemResponse,
53
58
  HabiticaContentResponse,
59
+ HabiticaDeleteWebhookResponse,
54
60
  HabiticaErrorResponse,
55
61
  HabiticaGroupMembersResponse,
62
+ HabiticaGroupsResponse,
56
63
  HabiticaLoginResponse,
64
+ HabiticaMessageResponse,
57
65
  HabiticaQuestResponse,
58
66
  HabiticaResponse,
59
67
  HabiticaScoreResponse,
@@ -67,6 +75,7 @@ from .typedefs import (
67
75
  HabiticaUserAnonymizedResponse,
68
76
  HabiticaUserExport,
69
77
  HabiticaUserResponse,
78
+ HabiticaWebhookResponse,
70
79
  HairPreferences,
71
80
  HatchingPotionEntry,
72
81
  HistoryUser,
@@ -98,6 +107,9 @@ from .typedefs import (
98
107
  PurchasedUser,
99
108
  PushDevicesUser,
100
109
  PushNotificationsPreferences,
110
+ QuestActivity,
111
+ QuestActivityOptions,
112
+ QuestActivityWebhook,
101
113
  QuestBoss,
102
114
  QuestBossRage,
103
115
  QuestCollect,
@@ -123,6 +135,9 @@ from .typedefs import (
123
135
  SuppressModalsPreferences,
124
136
  TagsUser,
125
137
  Task,
138
+ TaskActivity,
139
+ TaskActivityOptions,
140
+ TaskActivityWebhook,
126
141
  TaskData,
127
142
  TaskFilter,
128
143
  TaskPriority,
@@ -135,12 +150,13 @@ from .typedefs import (
135
150
  TrainingStats,
136
151
  TutorialFlags,
137
152
  UltimateGearSetsAchievments,
153
+ UserActivity,
154
+ UserActivityOptions,
155
+ UserActivityWebhook,
138
156
  UserAnonymizedData,
139
157
  UserData,
140
158
  UserTasks,
141
- WebhooksOptions,
142
- WebhooksType,
143
- WebhooksUser,
159
+ WebhookType,
144
160
  )
145
161
 
146
162
  __all__ = [
@@ -185,6 +201,11 @@ __all__ = [
185
201
  "GearItems",
186
202
  "GearItemsAvatar",
187
203
  "GearType",
204
+ "GlobalActivity",
205
+ "GlobalActivityWebhook",
206
+ "GroupChatReceived",
207
+ "GroupChatReceivedOptions",
208
+ "GroupChatReceivedWebhook",
188
209
  "GroupTask",
189
210
  "Habitica",
190
211
  "HabiticaCastSkillResponse",
@@ -194,13 +215,16 @@ __all__ = [
194
215
  "HabiticaClassSystemResponse",
195
216
  "HabiticaContentResponse",
196
217
  "HabiticaContentResponse",
218
+ "HabiticaDeleteWebhookResponse",
197
219
  "HabiticaErrorResponse",
198
220
  "HabiticaErrorResponse",
199
221
  "HabiticaException",
200
222
  "HabiticaGroupMembersResponse",
201
223
  "HabiticaGroupMembersResponse",
224
+ "HabiticaGroupsResponse",
202
225
  "HabiticaLoginResponse",
203
226
  "HabiticaLoginResponse",
227
+ "HabiticaMessageResponse",
204
228
  "HabiticaQuestResponse",
205
229
  "HabiticaQuestResponse",
206
230
  "HabiticaResponse",
@@ -227,6 +251,7 @@ __all__ = [
227
251
  "HabiticaUserExport",
228
252
  "HabiticaUserResponse",
229
253
  "HabiticaUserResponse",
254
+ "HabiticaWebhookResponse",
230
255
  "HairPreferences",
231
256
  "HatchingPotionEntry",
232
257
  "HistoryUser",
@@ -261,6 +286,9 @@ __all__ = [
261
286
  "PurchasedUser",
262
287
  "PushDevicesUser",
263
288
  "PushNotificationsPreferences",
289
+ "QuestActivity",
290
+ "QuestActivityOptions",
291
+ "QuestActivityWebhook",
264
292
  "QuestBoss",
265
293
  "QuestBossRage",
266
294
  "QuestCollect",
@@ -291,6 +319,9 @@ __all__ = [
291
319
  "TagsUser",
292
320
  "TagsUser",
293
321
  "Task",
322
+ "TaskActivity",
323
+ "TaskActivityOptions",
324
+ "TaskActivityWebhook",
294
325
  "TaskData",
295
326
  "TaskData",
296
327
  "TaskFilter",
@@ -305,15 +336,16 @@ __all__ = [
305
336
  "TrainingStats",
306
337
  "TutorialFlags",
307
338
  "UltimateGearSetsAchievments",
339
+ "UserActivity",
340
+ "UserActivityOptions",
341
+ "UserActivityWebhook",
308
342
  "UserAnonymizedData",
309
343
  "UserAnonymizedData",
310
344
  "UserData",
311
345
  "UserData",
312
346
  "UserTasks",
313
347
  "UserTasks",
314
- "WebhooksOptions",
315
- "WebhooksType",
316
- "WebhooksUser",
348
+ "WebhookType",
317
349
  "__version__",
318
350
  "deserialize_task",
319
351
  "extract_avatar",
habiticalib/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants for Habiticalib."""
2
2
 
3
- __version__ = "0.3.7rc1"
3
+ __version__ = "0.4.0rc1"
4
4
 
5
5
  DEFAULT_URL = "https://habitica.com/"
6
6
  ASSETS_URL = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/"
habiticalib/lib.py CHANGED
@@ -7,10 +7,9 @@ from http import HTTPStatus
7
7
  from io import BytesIO
8
8
  import logging
9
9
  from operator import add
10
- from typing import IO, TYPE_CHECKING, Any, Self
10
+ from typing import IO, TYPE_CHECKING, Self
11
11
 
12
12
  from aiohttp import ClientError, ClientResponseError, ClientSession
13
- from habitipy.aio import HabitipyAsync # type: ignore[import-untyped]
14
13
  from PIL import Image
15
14
  from yarl import URL
16
15
 
@@ -38,13 +37,18 @@ from .typedefs import (
38
37
  Attributes,
39
38
  Avatar,
40
39
  Direction,
40
+ GlobalActivity,
41
+ GroupChatReceived,
41
42
  HabiticaCastSkillResponse,
42
43
  HabiticaClass,
43
44
  HabiticaClassSystemResponse,
44
45
  HabiticaContentResponse,
46
+ HabiticaDeleteWebhookResponse,
45
47
  HabiticaErrorResponse,
46
48
  HabiticaGroupMembersResponse,
49
+ HabiticaGroupsResponse,
47
50
  HabiticaLoginResponse,
51
+ HabiticaMessageResponse,
48
52
  HabiticaQuestResponse,
49
53
  HabiticaResponse,
50
54
  HabiticaScoreResponse,
@@ -58,10 +62,14 @@ from .typedefs import (
58
62
  HabiticaUserAnonymizedResponse,
59
63
  HabiticaUserExport,
60
64
  HabiticaUserResponse,
65
+ HabiticaWebhookResponse,
61
66
  Language,
67
+ QuestActivity,
62
68
  Skill,
63
69
  Task,
70
+ TaskActivity,
64
71
  TaskFilter,
72
+ UserActivity,
65
73
  )
66
74
 
67
75
  if TYPE_CHECKING:
@@ -2044,32 +2052,191 @@ class Habitica:
2044
2052
 
2045
2053
  return avatar
2046
2054
 
2047
- async def habitipy(self) -> HabitipyAsync:
2048
- """Create a Habitipy instance."""
2055
+ async def create_webhook(
2056
+ self,
2057
+ webhook: TaskActivity
2058
+ | GroupChatReceived
2059
+ | UserActivity
2060
+ | QuestActivity
2061
+ | GlobalActivity,
2062
+ ) -> HabiticaWebhookResponse:
2063
+ """Create a new webhook.
2049
2064
 
2050
- _session = self._session
2051
- _headers = self._headers
2052
- loop = asyncio.get_running_loop()
2065
+ Parameters
2066
+ ----------
2067
+ webhook : TaskActivity or GroupChatReceived or UserActivity or QuestActivity or GlobalActivity
2068
+ The webhook object to be created. It should be an instance of one of the following types:
2069
+ - TaskActivity
2070
+ - GroupChatReceived
2071
+ - UserActivity
2072
+ - QuestActivity
2073
+ - GlobalActivity
2053
2074
 
2054
- class HAHabitipyAsync(HabitipyAsync):
2055
- """Closure API class to hold session."""
2075
+ Returns
2076
+ -------
2077
+ HabiticaWebhookResponse
2078
+ A response object containing the created webhook.
2056
2079
 
2057
- def __call__(self, **kwargs) -> Any:
2058
- """Pass session to habitipy."""
2059
- return super().__call__(_session, **kwargs)
2080
+ Raises
2081
+ ------
2082
+ BadRequestError
2083
+ A parameter did not pass validation.
2060
2084
 
2061
- def _make_headers(self) -> dict[str, str]:
2062
- """Inject headers."""
2063
- headers = super()._make_headers()
2064
- headers.update(_headers)
2065
- return headers
2085
+ """
2066
2086
 
2067
- return await loop.run_in_executor(
2068
- None,
2069
- HAHabitipyAsync,
2070
- {
2071
- "url": str(self.url),
2072
- "login": self._headers.get("X-API-USER"),
2073
- "password": self._headers.get("X-API-KEY"),
2074
- }, # type: ignore[var-annotated]
2087
+ url = self.url / "api/v3/user/webhook"
2088
+
2089
+ return HabiticaWebhookResponse.from_json(
2090
+ await self._request("post", url=url, json=webhook.to_dict(omit_none=True))
2091
+ )
2092
+
2093
+ async def delete_webhook(
2094
+ self, webhook_id: str | UUID
2095
+ ) -> HabiticaDeleteWebhookResponse:
2096
+ """Delete a webhook by its UUID.
2097
+
2098
+ Parameters
2099
+ ----------
2100
+ webhook_id : str or UUID
2101
+ The UUID identifier of the webhook to delete.
2102
+
2103
+ Returns
2104
+ -------
2105
+ HabiticaDeleteWebhookResponse
2106
+ A response object containing a list of the remaining webhooks.
2107
+
2108
+ Raises
2109
+ ------
2110
+ NotFoundError
2111
+ The specified webhook could not be found.
2112
+ """
2113
+ url = self.url / "api/v3/user/webhook" / str(webhook_id)
2114
+
2115
+ return HabiticaDeleteWebhookResponse.from_json(
2116
+ await self._request("delete", url)
2117
+ )
2118
+
2119
+ async def update_webhook(
2120
+ self,
2121
+ webhook: TaskActivity
2122
+ | GroupChatReceived
2123
+ | UserActivity
2124
+ | QuestActivity
2125
+ | GlobalActivity,
2126
+ ) -> HabiticaWebhookResponse:
2127
+ """Update a webhook by its UUID with the provided data.
2128
+
2129
+ Parameters
2130
+ ----------
2131
+ webhook : TaskActivity or GroupChatReceived or UserActivity or QuestActivity or GlobalActivity
2132
+ The webhook data to be updated. It must be an instance of one of the specified types.
2133
+
2134
+ Returns
2135
+ -------
2136
+ HabiticaWebhookResponse
2137
+ The response object containing the updated webhook.
2138
+
2139
+
2140
+ Raises
2141
+ ------
2142
+ ValueError
2143
+ If the identifier was not provided.
2144
+ BadRequestError
2145
+ A parameter did not pass validation.
2146
+
2147
+ """
2148
+ if not webhook.id:
2149
+ msg = "You must provide the identifier of the webhook to update."
2150
+ raise ValueError(msg)
2151
+
2152
+ url = self.url / "api/v3/user/webhook" / str(webhook.id)
2153
+
2154
+ return HabiticaWebhookResponse.from_json(
2155
+ await self._request("put", url, json=webhook.to_dict(omit_none=True))
2156
+ )
2157
+
2158
+ async def get_group(self, group_id: UUID | None = None) -> HabiticaGroupsResponse:
2159
+ """
2160
+ Retrieve a user's group or party information.
2161
+
2162
+ Parameters
2163
+ ----------
2164
+ group_id : UUID or None, optional
2165
+ The unique identifier of the group to retrieve. If not provided,
2166
+ the user's party information will be retrieved instead.
2167
+
2168
+ Returns
2169
+ -------
2170
+ HabiticaGroupsResponse
2171
+ An object representing the response containing the group or party details.
2172
+ """
2173
+
2174
+ url = self.url / "api/v3/groups" / (str(group_id) if group_id else "party")
2175
+
2176
+ return HabiticaGroupsResponse.from_json(await self._request("get", url))
2177
+
2178
+ async def send_group_message(
2179
+ self, message: str, group_id: UUID | None = None
2180
+ ) -> HabiticaMessageResponse:
2181
+ """Send a message to a specific group.
2182
+
2183
+ Parameters
2184
+ ----------
2185
+ message : str
2186
+ The content of the message to be sent.
2187
+ group_id : UUID
2188
+ The unique identifier of the group to send the message to.
2189
+ If not provided, the user's party will be used.
2190
+
2191
+ Returns
2192
+ -------
2193
+ HabiticaMessageResponse
2194
+ An object representing the response containing the sent message details.
2195
+
2196
+ Raises
2197
+ ------
2198
+ NotAuthorizedError
2199
+ If the user is not authorized to send messages to the specified group
2200
+ because the chat privileges have been revoked.
2201
+ NotFoundError
2202
+ If the specified group could not be found.
2203
+ """
2204
+ url = (
2205
+ self.url
2206
+ / "api/v3/groups"
2207
+ / (str(group_id) if group_id else "party")
2208
+ / "chat"
2209
+ )
2210
+ return HabiticaMessageResponse.from_json(
2211
+ await self._request("post", url, json={"message": message})
2212
+ )
2213
+
2214
+ async def send_private_message(
2215
+ self, message: str, to_user_id: UUID
2216
+ ) -> HabiticaMessageResponse:
2217
+ """Send a private message to a specific user.
2218
+
2219
+ Parameters
2220
+ ----------
2221
+ message : str
2222
+ The content of the private message to be sent.
2223
+ to_user_id : UUID
2224
+ The unique identifier of the user to send the message to.
2225
+
2226
+ Returns
2227
+ -------
2228
+ HabiticaMessageResponse
2229
+ An object representing the response containing the sent message details.
2230
+
2231
+ Raises
2232
+ ------
2233
+ NotFoundError
2234
+ If the specified user could not be found.
2235
+ """
2236
+ url = self.url / "api/v3/members/send-private-message"
2237
+
2238
+ return HabiticaMessageResponse.from_json(
2239
+ await self._request(
2240
+ "post", url, json={"message": message, "toUserId": str(to_user_id)}
2241
+ )
2075
2242
  )
habiticalib/typedefs.py CHANGED
@@ -7,12 +7,13 @@ from dataclasses import dataclass, field
7
7
  import datetime as dt
8
8
  from datetime import UTC, datetime
9
9
  from enum import Enum, StrEnum
10
- from typing import Any, NotRequired, TypedDict
10
+ from typing import Annotated, Any, NotRequired, TypedDict
11
11
  from uuid import UUID
12
12
 
13
13
  from mashumaro import field_options
14
14
  from mashumaro.config import TO_DICT_ADD_OMIT_NONE_FLAG
15
15
  from mashumaro.mixins.orjson import DataClassORJSONMixin
16
+ from mashumaro.types import Discriminator
16
17
 
17
18
 
18
19
  def serialize_datetime(date: str | int | None) -> datetime | None:
@@ -558,6 +559,9 @@ class QuestParty(BaseModel):
558
559
  RSVPNeeded: bool | None = None
559
560
  key: str | None = None
560
561
  completed: str | None = None
562
+ active: bool | None = None
563
+ leader: UUID | None = None
564
+ members: dict[UUID, bool] = field(default_factory=dict)
561
565
 
562
566
 
563
567
  @dataclass(kw_only=True)
@@ -776,48 +780,187 @@ class PushDevicesUser(BaseModel):
776
780
  updatedAt: datetime
777
781
 
778
782
 
779
- class WebhooksType(StrEnum):
783
+ class WebhookType(StrEnum):
780
784
  """Webhook types."""
781
785
 
782
786
  TASK_ACTIVITY = "taskActivity"
783
787
  USER_ACTIVITY = "userActivity"
784
788
  QUEST_ACTIVITY = "questActivity"
785
789
  GROUP_CHAT_RECEIVED = "groupChatReceived"
790
+ GLOBAL_ACTIVITY = "globalActivity"
786
791
 
787
792
 
788
793
  @dataclass(kw_only=True)
789
- class WebhooksOptions(BaseModel):
790
- """Webhooks options data."""
794
+ class QuestActivityOptions(BaseModel):
795
+ """Quest activity options."""
791
796
 
792
- created: bool | None = None
793
- updated: bool | None = None
794
- deleted: bool | None = None
795
- scored: bool | None = None
796
- questStarted: bool | None = None
797
- questFinished: bool | None = None
798
- questInvited: bool | None = None
799
- petHatched: bool | None = None
800
- mountRaised: bool | None = None
801
- leveledUp: bool | None = None
802
- groupId: UUID | None = None
797
+ questStarted: bool = False
798
+ questFinished: bool = False
799
+ questInvited: bool = False
803
800
 
804
801
 
805
802
  @dataclass(kw_only=True)
806
- class WebhooksUser(BaseModel):
807
- """Webhooks user data."""
803
+ class UserActivityOptions(BaseModel):
804
+ """User activity options."""
805
+
806
+ petHatched: bool = False
807
+ mountRaised: bool = False
808
+ leveledUp: bool = False
809
+
810
+
811
+ @dataclass
812
+ class GroupChatReceivedOptions(BaseModel):
813
+ """Group chat received options."""
814
+
815
+ groupId: UUID
808
816
 
817
+
818
+ @dataclass(kw_only=True)
819
+ class TaskActivityOptions(BaseModel):
820
+ """Task activity options."""
821
+
822
+ created: bool = False
823
+ updated: bool = False
824
+ deleted: bool = False
825
+ checklistScored: bool = False
826
+ scored: bool = True
827
+
828
+
829
+ @dataclass(kw_only=True)
830
+ class Webhook(BaseModel):
831
+ """Webhook base class."""
832
+
833
+ url: str | None = field(default=None, kw_only=False)
834
+ enabled: bool | None = None
835
+ label: str | None = None
809
836
  id: UUID | None = None
810
- Type: WebhooksType = WebhooksType.TASK_ACTIVITY
811
- url: str | None = None
812
- enabled: bool = True
837
+
838
+
839
+ @dataclass(kw_only=True)
840
+ class TaskActivity(Webhook):
841
+ """Task activity."""
842
+
843
+ Type: WebhookType = field(default=WebhookType.TASK_ACTIVITY, init=False)
844
+ options: TaskActivityOptions = field(default_factory=TaskActivityOptions)
845
+
846
+
847
+ @dataclass(kw_only=True)
848
+ class GroupChatReceived(Webhook):
849
+ """Group chat received."""
850
+
851
+ def __post_init__(self) -> None:
852
+ """Initialize the GroupChatReceived class."""
853
+ if self.groupId:
854
+ if not isinstance(self.groupId, UUID):
855
+ self.groupId = UUID(self.groupId)
856
+
857
+ self.options = GroupChatReceivedOptions(groupId=self.groupId)
858
+ self.groupId = None
859
+
860
+ groupId: UUID | str | None = field(default=None, kw_only=False)
861
+ Type: WebhookType = field(default=WebhookType.GROUP_CHAT_RECEIVED, init=False)
862
+ options: GroupChatReceivedOptions = field(init=False)
863
+
864
+
865
+ @dataclass(kw_only=True)
866
+ class UserActivity(Webhook):
867
+ """User activity."""
868
+
869
+ Type: WebhookType = field(default=WebhookType.USER_ACTIVITY, init=False)
870
+ options: UserActivityOptions = field(default_factory=UserActivityOptions)
871
+
872
+
873
+ @dataclass(kw_only=True)
874
+ class QuestActivity(Webhook):
875
+ """Quest activity."""
876
+
877
+ Type: WebhookType = field(default=WebhookType.QUEST_ACTIVITY, init=False)
878
+ options: QuestActivityOptions = field(default_factory=QuestActivityOptions)
879
+
880
+
881
+ @dataclass(kw_only=True)
882
+ class GlobalActivity(Webhook):
883
+ """Global activity.
884
+
885
+ Note: global webhooks send a request for every type of event
886
+ """
887
+
888
+ Type: WebhookType = field(default=WebhookType.GLOBAL_ACTIVITY, init=False)
889
+
890
+
891
+ class HabiticaWebhookResponse(HabiticaResponse):
892
+ """Representation of a webhook data response."""
893
+
894
+ data: Annotated[
895
+ Webhook,
896
+ Discriminator(
897
+ field="type",
898
+ include_subtypes=True,
899
+ ),
900
+ ]
901
+
902
+
903
+ class HabiticaDeleteWebhookResponse(HabiticaResponse):
904
+ """Representation of a delete webhook response."""
905
+
906
+ data: list[
907
+ Annotated[
908
+ Webhook,
909
+ Discriminator(
910
+ field="type",
911
+ include_subtypes=True,
912
+ ),
913
+ ]
914
+ ]
915
+
916
+
917
+ @dataclass(kw_only=True)
918
+ class WebhookUser(BaseModel):
919
+ """Webhooks user data."""
920
+
813
921
  failures: int = 0
814
- label: str = ""
815
- options = WebhooksOptions
816
922
  lastFailureAt: datetime | None = None
817
923
  createdAt: datetime | None = None
818
924
  updatedAt: datetime | None = None
819
925
 
820
926
 
927
+ @dataclass(kw_only=True)
928
+ class TaskActivityWebhook(WebhookUser, TaskActivity):
929
+ """Task activity webhook."""
930
+
931
+ type = "taskActivity"
932
+
933
+
934
+ @dataclass(kw_only=True)
935
+ class QuestActivityWebhook(WebhookUser, QuestActivity):
936
+ """Quest activity webhook."""
937
+
938
+ type = "questActivity"
939
+
940
+
941
+ @dataclass(kw_only=True)
942
+ class GlobalActivityWebhook(WebhookUser, GlobalActivity):
943
+ """Global activity webhook."""
944
+
945
+ type = "globalActivity"
946
+
947
+
948
+ @dataclass(kw_only=True)
949
+ class GroupChatReceivedWebhook(WebhookUser, GroupChatReceived):
950
+ """Group chat received webhook."""
951
+
952
+ type = "groupChatReceived"
953
+ groupId: None = None
954
+ options: GroupChatReceivedOptions = field(init=True)
955
+
956
+
957
+ @dataclass(kw_only=True)
958
+ class UserActivityWebhook(WebhookUser, UserActivity):
959
+ """User activity webhook."""
960
+
961
+ type = "userActivity"
962
+
963
+
821
964
  @dataclass(kw_only=True)
822
965
  class PinnedItemsUser(BaseModel):
823
966
  """PinnedItems user data."""
@@ -851,7 +994,15 @@ class UserData(Avatar, BaseModel):
851
994
  tasksOrder: TasksOrderUser = field(default_factory=TasksOrderUser)
852
995
  extra: dict = field(default_factory=dict)
853
996
  pushDevices: list[PushDevicesUser] = field(default_factory=list)
854
- webhooks: list[WebhooksUser] = field(default_factory=list)
997
+ webhooks: list[
998
+ Annotated[
999
+ Webhook,
1000
+ Discriminator(
1001
+ field="type",
1002
+ include_subtypes=True,
1003
+ ),
1004
+ ]
1005
+ ] = field(default_factory=list)
855
1006
  loginIncentives: int | None = None
856
1007
  invitesSent: int | None = None
857
1008
  pinnedItems: list[PinnedItemsUser] = field(default_factory=list)
@@ -1473,7 +1624,7 @@ class ItemListContent(BaseModel):
1473
1624
  bundles: ItemListEntry
1474
1625
 
1475
1626
 
1476
- @dataclass
1627
+ @dataclass(kw_only=True)
1477
1628
  class GearEntry(BaseModel):
1478
1629
  """GearEntry content data."""
1479
1630
 
@@ -1619,7 +1770,7 @@ class PetEntry(BaseModel):
1619
1770
  text: str | None = None
1620
1771
 
1621
1772
 
1622
- @dataclass
1773
+ @dataclass(kw_only=True)
1623
1774
  class InventoryItemEntry(BaseModel):
1624
1775
  """Inventory item content data."""
1625
1776
 
@@ -1631,6 +1782,36 @@ class InventoryItemEntry(BaseModel):
1631
1782
  key: str | None = None
1632
1783
  notes: str | None = None
1633
1784
  canDrop: bool | None = None
1785
+ sellWarningNote: str | None = None
1786
+
1787
+
1788
+ @dataclass(kw_only=True)
1789
+ class Achievment(BaseModel):
1790
+ """An achievment."""
1791
+
1792
+ icon: str
1793
+ titleKey: str
1794
+ textKey: str
1795
+ key: str
1796
+ text2Key: str | None = None
1797
+ notificationText: str | None = None
1798
+ singularTitleKey: str | None = None
1799
+ singularTextKey: str | None = None
1800
+ pluralTitleKey: str | None = None
1801
+ pluralTextKey: str | None = None
1802
+ modalTextKey: str | None = None
1803
+
1804
+
1805
+ @dataclass(kw_only=True)
1806
+ class Incentive(BaseModel):
1807
+ """A login incentive."""
1808
+
1809
+ rewardKey: list[str] = field(default_factory=list)
1810
+ nextRewardAt: int = 500
1811
+ prevRewardKey: int = 0
1812
+ reward: list[QuestsContent | GearEntry | InventoryItemEntry | Achievment] = field(
1813
+ default_factory=list
1814
+ )
1634
1815
 
1635
1816
 
1636
1817
  @dataclass
@@ -1688,7 +1869,7 @@ class ContentData(BaseModel):
1688
1869
  # tasksByCategory
1689
1870
  # userDefaultsMobile
1690
1871
  # faq
1691
- # loginIncentives
1872
+ loginIncentives: dict[str, Incentive]
1692
1873
 
1693
1874
 
1694
1875
  @dataclass
@@ -1722,3 +1903,112 @@ class HabiticaCastSkillResponse(HabiticaResponse):
1722
1903
  """Representation of a cast skill response."""
1723
1904
 
1724
1905
  data: UserTasks
1906
+
1907
+
1908
+ class GroupPrivacy(StrEnum):
1909
+ """Group privacy."""
1910
+
1911
+ PRIVATE = "private"
1912
+ PUBLIC = "public"
1913
+
1914
+
1915
+ class GroupType(StrEnum):
1916
+ """Group type."""
1917
+
1918
+ GUILD = "guild"
1919
+ PARTY = "party"
1920
+
1921
+
1922
+ @dataclass(kw_only=True)
1923
+ class LeaderOnly(BaseModel):
1924
+ """Group leaderOnly data."""
1925
+
1926
+ challenges: bool
1927
+ getGems: bool
1928
+
1929
+
1930
+ @dataclass(kw_only=True)
1931
+ class GroupLeader(BaseModel):
1932
+ """Group leader data."""
1933
+
1934
+ id: UUID
1935
+ auth: AuthUser
1936
+ profile: ProfileUser
1937
+
1938
+
1939
+ @dataclass(kw_only=True)
1940
+ class ChatMsgInfo(BaseModel):
1941
+ """Chat message info."""
1942
+
1943
+ type: str | None = None
1944
+ user: str | None = None
1945
+ quest: str | None = None
1946
+ items: dict[str, int] | None = None
1947
+
1948
+
1949
+ @dataclass(kw_only=True)
1950
+ class ChatMsg(BaseModel):
1951
+ """Chat message."""
1952
+
1953
+ id: UUID
1954
+ flagCount: int
1955
+ text: str
1956
+ unformattedText: str
1957
+ info: ChatMsgInfo
1958
+ timestamp: datetime = field(
1959
+ metadata=field_options(
1960
+ deserialize=serialize_datetime,
1961
+ )
1962
+ )
1963
+ likes: dict[UUID, bool]
1964
+ client: str | None = None
1965
+ uuid: UUID | str
1966
+ groupId: UUID | None = None
1967
+ user: str | None = None
1968
+ username: str | None = None
1969
+ userStyles: Avatar | None = None
1970
+ sent: bool | None = None
1971
+ ownerId: UUID | None = None
1972
+ uniqueMessageId: UUID | None = None
1973
+
1974
+
1975
+ @dataclass(kw_only=True)
1976
+ class GroupData(BaseModel):
1977
+ """Groups data."""
1978
+
1979
+ name: str
1980
+ summary: str = ""
1981
+ description: str = ""
1982
+ leader: GroupLeader
1983
+ type: GroupType
1984
+ privacy: GroupPrivacy
1985
+ chat: list[ChatMsg]
1986
+ leaderOnly: LeaderOnly
1987
+ memberCount: int = 1
1988
+ ChallengeCount: int = 0
1989
+ chatLimitCount: int | None = None
1990
+ balance: float
1991
+ logo: str | None = None
1992
+ leaderMessage: str | None = None
1993
+ quest: QuestParty
1994
+
1995
+
1996
+ @dataclass
1997
+ class HabiticaGroupsResponse(HabiticaResponse):
1998
+ """Representation of a groups response."""
1999
+
2000
+ data: GroupData
2001
+
2002
+
2003
+ @dataclass(kw_only=True)
2004
+ class MessageData(BaseModel):
2005
+ """Message data."""
2006
+
2007
+ message: ChatMsg
2008
+
2009
+
2010
+ @dataclass(kw_only=True)
2011
+ class HabiticaMessageResponse(HabiticaResponse):
2012
+ """Representation of a group response."""
2013
+
2014
+ data: MessageData
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Habiticalib
3
- Version: 0.3.7rc1
3
+ Version: 0.4.0rc1
4
4
  Summary: Asynchronous Python client library for the Habitica API
5
5
  Project-URL: Documentation, https://tr4nt0r.github.io/habiticalib/
6
6
  Project-URL: Source, https://github.com/tr4nt0r/habiticalib
@@ -12,7 +12,6 @@ Classifier: Operating System :: OS Independent
12
12
  Classifier: Programming Language :: Python :: 3 :: Only
13
13
  Requires-Python: >=3.12
14
14
  Requires-Dist: aiohttp~=3.9
15
- Requires-Dist: habitipy~=0.3.3
16
15
  Requires-Dist: mashumaro~=3.13
17
16
  Requires-Dist: orjson~=3.10
18
17
  Requires-Dist: pillow~=11.0
@@ -0,0 +1,12 @@
1
+ habiticalib/__init__.py,sha256=Wi3afcd5PdiXEXvP0dXA2oOAD08VgIr6GuA0xKGjMuY,7808
2
+ habiticalib/const.py,sha256=-5Siu34sK3R8Gf84EMIiLmij_0JqgNz4Eq0FUeJxS8I,2311
3
+ habiticalib/exceptions.py,sha256=i9hnCaMT5RbnTioFhwRYJkcC_bG9lMeUd2jJsWFVnVg,1342
4
+ habiticalib/ha.py,sha256=rSzrs7ixLJH3ZtOFlcuKV2t1ZndT0VpuPhDsGqorkOs,20757
5
+ habiticalib/helpers.py,sha256=lq2HBvqLsFo5_zckMnc7hzDsHLfyrcStpFUpet3ZuZY,4500
6
+ habiticalib/lib.py,sha256=DUMdqia-w4AAPdf8bAX2g9PXq0HgPocYy-E1-cFXV7g,78503
7
+ habiticalib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ habiticalib/typedefs.py,sha256=waQV2SfIJVBdjdfaARUfyVJNjXA2KSTX9A81MlsJPiA,50887
9
+ habiticalib-0.4.0rc1.dist-info/METADATA,sha256=hylhqV2zQH-ATtsUZJWbnVKkXG6DHmSGcCs4ryHDN8w,4179
10
+ habiticalib-0.4.0rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ habiticalib-0.4.0rc1.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
12
+ habiticalib-0.4.0rc1.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- habiticalib/__init__.py,sha256=ZUd6heFQJaJgNiseoSY2SfJzOHfGFdIiOHI-qf9fXuU,6940
2
- habiticalib/const.py,sha256=H2LnnOkR3qBIO9rGhndJiFtXwO-FdThjoTt3DkIzqsM,2311
3
- habiticalib/exceptions.py,sha256=i9hnCaMT5RbnTioFhwRYJkcC_bG9lMeUd2jJsWFVnVg,1342
4
- habiticalib/ha.py,sha256=rSzrs7ixLJH3ZtOFlcuKV2t1ZndT0VpuPhDsGqorkOs,20757
5
- habiticalib/helpers.py,sha256=lq2HBvqLsFo5_zckMnc7hzDsHLfyrcStpFUpet3ZuZY,4500
6
- habiticalib/lib.py,sha256=K6KwRBw_bq9wyXb5PJcZVlN2kF6zXiPm11Hk4XVHfqE,73598
7
- habiticalib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- habiticalib/typedefs.py,sha256=984f8IawG-L8XTinsNDmaiSJkgfIJk-vHBI44qRySNE,44343
9
- habiticalib-0.3.7rc1.dist-info/METADATA,sha256=pW_rpLjd26SZc6VSce_SK-MeAmquhVtwg69GEvGjfkQ,4210
10
- habiticalib-0.3.7rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- habiticalib-0.3.7rc1.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
12
- habiticalib-0.3.7rc1.dist-info/RECORD,,