Habiticalib 0.3.7rc0__py3-none-any.whl → 0.4.0__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,23 @@ from .typedefs import (
46
46
  GearItems,
47
47
  GearItemsAvatar,
48
48
  GearType,
49
+ GlobalActivity,
50
+ GlobalActivityWebhook,
51
+ GroupChatReceived,
52
+ GroupChatReceivedOptions,
53
+ GroupChatReceivedWebhook,
54
+ GroupData,
49
55
  GroupTask,
50
56
  HabiticaCastSkillResponse,
51
57
  HabiticaClass,
52
58
  HabiticaClassSystemResponse,
53
59
  HabiticaContentResponse,
60
+ HabiticaDeleteWebhookResponse,
54
61
  HabiticaErrorResponse,
55
62
  HabiticaGroupMembersResponse,
63
+ HabiticaGroupsResponse,
56
64
  HabiticaLoginResponse,
65
+ HabiticaMessageResponse,
57
66
  HabiticaQuestResponse,
58
67
  HabiticaResponse,
59
68
  HabiticaScoreResponse,
@@ -67,6 +76,7 @@ from .typedefs import (
67
76
  HabiticaUserAnonymizedResponse,
68
77
  HabiticaUserExport,
69
78
  HabiticaUserResponse,
79
+ HabiticaWebhookResponse,
70
80
  HairPreferences,
71
81
  HatchingPotionEntry,
72
82
  HistoryUser,
@@ -98,6 +108,9 @@ from .typedefs import (
98
108
  PurchasedUser,
99
109
  PushDevicesUser,
100
110
  PushNotificationsPreferences,
111
+ QuestActivity,
112
+ QuestActivityOptions,
113
+ QuestActivityWebhook,
101
114
  QuestBoss,
102
115
  QuestBossRage,
103
116
  QuestCollect,
@@ -123,6 +136,9 @@ from .typedefs import (
123
136
  SuppressModalsPreferences,
124
137
  TagsUser,
125
138
  Task,
139
+ TaskActivity,
140
+ TaskActivityOptions,
141
+ TaskActivityWebhook,
126
142
  TaskData,
127
143
  TaskFilter,
128
144
  TaskPriority,
@@ -135,12 +151,13 @@ from .typedefs import (
135
151
  TrainingStats,
136
152
  TutorialFlags,
137
153
  UltimateGearSetsAchievments,
154
+ UserActivity,
155
+ UserActivityOptions,
156
+ UserActivityWebhook,
138
157
  UserAnonymizedData,
139
158
  UserData,
140
159
  UserTasks,
141
- WebhooksOptions,
142
- WebhooksType,
143
- WebhooksUser,
160
+ WebhookType,
144
161
  )
145
162
 
146
163
  __all__ = [
@@ -185,6 +202,12 @@ __all__ = [
185
202
  "GearItems",
186
203
  "GearItemsAvatar",
187
204
  "GearType",
205
+ "GlobalActivity",
206
+ "GlobalActivityWebhook",
207
+ "GroupChatReceived",
208
+ "GroupChatReceivedOptions",
209
+ "GroupChatReceivedWebhook",
210
+ "GroupData",
188
211
  "GroupTask",
189
212
  "Habitica",
190
213
  "HabiticaCastSkillResponse",
@@ -194,13 +217,16 @@ __all__ = [
194
217
  "HabiticaClassSystemResponse",
195
218
  "HabiticaContentResponse",
196
219
  "HabiticaContentResponse",
220
+ "HabiticaDeleteWebhookResponse",
197
221
  "HabiticaErrorResponse",
198
222
  "HabiticaErrorResponse",
199
223
  "HabiticaException",
200
224
  "HabiticaGroupMembersResponse",
201
225
  "HabiticaGroupMembersResponse",
226
+ "HabiticaGroupsResponse",
202
227
  "HabiticaLoginResponse",
203
228
  "HabiticaLoginResponse",
229
+ "HabiticaMessageResponse",
204
230
  "HabiticaQuestResponse",
205
231
  "HabiticaQuestResponse",
206
232
  "HabiticaResponse",
@@ -227,6 +253,7 @@ __all__ = [
227
253
  "HabiticaUserExport",
228
254
  "HabiticaUserResponse",
229
255
  "HabiticaUserResponse",
256
+ "HabiticaWebhookResponse",
230
257
  "HairPreferences",
231
258
  "HatchingPotionEntry",
232
259
  "HistoryUser",
@@ -261,6 +288,9 @@ __all__ = [
261
288
  "PurchasedUser",
262
289
  "PushDevicesUser",
263
290
  "PushNotificationsPreferences",
291
+ "QuestActivity",
292
+ "QuestActivityOptions",
293
+ "QuestActivityWebhook",
264
294
  "QuestBoss",
265
295
  "QuestBossRage",
266
296
  "QuestCollect",
@@ -291,6 +321,9 @@ __all__ = [
291
321
  "TagsUser",
292
322
  "TagsUser",
293
323
  "Task",
324
+ "TaskActivity",
325
+ "TaskActivityOptions",
326
+ "TaskActivityWebhook",
294
327
  "TaskData",
295
328
  "TaskData",
296
329
  "TaskFilter",
@@ -305,15 +338,16 @@ __all__ = [
305
338
  "TrainingStats",
306
339
  "TutorialFlags",
307
340
  "UltimateGearSetsAchievments",
341
+ "UserActivity",
342
+ "UserActivityOptions",
343
+ "UserActivityWebhook",
308
344
  "UserAnonymizedData",
309
345
  "UserAnonymizedData",
310
346
  "UserData",
311
347
  "UserData",
312
348
  "UserTasks",
313
349
  "UserTasks",
314
- "WebhooksOptions",
315
- "WebhooksType",
316
- "WebhooksUser",
350
+ "WebhookType",
317
351
  "__version__",
318
352
  "deserialize_task",
319
353
  "extract_avatar",
habiticalib/const.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Constants for Habiticalib."""
2
2
 
3
- __version__ = "0.3.7rc0"
3
+ __version__ = "0.4.0"
4
4
 
5
5
  DEFAULT_URL = "https://habitica.com/"
6
6
  ASSETS_URL = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/"
habiticalib/ha.py CHANGED
@@ -9,3 +9,5 @@ ROGUE = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwM
9
9
  WIZARD = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSItMTIgLTEyIDcyIDcyIj4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZmlsbD0iIzFGNkVBMiIgZD0iTTI0LjQ2MiAxLjE1MWMtMy42OTUgMy43MTQtNy4zMjEgMTQuNjItOS4yMzYgMjAuOTEzLS44NC0xLjA2Mi0xLjc5OS0yLjA3Ni0zLjE1OC0zLjMyNi00LjgwNiAzLjUxNC03LjM1NyA3LjI1LTEwLjY0NiAxMS44MTYgOC45MTYgNy45MjYgMTEuMjMzIDkuMjU2IDIyLjk5NSAxNi4wMDVsLjA0NS0uMDI1aC4wMDFsLjA0NS4wMjVjMTEuNzYtNi43NDkgMTQuMDc5LTguMDggMjIuOTk0LTE2LjAwNS0zLjI4Ny00LjU2Ni01Ljg0MS04LjMwMi0xMC42NDUtMTEuODE2LTEuMzYxIDEuMjUtMi4zMTcgMi4yNjQtMy4xNTggMy4zMjYtMS45MTUtNi4yOTQtNS41NDMtMTcuMi05LjIzNi0yMC45MTNoLS4wMDF6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iIzI3OEFCRiIgZD0iTTI0LjQ2NCAzMi4xMDhsMy41NjEtMS4yNjVjNi4wNzUtLjYwNSA4LjQyNS0yLjI4MSA5LjQyNi0zLjQ5OGw2LjA1MyAyLjcwNy4wMDIuMDEzYS40NS40NSAwIDAgMS0uMTA1LjI4NiA0Ljk3IDQuOTcgMCAwIDEtLjMyLjMzYy0zLjQwNSAzLjMxNS0xOC4yMzcgMTEuOTgxLTE4LjYxNyAxMi4yMDJWMzIuMTA4eiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiM1M0I0RTUiIGQ9Ik0zNi40MDYgMjMuMDQxYy4yMy0uMTg4LjI5Mi0uMzQuNjc0LS4zMzYgMS4xODMuMDY3IDUuMTY5IDUuMTc1IDYuMDY0IDYuNDYxLjE5NC4yNzguMzY2LjYxLjM2Ljg4NWwtNi4wNTMtMi43MDdjLjIzNi0uMzY3LjE5LS45Mi0uMzU1LTEuMjUyLS44MTgtLjUwMS0yLjUyOS45NDktMi45NTkuMjg0LS41OTktLjkyNyAyLjA0LTMuMTQ3IDIuMjctMy4zMzUiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjMkFBMENGIiBkPSJNMjMuNTkxIDcuNDg3Yy01LjM5IDE1LjQxOS04LjIyNyAyMy44MTctOC4yMjcgMjMuODE3bDkuMDk3IDQuNzZWNi44MzljLS4zNiAwLS43MTguMjE2LS44Ny42NDgiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjMjc4QUJGIiBkPSJNMjUuMzMyIDcuNDg3Yy0uMTUyLS40MzItLjUxLS42NDgtLjg3LS42NDh2MjkuMjI1bDkuMDk3LTQuNzZzLTIuODM3LTguMzk4LTguMjI3LTIzLjgxNyIvPgogICAgICAgIDxwYXRoIGZpbGw9IiM0REIyRDYiIGQ9Ik0yNC40NjIgMzIuMTA4TDIwLjkgMzAuODQzYy02LjA3NS0uNjA1LTguMzQyLTIuMzUyLTkuNDI1LTMuNDk4TDUuNDIgMzAuMDUybC0uMDAyLjAxM2EuNDUuNDUgMCAwIDAgLjEwNi4yODZjLjA5LjEwNC4xOTcuMjE1LjMxOC4zMyAzLjQwNiAzLjMxNSAxOC4yMzggMTEuOTgxIDE4LjYxOSAxMi4yMDJWMzIuMTA4eiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiM2QkM0RTkiIGQ9Ik0xMi41MTkgMjMuMDQxYy0uMjMtLjE4OC0uMjkyLS4zNC0uNjc0LS4zMzYtMS4xODMuMDY3LTUuMTY5IDUuMTc1LTYuMDYzIDYuNDYxLS4xOTQuMjc4LS4zNjcuNjEtLjM2MS44ODVsNi4wNTMtMi43MDdjLS4yMzYtLjM2Ny0uMTktLjkyLjM1Ni0xLjI1Mi44MTctLjUwMSAyLjUyOC45NDkgMi45NTguMjg0LjYtLjkyNy0yLjAzOS0zLjE0Ny0yLjI3LTMuMzM1Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iI0E5REJGNiIgZD0iTTI0LjQ2MyAzNC45OTh2LTUuMTAxbC03LjIxLTQuMTMtMS40OCA0LjA0OXoiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjODRDRkYyIiBkPSJNMjQuNDYzIDM0Ljk5OHYtNS4xMDFsNy4yMDctNC4xMyAxLjQ4MyA0LjA0OXoiLz4KICAgIDwvZz4KPC9zdmc+"
10
10
  HEALER = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciICB2aWV3Qm94PSItMTIgLTEyIDcyIDcyIj4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPHBhdGggZmlsbD0iI0NGODIyOSIgZD0iTTI0LjYxIDQ3LjYwNHMtMS43ODktLjczNS0yLjU4NS0xLjEzOGwtLjE4My0uMDljLTUuMTMtMi41OC0xMC41NC01Ljc4Mi0xMy44ODEtMTIuMTA4LTMuNzc3LTcuMTUtMy4wNS0xOC41NjUtMi45NTUtMTkuODQzLjA3NS0xLjAwMy4zNzgtMy40NjQuMzc4LTMuNDY0czEuOTQxLS44NTggMi45MDEtMS4zMTFsMTMuODY0LTcuMDEyYy43NjQtLjM2MyAyLjQ2Mi0xLjExNCAyLjQ2Mi0xLjExNHMxLjY5Ny43NSAyLjQ2MyAxLjExNGwxMy44NiA3LjAxYy45NjYuNDU3IDMuMDUgMS4zMTUgMy4wNSAxLjMxNXMuMTU3IDIuNDY3LjIzMiAzLjQ2NWMuMDk0IDEuMjc1LjgyMiAxMi42OS0yLjk1NSAxOS44NC0zLjM0MyA2LjMzLTguNzU1IDkuNTMtMTMuODc2IDEyLjEwM2wtLjE5LjA5NmMtLjc5NS40MDItMi41ODQgMS4xMzctMi41ODQgMS4xMzciLz4KICAgICAgICA8cGF0aCBmaWxsPSIjRTI5RTQ1IiBkPSJNMTIuNjk0IDE2LjE0N2wxMS4wNTktNS42OTVjLjI3LS4xMjkuNTY0LS4xOTIuODU4LS4xOTJWNS44MjljLS4yOTQgMC0uNTg4LjA2My0uODU4LjE5Mkw5Ljg4OCAxMy4wMzJhMS45ODUgMS45ODUgMCAwIDAtLjcyNy42MDNsMy41MzMgMi41MjN2LS4wMTFNMjQuNjEyIDEwLjI1OVY1LjgyN3oiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjRkRDNjdFIiBkPSJNMjMuNzUyIDYuMDA4TDkuODkgMTMuMDJjLS42NTUuMzEtMS4wOS45NDUtMS4xNDUgMS42NjUtLjAzNC40NjYtLjgxIDExLjQ4NyAyLjUzMSAxNy44MTQgMi43ODIgNS4yNjYgNy4zNiA4LjA0OCAxMi4yNDIgMTAuNTA0bC4xOS4wOTZjLjI4NC4xNDIuNTkzLjIxMy45MDIuMjEzVjUuODE2Yy0uMjkzIDAtLjU4NS4wNjQtLjg1OC4xOTIiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjRkZBNjIzIiBkPSJNMjUuNTEyIDQzLjA5OWwuMTktLjA5NmM0Ljg4NS0yLjQ1NCA5LjQ2Mi01LjIzOCAxMi4yNDQtMTAuNTA1IDMuMzQxLTYuMzI2IDIuNTY1LTE3LjM0NyAyLjUzLTE3LjgxM2EyLjAwOSAyLjAwOSAwIDAgMC0xLjE0My0xLjY2NUwyNS40NjggNi4wMDhhMS45OTkgMS45OTkgMCAwIDAtLjg1OC0uMTkydjM3LjQ5NmMuMzEgMCAuNjE4LS4wNzEuOTAyLS4yMTMiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjRkZEREI1IiBkPSJNMTIuNjk0IDE2LjEzNGwxMS4wNTktNS42OTRjLjI3LS4xMjkuNTY0LS4xOTIuODU4LS4xOTJWNS44MTZjLS4yOTQgMC0uNTg3LjA2NC0uODU4LjE5Mkw5Ljg4OSAxMy4wMmExLjk4NSAxLjk4NSAwIDAgMC0uNzI4LjYwM2wzLjUzMyAyLjUyM3YtLjAxMiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiNGREM2N0UiIGQ9Ik0zOS4zMzMgMTMuMDJMMjUuNDY4IDYuMDA4YTEuOTk5IDEuOTk5IDAgMCAwLS44NTgtLjE5MnY0LjQzMWMuMjk0IDAgLjU4OC4wNjUuODU4LjE5MmwxMS4wNjUgNS43MDIgMy41MjctMi41MTlhMS45NzMgMS45NzMgMCAwIDAtLjcyNy0uNjAyIi8+CiAgICAgICAgPHBhdGggZmlsbD0iI0ZGQTYyMyIgZD0iTTI0LjIxNCAzOC44NThjLTQuMTk3LTIuMTI4LTcuMzgzLTQuNDM4LTkuMzg5LTguMjM1LTIuMjM5LTQuMjM4LTIuMjI5LTExLjYzLTIuMTMxLTE0LjQ3N0w5LjE2IDEzLjYyM2EyIDIgMCAwIDAtLjQxNyAxLjA2MmMtLjAxNS4yMDctLjE3NCAyLjQ5OC0uMDU3IDUuNTMxLjE0OCAzLjc5OC43MzEgOC43NjUgMi41OSAxMi4yODIgMi43ODIgNS4yNjcgNy4zNTcgOC4wNSAxMi4yNDIgMTAuNTA1bC4xOS4wOTZjLjI4NC4xNDIuNTkzLjIxMy45MDIuMjEzdi00LjMzYy0uMDk4IDAtLjE5Ny0uMDQtLjM5Ny0uMTI0Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iI0U1OTAyNSIgZD0iTTM0LjM5NSAzMC42MjNjLTIuMDA4IDMuODA0LTUuMjAzIDYuMTEzLTkuNDA2IDguMjQzLS4xODguMDc4LS4yODIuMTE3LS4zNzguMTE3djQuMzNjLjMxIDAgLjYxOC0uMDcyLjktLjIxNGwuMTktLjA5NmM0Ljg4NS0yLjQ1NSA5LjQ2Mi01LjIzOCAxMi4yNDQtMTAuNTA0IDEuODU3LTMuNTE4IDIuNDQzLTguNDg1IDIuNTktMTIuMjgyLjExOC0zLjAzNC0uMDQ0LTUuMzI1LS4wNi01LjUzMmExLjk5NSAxLjk5NSAwIDAgMC0uNDE0LTEuMDY0bC0zLjUyNyAyLjUyMWMuMTI5IDMuNTMtLjA3IDEwLjU2Ni0yLjEzOSAxNC40ODEiLz4KICAgICAgICA8cGF0aCBmaWxsPSIjRkZFNEM5IiBkPSJNMTYuMDc2IDI0LjU2NGw1LjY5LTIuODQ1IDIuODQ1IDIuODQ1ek0yNC42MSAzMy4wOThsLTIuODQ1LTUuNjg4IDIuODQ2LTIuODQ2eiIvPgogICAgICAgIDxwYXRoIGZpbGw9IiNFNTkwMjUiIGQ9Ik0zMy4xNDUgMjQuNTY0bC01LjY4OSAyLjg0Ni0yLjg0NS0yLjg0NnpNMjQuNjEgMTYuMDNsMi44NDYgNS42ODktMi44NDUgMi44NDV6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iI0U1OTAyNSIgZD0iTTMzLjE0NSAyNC41NjRsLTUuNjg5LTIuODQ1LTIuODQ1IDIuODQ1ek0yNC42MSAzMy4wOThsMi44NDYtNS42ODgtMi44NDUtMi44NDZ6Ii8+CiAgICAgICAgPHBhdGggZmlsbD0iI0ZGRTRDOSIgZD0iTTE2LjA3NiAyNC41NjRsNS42OSAyLjg0NiAyLjg0NS0yLjg0NnpNMjQuNjEgMTYuMDNsLTIuODQ1IDUuNjg5IDIuODQ2IDIuODQ1eiIvPgogICAgPC9nPgo8L3N2Zz4="
11
11
  FOOD = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNTgiIHZpZXdCb3g9IjAgMCA2MCA1OCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CjxyZWN0IHg9IjM4IiB5PSI2IiB3aWR0aD0iMjIiIGhlaWdodD0iMjYiIGZpbGw9InVybCgjcGF0dGVybjBfMTMyN18yNTYpIj48L3JlY3Q+CjxyZWN0IHdpZHRoPSIyNiIgaGVpZ2h0PSIyNiIgZmlsbD0idXJsKCNwYXR0ZXJuMV8xMzI3XzI1NikiPjwvcmVjdD4KPHJlY3QgeD0iOCIgeT0iMzYiIHdpZHRoPSIzMCIgaGVpZ2h0PSIyMiIgZmlsbD0idXJsKCNwYXR0ZXJuMl8xMzI3XzI1NikiPjwvcmVjdD4KPGRlZnM+CjxwYXR0ZXJuIGlkPSJwYXR0ZXJuMF8xMzI3XzI1NiIgcGF0dGVybkNvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHdpZHRoPSIxIiBoZWlnaHQ9IjEiPgo8dXNlIHhsaW5rOmhyZWY9IiNpbWFnZTBfMTMyN18yNTYiIHRyYW5zZm9ybT0ic2NhbGUoMC4wNDU0NTQ1IDAuMDM4NDYxNSkiPjwvdXNlPgo8L3BhdHRlcm4+CjxwYXR0ZXJuIGlkPSJwYXR0ZXJuMV8xMzI3XzI1NiIgcGF0dGVybkNvbnRlbnRVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIHdpZHRoPSIxIiBoZWlnaHQ9IjEiPgo8dXNlIHhsaW5rOmhyZWY9IiNpbWFnZTFfMTMyN18yNTYiIHRyYW5zZm9ybT0ic2NhbGUoMC4wMzg0NjE1KSI+PC91c2U+CjwvcGF0dGVybj4KPHBhdHRlcm4gaWQ9InBhdHRlcm4yXzEzMjdfMjU2IiBwYXR0ZXJuQ29udGVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgd2lkdGg9IjEiIGhlaWdodD0iMSI+Cjx1c2UgeGxpbms6aHJlZj0iI2ltYWdlMl8xMzI3XzI1NiIgdHJhbnNmb3JtPSJzY2FsZSgwLjAzMzMzMzMgMC4wNDU0NTQ1KSI+PC91c2U+CjwvcGF0dGVybj4KPGltYWdlIGlkPSJpbWFnZTBfMTMyN18yNTYiIHdpZHRoPSIyMiIgaGVpZ2h0PSIyNiIgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCWUFBQUFhQ0FZQUFBQ3pkcXhBQUFBQUFYTlNSMElBcnM0YzZRQUFBUWxKUkVGVVNBMjkwazFxd2xBVXhmRnNwK3NvWFlkem9lQWFXcUZiY1N4MTRMVFFTYnVBanJ1TFZnZFBudkFyY3NJalJsT0Z5OG45K3Q5alNOY04vQjd1N3N0cERJeWYzejZGMXVmek4yTXlRZnZmOTFMalo3czZSdlpqdlozbTR0Vmd3TjM2cTlUZ2tLclQ3K2VQVXNOZTA2b0JpNEJVblE2Q0UyaUJBcVhxVTV3LzV3b1dEVkwxVkgySzB3TWJBSGliZlpZYTZpMDFkenN3Nnk3bTUrVWZjTXhoUzNGd080WEp3SUNjNWVmRmFlcWc0NXVCMDVtODVWQ2R3ZDY3OVNxQVVnRmEyZ1FEV1RRb1Q4Mit2T2Q0Y3JBTEx0S3N6eDhYcFVhcmI3Nm5GcWdCK2NWZ29GVGdwK1ZMcVNIUHVkRTUwTCtCMTYrYlVzT2gwUTV6QVdoeXNFTU95Q2ZUc2VBRFNTQzNudTVpRmFjQUFBQUFTVVZPUks1Q1lJST0iPjwvaW1hZ2U+CjxpbWFnZSBpZD0iaW1hZ2UxXzEzMjdfMjU2IiB3aWR0aD0iMjYiIGhlaWdodD0iMjYiIHhsaW5rOmhyZWY9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQm9BQUFBYUNBWUFBQUNwU2t6T0FBQUFBWE5TUjBJQXJzNGM2UUFBQVNsSlJFRlVTQTNGMURGT3cwQVFCVkRUUmhTcDZSSFVhVkxRY0FXT0VDa05SNkhpUHRSY0psMUtxQlp0cEVmeGpiV3J4QTZXUmw4em52bC8vcTdsWVlqbmJuTmIvZ3B0K2U3NWZWMXFxT3Ryb29GRWcxay9XeWdKNzNjM3BRWUIrY1VDL3k2VVRqaDYyMjVMamQwd25NS2kzWmhITlpzUVlvaFl2djk0TERYVU9UbSt2cFFhWHc5UHAxQ2ZkSVFRSXBSZkxJUVFPbnZFTU92Nk9XazZNd0NUY0hZaFJ3UlR3QUtKN3VUNzgxQnFjS2orZTFlY0VJQ3pDeUdtdkZtdFNnMmJFN1JwYnE3UCs4bTd1cG9RSjVBalo1d2IyeHltZzNROCtjZTR1cENOYzhPV0EzT3c2VWpqNGtMdWlDQnNDYWZqcHFQRmhhYSt2bDVoanZYN3VQQ09VSU1CNkFnaDRzejE0eGtKWkVFamRPYUlXbWd1ZVVlNVJyaVlVQ29UN01XYzc4NTdCZlFoL2dGQ2FOUWFobDJ1M2dBQUFBQkpSVTVFcmtKZ2dnPT0iPjwvaW1hZ2U+CjxpbWFnZSBpZD0iaW1hZ2UyXzEzMjdfMjU2IiB3aWR0aD0iMzAiIGhlaWdodD0iMjIiIHhsaW5rOmhyZWY9ImRhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQjRBQUFBV0NBWUFBQURYWXl6UEFBQUFBWE5TUjBJQXJzNGM2UUFBQVJSSlJFRlVTQTNGMDhGdEFqRVVCRkNhZ0FZU0tkM1FBc1VnY1VrRHFTTzMxSkJqTHJuU0JsSms1TU9EMVdndDdSbzVJSDJOL2NlZStiUHNiamFEZjY4dmIyVmFnKzN1OGxQVHVyNHpLMWNwWko4eStoK0g3MUxMUHM4dDNoTklUQUY4dHpFQitQbHpLZFA2UGYrVld2akUwLzZyMUZvOVFBcE5UZXQ2dURIRDQvdTV6Qlhlb0ptME96SGhPZFBhd3o5c1RJQmdHbnJFeWV2dnR0dFNpMDVpdm95M3ZZTXBiQUFHeWVzL2JFeklmOFlJdGdZeCtDM0owb1dMdzR3WkpIcFVra2tzb1g0aW5sNHpxQU9KLzJic080TVNHa2d5aWZCUTMvbG1Vb1NERENGQi9IRGpOR1FNRFFDOWZIZ29XQk1kYkNYRlE0YXcyOWhFaEExZ2o0ZjZpZmpWU09ocHhnWllQWG52Qllhd1YyZnB2U3R4R0Z5dUlYV3NXUUFBQUFCSlJVNUVya0pnZ2c9PSI+PC9pbWFnZT4KPC9kZWZzPgo8L3N2Zz4="
12
+ DAMAGE = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSItMyAtMyAyMiAyMiI+CiAgICA8ZGVmcz4KICAgICAgICA8cGF0aCBpZD0iYSIgZD0iTTEwLjQ2NCAyLjkxN0w4LjIgNS4xOTd2Mi4wMmwyLjI2NC0yLjE3M1YyLjkxN3oiPjwvcGF0aD4KICAgIDwvZGVmcz4KICAgIDxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgdHJhbnNmb3JtPSJtYXRyaXgoLTEgMCAwIDEgMTYgLjMyKSI+CiAgICAgICAgPHBhdGggZmlsbD0iI0YwNjE2NiIgZD0iTTYuMTMgOS4yMDRsMi4xMTEuOTM0Yy4xNzYuMDc4LjI5LjIzNS4zMzMuNDE1LjA3My4zMDQuMjk1IDEuMDEuMzEzIDEuMzg2LjAxLjIxLS4yMTQuMzU2LS40MTQuMjdsLTMuNTI5LTEuNjIzYS41ODIuNTgyIDAgMCAxLS4yNTQtLjI0NEwzIDYuOTU1Yy0uMDktLjE5Mi4wNjMtLjQwNy4yODEtLjM5Ny4zOTEuMDE3IDEuMTEyLjIxOCAxLjQ0NC4zLjE4Ni4wNDUuMzUxLjE1LjQzMi4zMTlsLjk3MyAyLjAyN3oiPjwvcGF0aD4KICAgICAgICA8cGF0aCBmaWxsPSIjODc4MTkwIiBkPSJNMS4wMjQgMTQuMTA3bC45MS44NzUgMi4zNjMtLjE3OS4xMjEtMS40OSAxLjM1Ni0xLjMgMi40NjcgMS4xMjYgMS44NDYtLjQ3Ny0uNzc0LTMuMTk2IDUuMTcxLTQuNjMzLjk5LTQuNTk2aC0uMDAyVi4yMzVsLTQuNzg2Ljk1TDUuODYgNi4xNWwtMy4zMy0uNzQzLS40OTcgMS43NyAxLjE3NCAyLjM3LTEuMzU1IDEuMy0xLjU1Mi4xMTgtLjE4NiAyLjI2Ny45MS44NzV6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0YwNjE2NiIgZD0iTTIuOTc2IDEzLjM2NmwtMS4xODItMS4xMzQgMi45MjMtMi44MDUgMS4xOCAxLjEzNHoiPjwvcGF0aD4KICAgICAgICA8cGF0aCBmaWxsPSIjRjA2MTY2IiBkPSJNMS4xMjYgMTIuODc0bC4wODUtMS4wMzUgMS4wNzgtLjA4MiAxLjE4MiAxLjEzNS0uMDg1IDEuMDM1LTEuMDc4LjA4MnoiPjwvcGF0aD4KICAgICAgICA8cGF0aCBmaWxsPSIjRkZGIiBkPSJNMTEuMzEyIDIuMDg4bC4xIDIuMDQ2IDIuNzAyLTIuNTk1Yy0uMDUtLjA0NS0yLjA4Ni4xOC0yLjgwMi41NSI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNFREVDRUUiIGQ9Ik0xMS4yNjIgMi4xMTNMNS41NTMgNy44NjJsMS40NjMuNDkyIDQuMzk2LTQuMjItLjEtMi4wNDYtLjA1LjAyNU01LjU1MyA3Ljg2MmwtLjA1LjA1Mi42MjIgMS4yOTQuODktLjg1NC0xLjQ2Mi0uNDkyeiI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNFREVDRUUiIGQ9Ik0xMy41NDEgNC4yM2wtMi4xMy0uMDk2IDIuNzAzLTIuNTk0Yy4wNDYuMDQ4LS4xODkgMi4wMDMtLjU3MyAyLjY5Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0UxRTBFMyIgZD0iTTEzLjUxNiA0LjI3OGwtNS45ODkgNS40OC0uNTEyLTEuNDA0IDQuMzk2LTQuMjIgMi4xMy4wOTYtLjAyNS4wNDhNNy41MjcgOS43NThsLS4wNTQuMDQ4LTEuMzQ4LS41OTcuODktLjg1NC41MTIgMS40MDN6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0Q1QzhGRiIgZD0iTTIuMjg5IDExLjc1N2wtLjI1Ljg3OC0uODI5LS43OTZ6TTMuNDY5IDEyLjg5bC0uOTE0LjI0LjgyOC43OTV6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0JEQThGRiIgZD0iTTIuMjg5IDExLjc1N2wxLjE4MiAxLjEzNS0uOTE2LjIzNy0uNTE2LS40OTR6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0JEQThGRiIgZD0iTTEuMTI3IDEyLjg3NmwuOTE0LS4yNC0uODI4LS43OTZ6TTIuMzA3IDE0LjAwOGwuMjUtLjg3Ny44MjkuNzk2eiI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNENUM4RkYiIGQ9Ik0xLjEyNyAxMi44NzZMMi4zMSAxNC4wMWwuMjQ3LS44OC0uNTE2LS40OTV6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0IzNjIxMyIgZD0iTTQuOSAxMS41MjNsLTEuMTg0LTEuMTM3LjcxNS0uNjg1IDEuMTg0IDEuMTM2eiI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNFMzhGM0QiIGQ9Ik00LjE4NyAxMi4yMDhsLTEuMTg0LTEuMTM2LjcxNC0uNjg1TDQuOSAxMS41MjN6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0IzNjIxMyIgZD0iTTMuNDczIDEyLjg5NGwtMS4xODQtMS4xMzcuNzE0LS42ODUgMS4xODQgMS4xMzZ6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0MzQzBDNyIgZD0iTTYuMTMyIDkuMjA1bC0uOTc0LTIuMDI3YS41MjYuNTI2IDAgMCAwLS4xNTMtLjE4NS43MTguNzE4IDAgMCAwLS4yNzktLjEzNWMtLjMzMS0uMDgtMS4wNTItLjI4Mi0xLjQ0My0uM2EuMjk1LjI5NSAwIDAgMC0uMjQyLjEwOEw0LjQ2IDcuODI5IDUuNTAzIDkuODFsLjYzLS42MDVoLS4wMDF6Ij48L3BhdGg+CiAgICAgICAgPHBhdGggZmlsbD0iI0E1QTFBQyIgZD0iTTQuNDYgNy44MjlMMy4wNCA2LjY2NmEuMjcuMjcgMCAwIDAtLjAzOS4yOWwxLjY5IDMuMzg3Yy4wMjkuMDUzLjA2Ni4xLjExLjE0MmwuNzAyLS42NzVMNC40NiA3LjgzeiI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNDM0MwQzciIGQ9Ik04Ljg5MSAxMS45NGMtLjAxOC0uMzc1LS4yMjgtMS4wNjgtLjMxMi0xLjM4NWEuNjY4LjY2OCAwIDAgMC0uMTQtLjI2OC41NC41NCAwIDAgMC0uMTkzLS4xNDdsLTIuMTExLS45MzV2LS4wMDJsLS42MzEuNjA2IDIuMDY0IDEuMDAxIDEuMjExIDEuMzYzYS4yNzUuMjc1IDAgMCAwIC4xMTItLjIzMyI+PC9wYXRoPgogICAgICAgIDxwYXRoIGZpbGw9IiNBNUExQUMiIGQ9Ik03LjU2OCAxMC44MWwxLjIxMSAxLjM2M2EuMy4zIDAgMCAxLS4zMDEuMDM3bC0zLjUzLTEuNjIyYS41ODguNTg4IDAgMCAxLS4xNDctLjEwNWwuNzAzLS42NzQgMi4wNjQgMS4wMDF6Ij48L3BhdGg+CiAgICAgICAgPG1hc2sgaWQ9ImIiIGZpbGw9IiNmZmYiPgogICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNhIj48L3VzZT4KICAgICAgICA8L21hc2s+CiAgICAgICAgPHBhdGggZmlsbD0iI0ZGRiIgZD0iTTkuODI0IDcuNDVoLjMyOVYxLjg2NWgtLjMyOXpNOC4yIDguODYyaC45NzRWMy4yNzdIOC4yeiIgbWFzaz0idXJsKCNiKSI+PC9wYXRoPgogICAgPC9nPgo8L3N2Zz4="
13
+ PARTY = "data:image/svg+xml;base64,PHN2ZyBpZD0iTGF5ZXJfMSIgZGF0YS1uYW1lPSJMYXllciAxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii02IC02IDQ2IDUwIj48dGl0bGU+QnJvbnplX1NtYWxsPC90aXRsZT48cGF0aCBkPSJNMjAsMzYuMjhDNy4xOCwzMC42MSw1LjYsMjQuNjksNS41LDEwLjQyTDIwLDMuNzVsMTQuNSw2LjY3QzM0LjQsMjQuNjksMzIuODIsMzAuNjEsMjAsMzYuMjhaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMyAtMSkiIGZpbGw9IiNlYThjMzEiPjwvcGF0aD48cGF0aCBkPSJNMjAsNi41TDMyLDEyYy0wLjE1LDExLjU2LTEuNTEsMTYuNjItMTIsMjEuNTFDOS41MywyOC42NCw4LjE3LDIzLjU4LDgsMTJMMjAsNi41TTIwLDFMMyw4LjgyQzMsMjQuNDcsNC4xMywzMi4yOSwyMCwzOSwzNS44NywzMi4yOSwzNywyNC40NywzNyw4LjgyTDIwLDFoMFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zIC0xKSIgZmlsbD0iI2IzNjIxMyI+PC9wYXRoPjxwYXRoIGQ9Ik0yMCw0LjNsMTQsNi40NGMtMC4xMiwxMy43Mi0xLjcyLDE5LjUxLTE0LDI1QzcuNzMsMzAuMjUsNi4xMiwyNC40Niw2LDEwLjc0TDIwLDQuM00yMCwxTDMsOC44MkMzLDI0LjQ3LDQuMTMsMzIuMjksMjAsMzksMzUuODcsMzIuMjksMzcsMjQuNDcsMzcsOC44MkwyMCwxaDBaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMyAtMSkiIGZpbGw9IiNkNzdhMjAiPjwvcGF0aD48L3N2Zz4="
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
- from mashumaro.config import BaseConfig
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:
@@ -37,7 +38,7 @@ def serialize_datetime(date: str | int | None) -> datetime | None:
37
38
  class BaseModel(DataClassORJSONMixin):
38
39
  """Base config for dataclasses."""
39
40
 
40
- class Config(BaseConfig):
41
+ class Config:
41
42
  """Configuration for TaskData."""
42
43
 
43
44
  aliases = { # noqa: RUF012
@@ -51,6 +52,7 @@ class BaseModel(DataClassORJSONMixin):
51
52
  }
52
53
  serialize_by_alias = True
53
54
  omit_none = True
55
+ code_generation_options = [TO_DICT_ADD_OMIT_NONE_FLAG] # noqa: RUF012
54
56
 
55
57
  def __eq__(self, value: object) -> bool:
56
58
  """Check if two instances are equal."""
@@ -545,8 +547,9 @@ class ProgressQuest(BaseModel):
545
547
 
546
548
  up: float | None = None
547
549
  down: float | None = None
548
- collect: dict = field(default_factory=dict)
550
+ collect: dict[str, int] = field(default_factory=dict)
549
551
  collectedItems: int | None = None
552
+ hp: float | None = None
550
553
 
551
554
 
552
555
  @dataclass(kw_only=True)
@@ -557,6 +560,9 @@ class QuestParty(BaseModel):
557
560
  RSVPNeeded: bool | None = None
558
561
  key: str | None = None
559
562
  completed: str | None = None
563
+ active: bool | None = None
564
+ leader: UUID | None = None
565
+ members: dict[UUID, bool] = field(default_factory=dict)
560
566
 
561
567
 
562
568
  @dataclass(kw_only=True)
@@ -775,48 +781,187 @@ class PushDevicesUser(BaseModel):
775
781
  updatedAt: datetime
776
782
 
777
783
 
778
- class WebhooksType(StrEnum):
784
+ class WebhookType(StrEnum):
779
785
  """Webhook types."""
780
786
 
781
787
  TASK_ACTIVITY = "taskActivity"
782
788
  USER_ACTIVITY = "userActivity"
783
789
  QUEST_ACTIVITY = "questActivity"
784
790
  GROUP_CHAT_RECEIVED = "groupChatReceived"
791
+ GLOBAL_ACTIVITY = "globalActivity"
785
792
 
786
793
 
787
794
  @dataclass(kw_only=True)
788
- class WebhooksOptions(BaseModel):
789
- """Webhooks options data."""
795
+ class QuestActivityOptions(BaseModel):
796
+ """Quest activity options."""
790
797
 
791
- created: bool | None = None
792
- updated: bool | None = None
793
- deleted: bool | None = None
794
- scored: bool | None = None
795
- questStarted: bool | None = None
796
- questFinished: bool | None = None
797
- questInvited: bool | None = None
798
- petHatched: bool | None = None
799
- mountRaised: bool | None = None
800
- leveledUp: bool | None = None
801
- groupId: UUID | None = None
798
+ questStarted: bool = False
799
+ questFinished: bool = False
800
+ questInvited: bool = False
802
801
 
803
802
 
804
803
  @dataclass(kw_only=True)
805
- class WebhooksUser(BaseModel):
806
- """Webhooks user data."""
804
+ class UserActivityOptions(BaseModel):
805
+ """User activity options."""
806
+
807
+ petHatched: bool = False
808
+ mountRaised: bool = False
809
+ leveledUp: bool = False
810
+
811
+
812
+ @dataclass
813
+ class GroupChatReceivedOptions(BaseModel):
814
+ """Group chat received options."""
807
815
 
816
+ groupId: UUID
817
+
818
+
819
+ @dataclass(kw_only=True)
820
+ class TaskActivityOptions(BaseModel):
821
+ """Task activity options."""
822
+
823
+ created: bool = False
824
+ updated: bool = False
825
+ deleted: bool = False
826
+ checklistScored: bool = False
827
+ scored: bool = True
828
+
829
+
830
+ @dataclass(kw_only=True)
831
+ class Webhook(BaseModel):
832
+ """Webhook base class."""
833
+
834
+ url: str | None = field(default=None, kw_only=False)
835
+ enabled: bool | None = None
836
+ label: str | None = None
808
837
  id: UUID | None = None
809
- Type: WebhooksType = WebhooksType.TASK_ACTIVITY
810
- url: str | None = None
811
- enabled: bool = True
838
+
839
+
840
+ @dataclass(kw_only=True)
841
+ class TaskActivity(Webhook):
842
+ """Task activity."""
843
+
844
+ Type: WebhookType = field(default=WebhookType.TASK_ACTIVITY, init=False)
845
+ options: TaskActivityOptions = field(default_factory=TaskActivityOptions)
846
+
847
+
848
+ @dataclass(kw_only=True)
849
+ class GroupChatReceived(Webhook):
850
+ """Group chat received."""
851
+
852
+ def __post_init__(self) -> None:
853
+ """Initialize the GroupChatReceived class."""
854
+ if self.groupId:
855
+ if not isinstance(self.groupId, UUID):
856
+ self.groupId = UUID(self.groupId)
857
+
858
+ self.options = GroupChatReceivedOptions(groupId=self.groupId)
859
+ self.groupId = None
860
+
861
+ groupId: UUID | str | None = field(default=None, kw_only=False)
862
+ Type: WebhookType = field(default=WebhookType.GROUP_CHAT_RECEIVED, init=False)
863
+ options: GroupChatReceivedOptions = field(init=False)
864
+
865
+
866
+ @dataclass(kw_only=True)
867
+ class UserActivity(Webhook):
868
+ """User activity."""
869
+
870
+ Type: WebhookType = field(default=WebhookType.USER_ACTIVITY, init=False)
871
+ options: UserActivityOptions = field(default_factory=UserActivityOptions)
872
+
873
+
874
+ @dataclass(kw_only=True)
875
+ class QuestActivity(Webhook):
876
+ """Quest activity."""
877
+
878
+ Type: WebhookType = field(default=WebhookType.QUEST_ACTIVITY, init=False)
879
+ options: QuestActivityOptions = field(default_factory=QuestActivityOptions)
880
+
881
+
882
+ @dataclass(kw_only=True)
883
+ class GlobalActivity(Webhook):
884
+ """Global activity.
885
+
886
+ Note: global webhooks send a request for every type of event
887
+ """
888
+
889
+ Type: WebhookType = field(default=WebhookType.GLOBAL_ACTIVITY, init=False)
890
+
891
+
892
+ class HabiticaWebhookResponse(HabiticaResponse):
893
+ """Representation of a webhook data response."""
894
+
895
+ data: Annotated[
896
+ Webhook,
897
+ Discriminator(
898
+ field="type",
899
+ include_subtypes=True,
900
+ ),
901
+ ]
902
+
903
+
904
+ class HabiticaDeleteWebhookResponse(HabiticaResponse):
905
+ """Representation of a delete webhook response."""
906
+
907
+ data: list[
908
+ Annotated[
909
+ Webhook,
910
+ Discriminator(
911
+ field="type",
912
+ include_subtypes=True,
913
+ ),
914
+ ]
915
+ ]
916
+
917
+
918
+ @dataclass(kw_only=True)
919
+ class WebhookUser(BaseModel):
920
+ """Webhooks user data."""
921
+
812
922
  failures: int = 0
813
- label: str = ""
814
- options = WebhooksOptions
815
923
  lastFailureAt: datetime | None = None
816
924
  createdAt: datetime | None = None
817
925
  updatedAt: datetime | None = None
818
926
 
819
927
 
928
+ @dataclass(kw_only=True)
929
+ class TaskActivityWebhook(WebhookUser, TaskActivity):
930
+ """Task activity webhook."""
931
+
932
+ type = "taskActivity"
933
+
934
+
935
+ @dataclass(kw_only=True)
936
+ class QuestActivityWebhook(WebhookUser, QuestActivity):
937
+ """Quest activity webhook."""
938
+
939
+ type = "questActivity"
940
+
941
+
942
+ @dataclass(kw_only=True)
943
+ class GlobalActivityWebhook(WebhookUser, GlobalActivity):
944
+ """Global activity webhook."""
945
+
946
+ type = "globalActivity"
947
+
948
+
949
+ @dataclass(kw_only=True)
950
+ class GroupChatReceivedWebhook(WebhookUser, GroupChatReceived):
951
+ """Group chat received webhook."""
952
+
953
+ type = "groupChatReceived"
954
+ groupId: None = None
955
+ options: GroupChatReceivedOptions = field(init=True)
956
+
957
+
958
+ @dataclass(kw_only=True)
959
+ class UserActivityWebhook(WebhookUser, UserActivity):
960
+ """User activity webhook."""
961
+
962
+ type = "userActivity"
963
+
964
+
820
965
  @dataclass(kw_only=True)
821
966
  class PinnedItemsUser(BaseModel):
822
967
  """PinnedItems user data."""
@@ -850,7 +995,15 @@ class UserData(Avatar, BaseModel):
850
995
  tasksOrder: TasksOrderUser = field(default_factory=TasksOrderUser)
851
996
  extra: dict = field(default_factory=dict)
852
997
  pushDevices: list[PushDevicesUser] = field(default_factory=list)
853
- webhooks: list[WebhooksUser] = field(default_factory=list)
998
+ webhooks: list[
999
+ Annotated[
1000
+ Webhook,
1001
+ Discriminator(
1002
+ field="type",
1003
+ include_subtypes=True,
1004
+ ),
1005
+ ]
1006
+ ] = field(default_factory=list)
854
1007
  loginIncentives: int | None = None
855
1008
  invitesSent: int | None = None
856
1009
  pinnedItems: list[PinnedItemsUser] = field(default_factory=list)
@@ -1472,7 +1625,7 @@ class ItemListContent(BaseModel):
1472
1625
  bundles: ItemListEntry
1473
1626
 
1474
1627
 
1475
- @dataclass
1628
+ @dataclass(kw_only=True)
1476
1629
  class GearEntry(BaseModel):
1477
1630
  """GearEntry content data."""
1478
1631
 
@@ -1618,7 +1771,7 @@ class PetEntry(BaseModel):
1618
1771
  text: str | None = None
1619
1772
 
1620
1773
 
1621
- @dataclass
1774
+ @dataclass(kw_only=True)
1622
1775
  class InventoryItemEntry(BaseModel):
1623
1776
  """Inventory item content data."""
1624
1777
 
@@ -1630,6 +1783,36 @@ class InventoryItemEntry(BaseModel):
1630
1783
  key: str | None = None
1631
1784
  notes: str | None = None
1632
1785
  canDrop: bool | None = None
1786
+ sellWarningNote: str | None = None
1787
+
1788
+
1789
+ @dataclass(kw_only=True)
1790
+ class Achievment(BaseModel):
1791
+ """An achievment."""
1792
+
1793
+ icon: str
1794
+ titleKey: str
1795
+ textKey: str
1796
+ key: str
1797
+ text2Key: str | None = None
1798
+ notificationText: str | None = None
1799
+ singularTitleKey: str | None = None
1800
+ singularTextKey: str | None = None
1801
+ pluralTitleKey: str | None = None
1802
+ pluralTextKey: str | None = None
1803
+ modalTextKey: str | None = None
1804
+
1805
+
1806
+ @dataclass(kw_only=True)
1807
+ class Incentive(BaseModel):
1808
+ """A login incentive."""
1809
+
1810
+ rewardKey: list[str] = field(default_factory=list)
1811
+ nextRewardAt: int = 500
1812
+ prevRewardKey: int = 0
1813
+ reward: list[QuestsContent | GearEntry | InventoryItemEntry | Achievment] = field(
1814
+ default_factory=list
1815
+ )
1633
1816
 
1634
1817
 
1635
1818
  @dataclass
@@ -1687,7 +1870,7 @@ class ContentData(BaseModel):
1687
1870
  # tasksByCategory
1688
1871
  # userDefaultsMobile
1689
1872
  # faq
1690
- # loginIncentives
1873
+ loginIncentives: dict[str, Incentive]
1691
1874
 
1692
1875
 
1693
1876
  @dataclass
@@ -1721,3 +1904,113 @@ class HabiticaCastSkillResponse(HabiticaResponse):
1721
1904
  """Representation of a cast skill response."""
1722
1905
 
1723
1906
  data: UserTasks
1907
+
1908
+
1909
+ class GroupPrivacy(StrEnum):
1910
+ """Group privacy."""
1911
+
1912
+ PRIVATE = "private"
1913
+ PUBLIC = "public"
1914
+
1915
+
1916
+ class GroupType(StrEnum):
1917
+ """Group type."""
1918
+
1919
+ GUILD = "guild"
1920
+ PARTY = "party"
1921
+
1922
+
1923
+ @dataclass(kw_only=True)
1924
+ class LeaderOnly(BaseModel):
1925
+ """Group leaderOnly data."""
1926
+
1927
+ challenges: bool
1928
+ getGems: bool
1929
+
1930
+
1931
+ @dataclass(kw_only=True)
1932
+ class GroupLeader(BaseModel):
1933
+ """Group leader data."""
1934
+
1935
+ id: UUID
1936
+ auth: AuthUser
1937
+ profile: ProfileUser
1938
+
1939
+
1940
+ @dataclass(kw_only=True)
1941
+ class ChatMsgInfo(BaseModel):
1942
+ """Chat message info."""
1943
+
1944
+ type: str | None = None
1945
+ user: str | None = None
1946
+ quest: str | None = None
1947
+ items: dict[str, int] | None = None
1948
+
1949
+
1950
+ @dataclass(kw_only=True)
1951
+ class ChatMsg(BaseModel):
1952
+ """Chat message."""
1953
+
1954
+ id: UUID
1955
+ flagCount: int
1956
+ text: str
1957
+ unformattedText: str
1958
+ info: ChatMsgInfo
1959
+ timestamp: datetime = field(
1960
+ metadata=field_options(
1961
+ deserialize=serialize_datetime,
1962
+ )
1963
+ )
1964
+ likes: dict[UUID, bool]
1965
+ client: str | None = None
1966
+ uuid: UUID | str
1967
+ groupId: UUID | None = None
1968
+ user: str | None = None
1969
+ username: str | None = None
1970
+ userStyles: Avatar | None = None
1971
+ sent: bool | None = None
1972
+ ownerId: UUID | None = None
1973
+ uniqueMessageId: UUID | None = None
1974
+
1975
+
1976
+ @dataclass(kw_only=True)
1977
+ class GroupData(BaseModel):
1978
+ """Groups data."""
1979
+
1980
+ id: UUID
1981
+ name: str
1982
+ summary: str = ""
1983
+ description: str = ""
1984
+ leader: GroupLeader
1985
+ type: GroupType
1986
+ privacy: GroupPrivacy
1987
+ chat: list[ChatMsg]
1988
+ leaderOnly: LeaderOnly
1989
+ memberCount: int = 1
1990
+ ChallengeCount: int = 0
1991
+ chatLimitCount: int | None = None
1992
+ balance: float
1993
+ logo: str | None = None
1994
+ leaderMessage: str | None = None
1995
+ quest: QuestParty
1996
+
1997
+
1998
+ @dataclass
1999
+ class HabiticaGroupsResponse(HabiticaResponse):
2000
+ """Representation of a groups response."""
2001
+
2002
+ data: GroupData
2003
+
2004
+
2005
+ @dataclass(kw_only=True)
2006
+ class MessageData(BaseModel):
2007
+ """Message data."""
2008
+
2009
+ message: ChatMsg
2010
+
2011
+
2012
+ @dataclass(kw_only=True)
2013
+ class HabiticaMessageResponse(HabiticaResponse):
2014
+ """Representation of a group response."""
2015
+
2016
+ data: MessageData
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Habiticalib
3
- Version: 0.3.7rc0
3
+ Version: 0.4.0
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=UxNKxNhjIi3v95VE3h-JWgitriNZytrGeX0GvKdevwU,7840
2
+ habiticalib/const.py,sha256=EN1INod7PhUH4sXIjx_7T84FciaXMGPCWDt8C9wA2-U,2308
3
+ habiticalib/exceptions.py,sha256=i9hnCaMT5RbnTioFhwRYJkcC_bG9lMeUd2jJsWFVnVg,1342
4
+ habiticalib/ha.py,sha256=c3cbXnWsA7IjcelzHb6snZ4C-fCDqwKoYZwvQiugnyY,25920
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=jH2Q2F6CUShTN2XmfVOfbAfP7m8tMVLDe8Q8lpx3lM0,50938
9
+ habiticalib-0.4.0.dist-info/METADATA,sha256=8ybZ21z48BklMlGBLHmA8HgNYU3QoltZcnFoN35-7NA,4176
10
+ habiticalib-0.4.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
+ habiticalib-0.4.0.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
12
+ habiticalib-0.4.0.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- habiticalib/__init__.py,sha256=ZUd6heFQJaJgNiseoSY2SfJzOHfGFdIiOHI-qf9fXuU,6940
2
- habiticalib/const.py,sha256=XnUiezs1-foo8BWXmFJZ1sCATsygwFNvGuzULoszRk0,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=VoRoKrDmJraEU6iB9WkD4Aq6Q0_4iLCmD1uWdfbgdMc,44260
9
- habiticalib-0.3.7rc0.dist-info/METADATA,sha256=bh846TxXDiGLsnI-peFnzfZlSRWx6t_HWkw4Kae0lRE,4210
10
- habiticalib-0.3.7rc0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
11
- habiticalib-0.3.7rc0.dist-info/licenses/LICENSE,sha256=oIinIOSJ49l1iVIRI3XGXFWt6SF7a83kEFBAY8ORwNI,1084
12
- habiticalib-0.3.7rc0.dist-info/RECORD,,