Habiticalib 0.1.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/types.py ADDED
@@ -0,0 +1,1224 @@
1
+ """Typedefs for Habiticalib."""
2
+
3
+ # pylint: disable=C0103
4
+ from __future__ import annotations
5
+
6
+ from dataclasses import dataclass, field
7
+ import datetime as dt
8
+ from datetime import UTC, datetime
9
+ from enum import Enum, StrEnum
10
+ from typing import Any, NotRequired, TypedDict
11
+ from uuid import UUID # noqa: TCH003
12
+
13
+ from mashumaro import field_options
14
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
15
+
16
+
17
+ def serialize_datetime(date: str | int | None) -> datetime | None:
18
+ """Convert an iso date to a datetime.date object."""
19
+ if isinstance(date, int):
20
+ return datetime.fromtimestamp(date / 1000, tz=UTC)
21
+ if isinstance(date, str):
22
+ try:
23
+ return datetime.fromisoformat(date)
24
+ except ValueError:
25
+ # sometimes nextDue dates are JavaScript datetime strings
26
+ # instead of iso: "Mon May 06 2024 00:00:00 GMT+0200"
27
+ # This was fixed in Habitica v5.28.9, nextDue dates are now isoformat
28
+ try:
29
+ return datetime.strptime(date, "%a %b %d %Y %H:%M:%S %Z%z")
30
+ except ValueError:
31
+ return None
32
+ return None
33
+
34
+
35
+ @dataclass(kw_only=True)
36
+ class NotificationsUser:
37
+ """Notifications User data."""
38
+
39
+ Type: str = field(metadata=field_options(alias="type"))
40
+ data: dict[str, Any]
41
+ seen: bool
42
+ id: UUID
43
+
44
+
45
+ @dataclass(kw_only=True)
46
+ class HabiticaResponse(DataClassORJSONMixin):
47
+ """Representation of a base Habitica API response."""
48
+
49
+ data: Any
50
+ success: bool
51
+ notifications: list[NotificationsUser] = field(default_factory=list)
52
+ userV: int | None = None
53
+ appVersion: str | None = None
54
+
55
+
56
+ @dataclass(kw_only=True)
57
+ class LoginData:
58
+ """Login data."""
59
+
60
+ id: UUID
61
+ apiToken: str
62
+ newUser: bool
63
+ username: str
64
+ passwordResetCode: str | None = None
65
+
66
+
67
+ @dataclass(kw_only=True)
68
+ class HabiticaLoginResponse(HabiticaResponse):
69
+ """Representation of a login data response."""
70
+
71
+ data: LoginData
72
+
73
+
74
+ @dataclass(kw_only=True)
75
+ class LocalAuth:
76
+ """Auth local data."""
77
+
78
+ email: str | None = None
79
+ username: str | None = None
80
+ lowerCaseUsername: str | None = None
81
+ has_password: bool | None = None
82
+
83
+
84
+ @dataclass(kw_only=True)
85
+ class LocalTimestamps:
86
+ """Timestamps local data."""
87
+
88
+ created: datetime | None = None
89
+ loggedin: datetime | None = None
90
+ updated: datetime | None = None
91
+
92
+
93
+ @dataclass(kw_only=True)
94
+ class AuthUser:
95
+ """User auth data."""
96
+
97
+ local: LocalAuth = field(default_factory=LocalAuth)
98
+ timestamps: LocalTimestamps = field(default_factory=LocalTimestamps)
99
+ facebook: dict | None = None
100
+ google: dict | None = None
101
+ apple: dict | None = None
102
+
103
+
104
+ @dataclass(kw_only=True)
105
+ class UltimateGearSetsAchievments:
106
+ """Achievments ultimateGearSets data."""
107
+
108
+ healer: bool | None = None
109
+ wizard: bool | None = None
110
+ rogue: bool | None = None
111
+ warrior: bool | None = None
112
+
113
+
114
+ @dataclass(kw_only=True)
115
+ class QuestsAchievments:
116
+ """Achievments quests."""
117
+
118
+ bewilder: int | None = None
119
+ burnout: int | None = None
120
+ stressbeast: int | None = None
121
+ harpy: int | None = None
122
+ atom3: int | None = None
123
+ vice3: int | None = None
124
+ vice1: int | None = None
125
+ gryphon: int | None = None
126
+ evilsanta2: int | None = None
127
+ evilsanta: int | None = None
128
+ dilatory_derby: int | None = None
129
+ dilatory: int | None = None
130
+ atom2: int | None = None
131
+ atom1: int | None = None
132
+ dysheartener: int | None = None
133
+
134
+
135
+ @dataclass(kw_only=True)
136
+ class AchievementsUser:
137
+ """User achievments data."""
138
+
139
+ ultimateGearSets: UltimateGearSetsAchievments = field(
140
+ default_factory=UltimateGearSetsAchievments
141
+ )
142
+ streak: int | None = None
143
+ challenges: list = field(default_factory=list)
144
+ perfect: int | None = None
145
+ quests: QuestsAchievments = field(default_factory=QuestsAchievments)
146
+ backToBasics: bool | None = None
147
+ dustDevil: bool | None = None
148
+ primedForPainting: bool | None = None
149
+ completedTask: bool | None = None
150
+ createdTask: bool | None = None
151
+ fedPet: bool | None = None
152
+ hatchedPet: bool | None = None
153
+ purchasedEquipment: bool | None = None
154
+ tickledPink: bool | None = None
155
+ goodAsGold: bool | None = None
156
+ boneCollector: bool | None = None
157
+ seeingRed: bool | None = None
158
+ violetsAreBlue: bool | None = None
159
+ shadyCustomer: bool | None = None
160
+ joinedGuild: bool | None = None
161
+ joinedChallenge: bool | None = None
162
+ partyUp: None = None
163
+
164
+
165
+ @dataclass(kw_only=True)
166
+ class BackerUser:
167
+ """User backer data."""
168
+
169
+ tier: int | None = None
170
+ npc: str | None = None
171
+ tokensApplied: bool | None = None
172
+
173
+
174
+ @dataclass(kw_only=True)
175
+ class PermissionsUser:
176
+ """User permissions data."""
177
+
178
+ fullAccess: bool | None = None
179
+ news: bool | None = None
180
+ userSupport: bool | None = None
181
+ challengeAdmin: bool | None = None
182
+ moderator: bool | None = None
183
+ coupons: bool | None = None
184
+
185
+
186
+ @dataclass(kw_only=True)
187
+ class ContributorUser:
188
+ """User contributer data."""
189
+
190
+ contributions: str | None = None
191
+ level: int | None = None
192
+ text: str | None = None
193
+
194
+
195
+ @dataclass(kw_only=True)
196
+ class ConsecutivePlan:
197
+ """Plan consecutive data."""
198
+
199
+ trinkets: int | None = None
200
+ gemCapExtra: int | None = None
201
+ offset: int | None = None
202
+ count: int | None = None
203
+
204
+
205
+ @dataclass(kw_only=True)
206
+ class PlanPurchased:
207
+ """Purchased background data."""
208
+
209
+ consecutive: ConsecutivePlan = field(default_factory=ConsecutivePlan)
210
+ mysteryItems: list = field(default_factory=list)
211
+ gemsBought: int | None = None
212
+ extraMonths: int | None = None
213
+ dateUpdated: datetime | None = None
214
+ perkMonthCount: int | None = None
215
+ quantity: int | None = None
216
+
217
+
218
+ @dataclass(kw_only=True)
219
+ class PurchasedUser:
220
+ """User purchased data."""
221
+
222
+ plan: PlanPurchased = field(default_factory=PlanPurchased)
223
+ txnCount: int | None = None
224
+ background: dict[str, bool] = field(default_factory=dict)
225
+ shirt: dict[str, bool] = field(default_factory=dict)
226
+ hair: dict[str, bool] = field(default_factory=dict)
227
+ skin: dict[str, bool] = field(default_factory=dict)
228
+ ads: bool | None = None
229
+ mobileChat: bool | None = None
230
+
231
+
232
+ @dataclass(kw_only=True)
233
+ class TourFlags:
234
+ """Flags tour data."""
235
+
236
+ intro: int | None = None
237
+ classes: int | None = None
238
+ stats: int | None = None
239
+ tavern: int | None = None
240
+ party: int | None = None
241
+ guilds: int | None = None
242
+ challenges: int | None = None
243
+ market: int | None = None
244
+ pets: int | None = None
245
+ mounts: int | None = None
246
+ hall: int | None = None
247
+ equipment: int | None = None
248
+ groupPlans: int | None = None
249
+
250
+
251
+ @dataclass(kw_only=True)
252
+ class CommonTutorial:
253
+ """Tutorial common data."""
254
+
255
+ habits: bool
256
+ dailies: bool
257
+ todos: bool
258
+ rewards: bool
259
+ party: bool
260
+ pets: bool
261
+ gems: bool
262
+ skills: bool
263
+ classes: bool
264
+ tavern: bool
265
+ equipment: bool
266
+ items: bool
267
+ mounts: bool
268
+ inbox: bool
269
+ stats: bool
270
+
271
+
272
+ @dataclass(kw_only=True)
273
+ class IosTutorial:
274
+ """Tutorial ios data."""
275
+
276
+ addTask: bool
277
+ editTask: bool
278
+ deleteTask: bool
279
+ filterTask: bool
280
+ groupPets: bool
281
+ inviteParty: bool
282
+ reorderTask: bool
283
+
284
+
285
+ @dataclass(kw_only=True)
286
+ class TutorialFlags:
287
+ """Flags tutorial data."""
288
+
289
+ common: CommonTutorial | None = None
290
+ ios: IosTutorial | None = None
291
+
292
+
293
+ @dataclass(kw_only=True)
294
+ class FlagsUser:
295
+ """User flags data."""
296
+
297
+ customizationsNotification: bool | None = None
298
+ tour: TourFlags = field(default_factory=TourFlags)
299
+ showTour: bool | None = None
300
+ tutorial: TutorialFlags = field(default_factory=TutorialFlags)
301
+ dropsEnabled: bool | None = None
302
+ itemsEnabled: bool | None = None
303
+ lastNewStuffRead: str | None = None
304
+ rewrite: bool | None = None
305
+ classSelected: bool | None = None
306
+ rebirthEnabled: bool | None = None
307
+ levelDrops: dict[str, bool] = field(default_factory=dict)
308
+ recaptureEmailsPhase: int | None = None
309
+ weeklyRecapEmailsPhase: int | None = None
310
+ lastWeeklyRecap: datetime | None = None
311
+ communityGuidelinesAccepted: bool | None = None
312
+ cronCount: int | None = None
313
+ welcomed: bool | None = None
314
+ armoireEnabled: bool | None = None
315
+ armoireOpened: bool | None = None
316
+ armoireEmpty: bool | None = None
317
+ cardReceived: bool | None = None
318
+ warnedLowHealth: bool | None = None
319
+ verifiedUsername: bool | None = None
320
+ newStuff: bool | None = None
321
+ thirdPartyTools: datetime | None = None
322
+ mathUpdates: bool | None = None
323
+ lastFreeRebirth: datetime | None = None
324
+ chatRevoked: bool | None = None
325
+ chatShadowMuted: bool | None = None
326
+ lastWeeklyRecapDiscriminator: bool | None = None
327
+ onboardingEmailsPhase: str | None = None
328
+
329
+
330
+ @dataclass(kw_only=True)
331
+ class EntryHistory:
332
+ """History entry data."""
333
+
334
+ date: datetime = field(
335
+ metadata=field_options(
336
+ deserialize=serialize_datetime,
337
+ )
338
+ )
339
+ value: float
340
+ scoredUp: int | None = None
341
+ scoredDown: int | None = None
342
+ isDue: bool | None = None
343
+ completed: bool | None = None
344
+
345
+
346
+ @dataclass(kw_only=True)
347
+ class HistoryUser:
348
+ """User history data."""
349
+
350
+ todos: list[EntryHistory] = field(default_factory=list)
351
+ exp: list[EntryHistory] = field(default_factory=list)
352
+
353
+
354
+ @dataclass(kw_only=True)
355
+ class EquippedGear:
356
+ """Gear equipped data."""
357
+
358
+ weapon: str | None = None
359
+ armor: str | None = None
360
+ head: str | None = None
361
+ shield: str | None = None
362
+ back: str | None = None
363
+ headAccessory: str | None = None
364
+ eyewear: str | None = None
365
+ body: str | None = None
366
+
367
+
368
+ @dataclass(kw_only=True)
369
+ class GearItems:
370
+ """Items gear data."""
371
+
372
+ equipped: EquippedGear = field(default_factory=EquippedGear)
373
+ costume: EquippedGear = field(default_factory=EquippedGear)
374
+ owned: dict[str, bool] = field(default_factory=dict)
375
+
376
+
377
+ @dataclass(kw_only=True)
378
+ class SpecialItems:
379
+ """Items special data."""
380
+
381
+ birthdayReceived: list = field(default_factory=list)
382
+ birthday: int | None = None
383
+ thankyouReceived: list = field(default_factory=list)
384
+ thankyou: int | None = None
385
+ greetingReceived: list = field(default_factory=list)
386
+ greeting: int | None = None
387
+ nyeReceived: list = field(default_factory=list)
388
+ nye: int | None = None
389
+ valentineReceived: list = field(default_factory=list)
390
+ valentine: int | None = None
391
+ seafoam: int | None = None
392
+ shinySeed: int | None = None
393
+ spookySparkles: int | None = None
394
+ snowball: int | None = None
395
+ congrats: int | None = None
396
+ congratsReceived: list = field(default_factory=list)
397
+ getwell: int | None = None
398
+ getwellReceived: list = field(default_factory=list)
399
+ goodluck: int | None = None
400
+ goodluckReceived: list = field(default_factory=list)
401
+
402
+
403
+ @dataclass(kw_only=True)
404
+ class LastDropItems:
405
+ """LastDrop items data."""
406
+
407
+ count: int | None = None
408
+ date: datetime | None = None
409
+
410
+
411
+ @dataclass(kw_only=True)
412
+ class ItemsUser:
413
+ """User items data."""
414
+
415
+ gear: GearItems = field(default_factory=GearItems)
416
+ special: SpecialItems = field(default_factory=SpecialItems)
417
+ lastDrop: LastDropItems = field(default_factory=LastDropItems)
418
+ currentMount: str | None = None
419
+ currentPet: str | None = None
420
+ quests: dict[str, int] = field(default_factory=dict)
421
+ mounts: dict[str, bool] = field(default_factory=dict)
422
+ food: dict[str, int] = field(default_factory=dict)
423
+ hatchingPotions: dict[str, int] = field(default_factory=dict)
424
+ eggs: dict[str, int] = field(default_factory=dict)
425
+ pets: dict[str, int] = field(default_factory=dict)
426
+
427
+
428
+ @dataclass(kw_only=True)
429
+ class InvitationsUser:
430
+ """Invitations user data."""
431
+
432
+ party: dict = field(default_factory=dict)
433
+ guilds: list = field(default_factory=list)
434
+ parties: list = field(default_factory=list)
435
+
436
+
437
+ @dataclass(kw_only=True)
438
+ class ProgressQuest:
439
+ """Quest progress data."""
440
+
441
+ up: float | None = None
442
+ down: float | None = None
443
+ collect: dict = field(default_factory=dict)
444
+ collectedItems: int | None = None
445
+
446
+
447
+ @dataclass(kw_only=True)
448
+ class QuestParty:
449
+ """Party quest data."""
450
+
451
+ progress: ProgressQuest = field(default_factory=ProgressQuest)
452
+ RSVPNeeded: bool | None = None
453
+ key: str | None = None
454
+ completed: str | None = None
455
+
456
+
457
+ @dataclass(kw_only=True)
458
+ class PartyUser:
459
+ """Party user data."""
460
+
461
+ quest: QuestParty = field(default_factory=QuestParty)
462
+ order: str | None = None
463
+ orderAscending: str | None = None
464
+ _id: UUID | None = None
465
+
466
+
467
+ @dataclass(kw_only=True)
468
+ class HairPreferences:
469
+ """Hair preferences data."""
470
+
471
+ color: str | None = None
472
+ base: int | None = None
473
+ bangs: int | None = None
474
+ beard: int | None = None
475
+ mustache: int | None = None
476
+ flower: int | None = None
477
+
478
+
479
+ @dataclass(kw_only=True)
480
+ class EmailNotificationsPreferences:
481
+ """EmailNotifications preferences data."""
482
+
483
+ unsubscribeFromAll: bool | None = None
484
+ newPM: bool | None = None
485
+ kickedGroup: bool | None = None
486
+ wonChallenge: bool | None = None
487
+ giftedGems: bool | None = None
488
+ giftedSubscription: bool | None = None
489
+ invitedParty: bool | None = None
490
+ invitedGuild: bool | None = None
491
+ questStarted: bool | None = None
492
+ invitedQuest: bool | None = None
493
+ importantAnnouncements: bool | None = None
494
+ weeklyRecaps: bool | None = None
495
+ onboarding: bool | None = None
496
+ majorUpdates: bool | None = None
497
+ subscriptionReminders: bool | None = None
498
+ contentRelease: bool | None = None
499
+
500
+
501
+ @dataclass(kw_only=True)
502
+ class PushNotificationsPreferences:
503
+ """PushNotifications preferences data."""
504
+
505
+ unsubscribeFromAll: bool | None = None
506
+ newPM: bool | None = None
507
+ wonChallenge: bool | None = None
508
+ giftedGems: bool | None = None
509
+ giftedSubscription: bool | None = None
510
+ invitedParty: bool | None = None
511
+ invitedGuild: bool | None = None
512
+ questStarted: bool | None = None
513
+ invitedQuest: bool | None = None
514
+ majorUpdates: bool | None = None
515
+ mentionParty: bool | None = None
516
+ mentionJoinedGuild: bool | None = None
517
+ mentionUnjoinedGuild: bool | None = None
518
+ partyActivity: bool | None = None
519
+ contentRelease: bool | None = None
520
+
521
+
522
+ @dataclass(kw_only=True)
523
+ class SuppressModalsPreferences:
524
+ """SupressModals preferences data."""
525
+
526
+ levelUp: bool | None = None
527
+ hatchPet: bool | None = None
528
+ raisePet: bool | None = None
529
+ streak: bool | None = None
530
+
531
+
532
+ @dataclass(kw_only=True)
533
+ class ActiveFilterTask:
534
+ """ActiveFilter task data."""
535
+
536
+ habit: str | None = None
537
+ daily: str | None = None
538
+ todo: str | None = None
539
+ reward: str | None = None
540
+
541
+
542
+ @dataclass(kw_only=True)
543
+ class TasksPreferences:
544
+ """Tasks preferences data."""
545
+
546
+ activeFilter: ActiveFilterTask = field(default_factory=ActiveFilterTask)
547
+ groupByChallenge: bool | None = None
548
+ confirmScoreNotes: bool | None = None
549
+ mirrorGroupTasks: list[UUID] = field(default_factory=list)
550
+
551
+
552
+ @dataclass(kw_only=True)
553
+ class PreferencesUser:
554
+ """Preferences user data."""
555
+
556
+ hair: HairPreferences = field(default_factory=HairPreferences)
557
+ emailNotifications: EmailNotificationsPreferences = field(
558
+ default_factory=EmailNotificationsPreferences
559
+ )
560
+ pushNotifications: PushNotificationsPreferences = field(
561
+ default_factory=PushNotificationsPreferences
562
+ )
563
+ suppressModals: SuppressModalsPreferences = field(
564
+ default_factory=SuppressModalsPreferences
565
+ )
566
+ tasks: TasksPreferences = field(default_factory=TasksPreferences)
567
+ dayStart: int | None = None
568
+ size: str | None = None
569
+ hideHeader: bool | None = None
570
+ skin: str | None = None
571
+ shirt: str | None = None
572
+ timezoneOffset: int | None = None
573
+ sound: str | None = None
574
+ chair: str | None = None
575
+ allocationMode: str | None = None
576
+ autoEquip: bool | None = None
577
+ costume: bool | None = None
578
+ dateFormat: str | None = None
579
+ sleep: bool | None = None
580
+ stickyHeader: bool | None = None
581
+ disableClasses: bool | None = None
582
+ newTaskEdit: bool | None = None
583
+ dailyDueDefaultView: bool | None = None
584
+ advancedCollapsed: bool | None = None
585
+ toolbarCollapsed: bool | None = None
586
+ reverseChatOrder: bool | None = None
587
+ developerMode: bool | None = None
588
+ displayInviteToPartyWhenPartyIs1: bool | None = None
589
+ background: str | None = None
590
+ automaticAllocation: bool | None = None
591
+ webhooks: dict = field(default_factory=dict)
592
+ improvementCategories: list[str] = field(default_factory=list)
593
+ timezoneOffsetAtLastCron: int | None = None
594
+ language: str | None = None
595
+
596
+
597
+ @dataclass(kw_only=True)
598
+ class ProfileUser:
599
+ """Profile user data."""
600
+
601
+ blurb: str | None = None
602
+ imageUrl: str | None = None
603
+ name: str | None = None
604
+
605
+
606
+ @dataclass(kw_only=True)
607
+ class BuffsStats:
608
+ """Buffs stats data."""
609
+
610
+ Str: int | None = field(default=None, metadata=field_options(alias="str"))
611
+ per: int | None = None
612
+ con: int | None = None
613
+ stealth: int | None = None
614
+ streaks: bool | None = None
615
+ seafoam: bool | None = None
616
+ shinySeed: bool | None = None
617
+ snowball: bool | None = None
618
+ spookySparkles: bool | None = None
619
+ Int: int | None = field(default=None, metadata=field_options(alias="int"))
620
+
621
+
622
+ @dataclass(kw_only=True)
623
+ class TrainingStats:
624
+ """Training stats data."""
625
+
626
+ Str: float | None = field(default=None, metadata=field_options(alias="str"))
627
+ per: int | None = None
628
+ con: int | None = None
629
+ Int: int | None = field(default=None, metadata=field_options(alias="int"))
630
+
631
+
632
+ class HabiticaClass(StrEnum):
633
+ """Habitica's player classes."""
634
+
635
+ WARRIOR = "warrior"
636
+ ROGUE = "rogue"
637
+ MAGE = "wizard"
638
+ HEALER = "healer"
639
+
640
+
641
+ @dataclass(kw_only=True)
642
+ class StatsUser:
643
+ """Stats user data."""
644
+
645
+ buffs: BuffsStats = field(default_factory=BuffsStats)
646
+ training: TrainingStats = field(default_factory=TrainingStats)
647
+ hp: float | None = None
648
+ mp: float | None = None
649
+ exp: int | None = None
650
+ gp: float | None = None
651
+ lvl: int | None = None
652
+ Class: HabiticaClass | None = field(
653
+ default=None, metadata=field_options(alias="class")
654
+ )
655
+ points: int | None = None
656
+ Str: int | None = field(default=None, metadata=field_options(alias="str"))
657
+ con: int | None = None
658
+ per: int | None = None
659
+ toNextLevel: int | None = None
660
+ maxHealth: int | None = None
661
+ maxMP: int | None = None
662
+ Int: int | None = field(default=None, metadata=field_options(alias="int"))
663
+
664
+
665
+ field(
666
+ metadata=field_options(
667
+ deserialize=serialize_datetime,
668
+ )
669
+ )
670
+
671
+
672
+ @dataclass(kw_only=True)
673
+ class TagsUser:
674
+ """Tags user data."""
675
+
676
+ id: UUID | None = None
677
+ name: str | None = None
678
+ challenge: bool | None = None
679
+ group: str | None = None
680
+
681
+
682
+ @dataclass(kw_only=True)
683
+ class InboxUser:
684
+ """Inbox user data."""
685
+
686
+ newMessages: int | None = None
687
+ optOut: bool | None = None
688
+ blocks: list = field(default_factory=list)
689
+ messages: dict = field(default_factory=dict)
690
+
691
+
692
+ @dataclass(kw_only=True)
693
+ class TasksOrderUser:
694
+ """TasksOrder user data."""
695
+
696
+ habits: list[UUID] = field(default_factory=list)
697
+ dailys: list[UUID] = field(default_factory=list)
698
+ todos: list[UUID] = field(default_factory=list)
699
+ rewards: list[UUID] = field(default_factory=list)
700
+
701
+
702
+ @dataclass(kw_only=True)
703
+ class PushDevicesUser:
704
+ """PushDevices user data."""
705
+
706
+ regId: str
707
+ Type: str = field(metadata=field_options(alias="type"))
708
+ createdAt: datetime
709
+ updatedAt: datetime
710
+
711
+
712
+ @dataclass(kw_only=True)
713
+ class WebhooksUser:
714
+ """Webhooks user data."""
715
+
716
+ id: UUID
717
+ Type: str = field(metadata=field_options(alias="type"))
718
+ label: str
719
+ url: str
720
+ enabled: bool
721
+ failures: int
722
+ lastFailureAt: datetime | None
723
+
724
+
725
+ @dataclass(kw_only=True)
726
+ class PinnedItemsUser:
727
+ """PinnedItems user data."""
728
+
729
+ path: str
730
+ Type: str = field(metadata=field_options(alias="type"))
731
+
732
+
733
+ @dataclass(kw_only=True)
734
+ class UserData:
735
+ """User data."""
736
+
737
+ id: UUID | None = None
738
+ preferences: PreferencesUser = field(default_factory=PreferencesUser)
739
+ flags: FlagsUser = field(default_factory=FlagsUser)
740
+ auth: AuthUser = field(default_factory=AuthUser)
741
+ achievements: AchievementsUser = field(default_factory=AchievementsUser)
742
+ backer: BackerUser = field(default_factory=BackerUser)
743
+ contributor: ContributorUser = field(default_factory=ContributorUser)
744
+ permissions: PermissionsUser = field(default_factory=PermissionsUser)
745
+ purchased: PurchasedUser = field(default_factory=PurchasedUser)
746
+ history: HistoryUser = field(default_factory=HistoryUser)
747
+ items: ItemsUser = field(default_factory=ItemsUser)
748
+ invitations: InvitationsUser = field(default_factory=InvitationsUser)
749
+ party: PartyUser = field(default_factory=PartyUser)
750
+ profile: ProfileUser = field(default_factory=ProfileUser)
751
+ stats: StatsUser = field(default_factory=StatsUser)
752
+ notifications: list[NotificationsUser] = field(default_factory=list)
753
+ tags: list[TagsUser] = field(default_factory=list)
754
+ inbox: InboxUser = field(default_factory=InboxUser)
755
+ tasksOrder: TasksOrderUser = field(default_factory=TasksOrderUser)
756
+ extra: dict = field(default_factory=dict)
757
+ pushDevices: list[PushDevicesUser] = field(default_factory=list)
758
+ webhooks: list[WebhooksUser] = field(default_factory=list)
759
+ loginIncentives: int | None = None
760
+ invitesSent: int | None = None
761
+ pinnedItems: list[PinnedItemsUser] = field(default_factory=list)
762
+ pinnedItemsOrder: list[str] = field(default_factory=list)
763
+ unpinnedItems: list[PinnedItemsUser] = field(default_factory=list)
764
+ secret: str | None = None
765
+ balance: float | None = None
766
+ lastCron: datetime | None = None
767
+ needsCron: bool | None = None
768
+ challenges: list[UUID] = field(default_factory=list)
769
+ guilds: list[UUID] = field(default_factory=list)
770
+ newMessages: dict[str, bool] = field(default_factory=dict)
771
+
772
+
773
+ @dataclass(kw_only=True)
774
+ class HabiticaUserResponse(HabiticaResponse):
775
+ """Representation of a user data response."""
776
+
777
+ data: UserData
778
+
779
+
780
+ @dataclass(kw_only=True)
781
+ class CompletedBy:
782
+ """Task group completedby data."""
783
+
784
+ userId: UUID | None = None
785
+ date: datetime | None = None
786
+
787
+
788
+ @dataclass(kw_only=True)
789
+ class GroupTask:
790
+ """Task group data."""
791
+
792
+ assignedUsers: list[UUID] | None = None
793
+ id: UUID | None = None
794
+ assignedDate: datetime | None = None
795
+ assigningUsername: str | None = None
796
+ assignedUsersDetail: dict[str, Any] = field(default_factory=dict)
797
+ taskId: UUID | None = None
798
+ managerNotes: str | None = None
799
+ completedBy: CompletedBy = field(default_factory=CompletedBy)
800
+
801
+
802
+ @dataclass(kw_only=True)
803
+ class Repeat:
804
+ """Task repeat data."""
805
+
806
+ m: bool = True
807
+ t: bool = True
808
+ w: bool = True
809
+ th: bool = False
810
+ f: bool = False
811
+ s: bool = False
812
+ su: bool = False
813
+
814
+
815
+ class ChallengeAbortedReason(StrEnum):
816
+ """Task challenge aborted reason data."""
817
+
818
+ CHALLENGE_DELETED = "CHALLENGE_DELETED"
819
+ TASK_DELETED = "TASK_DELETED"
820
+ UNSUBSCRIBED = "UNSUBSCRIBED"
821
+ CHALLENGE_CLOSED = "CHALLENGE_CLOSED"
822
+ CHALLENGE_TASK_NOT_FOUND = "CHALLENGE_TASK_NOT_FOUND"
823
+
824
+
825
+ @dataclass(kw_only=True)
826
+ class Challenge:
827
+ """Challenge task data."""
828
+
829
+ id: UUID | None = None
830
+ taskId: UUID | None = None
831
+ shortName: str | None = None
832
+ broken: ChallengeAbortedReason | None = None
833
+ winner: str | None = None
834
+
835
+
836
+ @dataclass(kw_only=True)
837
+ class Reminders:
838
+ """Task reminders data."""
839
+
840
+ id: UUID
841
+ time: datetime
842
+ startDate: datetime | None = None
843
+
844
+
845
+ class TaskType(StrEnum):
846
+ """Task types enum."""
847
+
848
+ DAILY = "daily"
849
+ TODO = "todo"
850
+ HABIT = "habit"
851
+ REWARD = "reward"
852
+
853
+
854
+ class Attributes(StrEnum):
855
+ """Character attributes enum."""
856
+
857
+ STR = "str"
858
+ CON = "con"
859
+ INT = "int"
860
+ PER = "per"
861
+
862
+
863
+ class Frequency(StrEnum):
864
+ """Recurrence frequency enum."""
865
+
866
+ DAILY = "daily"
867
+ WEEKLY = "weekly"
868
+ MONTHLY = "monthly"
869
+ YEARLY = "yearly"
870
+
871
+
872
+ class Task(TypedDict("Task", {"type": NotRequired[TaskType]}), total=True):
873
+ """Representation of a task."""
874
+
875
+ text: NotRequired[str]
876
+ attribute: NotRequired[Attributes]
877
+ alias: NotRequired[str]
878
+ notes: NotRequired[str]
879
+ tags: NotRequired[list[UUID]]
880
+ collapseChecklist: NotRequired[bool]
881
+ date: NotRequired[datetime | dt.date | None]
882
+ priority: NotRequired[TaskPriority]
883
+ reminders: NotRequired[list[Reminders]]
884
+ checklist: NotRequired[list[str]]
885
+ up: NotRequired[bool]
886
+ down: NotRequired[bool]
887
+ counterUp: NotRequired[int]
888
+ counterDown: NotRequired[int]
889
+ startDate: NotRequired[datetime | dt.date]
890
+ frequency: NotRequired[Frequency]
891
+ everyX: NotRequired[int]
892
+ repeat: NotRequired[Repeat]
893
+ daysOfMonth: NotRequired[list[int]]
894
+ weeksOfMonth: NotRequired[list[int]]
895
+ completed: NotRequired[bool]
896
+ streak: NotRequired[int]
897
+
898
+
899
+ @dataclass(kw_only=True)
900
+ class TaskData:
901
+ """Task data."""
902
+
903
+ challenge: Challenge = field(default_factory=Challenge)
904
+ group: GroupTask = field(default_factory=GroupTask)
905
+ Type: TaskType | None = field(default=None, metadata=field_options(alias="type"))
906
+ text: str | None = None
907
+ notes: str | None = None
908
+ tags: list[UUID] | None = None
909
+ value: float | None = None
910
+ priority: TaskPriority | None = None
911
+ attribute: Attributes | None = None
912
+ byHabitica: bool | None = None
913
+ createdAt: datetime | None = None
914
+ updatedAt: datetime | None = None
915
+ date: datetime | None = None
916
+ id: UUID | None = None
917
+ userId: UUID | None = None
918
+ up: bool | None = None
919
+ down: bool | None = None
920
+ counterUp: int | None = None
921
+ counterDown: int | None = None
922
+ frequency: Frequency | None = None
923
+ history: list[EntryHistory] | None = None
924
+ alias: str | None = None
925
+ everyX: int | None = None
926
+ startDate: datetime | None = None
927
+ streak: int | None = None
928
+ reminders: list[Reminders] = field(default_factory=list)
929
+ daysOfMonth: list[int] = field(default_factory=list)
930
+ weeksOfMonth: list[int] = field(default_factory=list)
931
+ nextDue: list[datetime] = field(
932
+ default_factory=list,
933
+ metadata=field_options(deserialize=lambda x: list(map(serialize_datetime, x))),
934
+ )
935
+ yesterDaily: bool | None = None
936
+ completed: bool | None = None
937
+ collapseChecklist: bool = False
938
+ checklist: list[str] = field(default_factory=list)
939
+ isDue: bool | None = None
940
+ repeat: Repeat = field(default_factory=Repeat)
941
+
942
+
943
+ @dataclass(kw_only=True)
944
+ class HabiticaTasksResponse(HabiticaResponse):
945
+ """Repesentation of a tasks data response."""
946
+
947
+ data: list[TaskData]
948
+
949
+
950
+ @dataclass(kw_only=True)
951
+ class HabiticaTaskResponse(HabiticaResponse):
952
+ """Repesentation of a single task data response."""
953
+
954
+ data: TaskData
955
+
956
+
957
+ @dataclass(kw_only=True)
958
+ class HabiticaErrorResponse(DataClassORJSONMixin):
959
+ """Base class for Habitica errors."""
960
+
961
+ success: bool
962
+ error: str
963
+ message: str
964
+
965
+
966
+ @dataclass(kw_only=True)
967
+ class TasksUserExport:
968
+ """Tasks user export data."""
969
+
970
+ todos: list[TaskData] = field(default_factory=list)
971
+ dailys: list[TaskData] = field(default_factory=list)
972
+ habits: list[TaskData] = field(default_factory=list)
973
+ rewards: list[TaskData] = field(default_factory=list)
974
+
975
+
976
+ @dataclass(kw_only=True)
977
+ class BuffsUserStyles:
978
+ """Buffs UserStyles data."""
979
+
980
+ per: int | None = None
981
+ con: int | None = None
982
+ stealth: int | None = None
983
+ seafoam: bool | None = None
984
+ shinySeed: bool | None = None
985
+ snowball: bool | None = None
986
+ spookySparkles: bool | None = None
987
+
988
+
989
+ @dataclass(kw_only=True)
990
+ class StatsUserStyles:
991
+ """Stats user styles data."""
992
+
993
+ buffs: BuffsUserStyles = field(default_factory=BuffsUserStyles)
994
+ Class: HabiticaClass = field(default=HabiticaClass.WARRIOR)
995
+
996
+
997
+ @dataclass(kw_only=True)
998
+ class GearItemsUserStyles:
999
+ """Items gear data."""
1000
+
1001
+ equipped: EquippedGear = field(default_factory=EquippedGear)
1002
+ costume: EquippedGear = field(default_factory=EquippedGear)
1003
+
1004
+
1005
+ @dataclass(kw_only=True)
1006
+ class ItemsUserStyles:
1007
+ """Items user styles data."""
1008
+
1009
+ gear: GearItemsUserStyles = field(default_factory=GearItemsUserStyles)
1010
+ currentMount: str | None = None
1011
+ currentPet: str | None = None
1012
+
1013
+
1014
+ @dataclass(kw_only=True)
1015
+ class PreferencesUserStyles:
1016
+ """Preferences user styles data."""
1017
+
1018
+ hair: HairPreferences = field(default_factory=HairPreferences)
1019
+ size: str | None = None
1020
+ skin: str | None = None
1021
+ shirt: str | None = None
1022
+ chair: str | None = None
1023
+ costume: bool | None = None
1024
+ sleep: bool | None = None
1025
+ background: str | None = None
1026
+
1027
+
1028
+ @dataclass(kw_only=True)
1029
+ class UserStyles(DataClassORJSONMixin):
1030
+ """Represents minimalistic data only containing user styles."""
1031
+
1032
+ items: ItemsUserStyles = field(default_factory=ItemsUserStyles)
1033
+ preferences: PreferencesUserStyles = field(default_factory=PreferencesUserStyles)
1034
+ stats: StatsUserStyles = field(default_factory=StatsUserStyles)
1035
+
1036
+
1037
+ @dataclass(kw_only=True)
1038
+ class HabiticaUserExport(UserData, DataClassORJSONMixin):
1039
+ """Representation of a user data export."""
1040
+
1041
+ tasks: TasksUserExport = field(default_factory=TasksUserExport)
1042
+
1043
+
1044
+ @dataclass(kw_only=True)
1045
+ class HabiticaStatsResponse(HabiticaResponse):
1046
+ """Representation of a response containing stats data."""
1047
+
1048
+ data: StatsUser
1049
+
1050
+
1051
+ @dataclass(kw_only=True)
1052
+ class QuestTmpScore:
1053
+ """Represents the quest progress details."""
1054
+
1055
+ progressDelta: float | None = None
1056
+ collection: int | None = None
1057
+
1058
+
1059
+ @dataclass(kw_only=True)
1060
+ class DropTmpScore:
1061
+ """Represents the details of an item drop."""
1062
+
1063
+ target: str | None = None
1064
+ canDrop: bool | None = None
1065
+ value: int | None = None
1066
+ key: str | None = None
1067
+ Type: str | None = field(default=None, metadata=field_options(alias="type"))
1068
+ dialog: str | None = None
1069
+
1070
+
1071
+ @dataclass(kw_only=True)
1072
+ class TmpScore:
1073
+ """Temporary quest and drop data."""
1074
+
1075
+ quest: QuestTmpScore = field(default_factory=QuestTmpScore)
1076
+ drop: DropTmpScore = field(default_factory=DropTmpScore)
1077
+
1078
+
1079
+ @dataclass
1080
+ class ScoreData(StatsUser):
1081
+ """Scora data."""
1082
+
1083
+ delta: float | None = None
1084
+ tmp: TmpScore = field(
1085
+ default_factory=TmpScore, metadata=field_options(alias="_tmp")
1086
+ )
1087
+
1088
+
1089
+ @dataclass(kw_only=True)
1090
+ class HabiticaScoreResponse(HabiticaResponse, DataClassORJSONMixin):
1091
+ """Representation of a score response."""
1092
+
1093
+ data: ScoreData
1094
+
1095
+
1096
+ @dataclass(kw_only=True)
1097
+ class HabiticaTagsResponse(HabiticaResponse, DataClassORJSONMixin):
1098
+ """Representation of a score response."""
1099
+
1100
+ data: list[TagsUser]
1101
+
1102
+
1103
+ @dataclass(kw_only=True)
1104
+ class HabiticaTagResponse(HabiticaResponse, DataClassORJSONMixin):
1105
+ """Representation of a score response."""
1106
+
1107
+ data: TagsUser
1108
+
1109
+
1110
+ @dataclass
1111
+ class ChangeClassData:
1112
+ """Change class data."""
1113
+
1114
+ preferences: PreferencesUser = field(default_factory=PreferencesUser)
1115
+ flags: FlagsUser = field(default_factory=FlagsUser)
1116
+ items: ItemsUser = field(default_factory=ItemsUser)
1117
+ stats: StatsUser = field(default_factory=StatsUser)
1118
+
1119
+
1120
+ @dataclass(kw_only=True)
1121
+ class HabiticaClassSystemResponse(HabiticaResponse, DataClassORJSONMixin):
1122
+ """Representation of a change-class response."""
1123
+
1124
+ data: ChangeClassData
1125
+
1126
+
1127
+ @dataclass
1128
+ class HabiticaTaskOrderResponse(HabiticaResponse):
1129
+ """Representation of a reorder task response."""
1130
+
1131
+ data: list[UUID] = field(default_factory=list)
1132
+
1133
+
1134
+ class TaskFilter(StrEnum):
1135
+ """Enum representing the valid types of tasks for requests."""
1136
+
1137
+ HABITS = "habits"
1138
+ DAILYS = "dailys"
1139
+ TODOS = "todos"
1140
+ REWARDS = "rewards"
1141
+ COMPLETED_TODOS = "completedTodos"
1142
+
1143
+
1144
+ class Language(StrEnum):
1145
+ """Valid languages for Habitica content."""
1146
+
1147
+ BG = "bg"
1148
+ CS = "cs"
1149
+ DA = "da"
1150
+ DE = "de"
1151
+ EN = "en"
1152
+ EN_PIRATE = "en@pirate"
1153
+ EN_GB = "en_GB"
1154
+ ES = "es"
1155
+ ES_419 = "es_419"
1156
+ FR = "fr"
1157
+ HE = "he"
1158
+ HU = "hu"
1159
+ ID = "id"
1160
+ IT = "it"
1161
+ JA = "ja"
1162
+ NL = "nl"
1163
+ PL = "pl"
1164
+ PT = "pt"
1165
+ PT_BR = "pt_BR"
1166
+ RO = "ro"
1167
+ RU = "ru"
1168
+ SK = "sk"
1169
+ SR = "sr"
1170
+ SV = "sv"
1171
+ UK = "uk"
1172
+ ZH = "zh"
1173
+ ZH_TW = "zh_TW"
1174
+
1175
+
1176
+ class Skill(StrEnum):
1177
+ """Skills or spells available for casting."""
1178
+
1179
+ # Mage skills
1180
+ BURST_OF_FLAMES = "fireball"
1181
+ ETHEREAL_SURGE = "mpheal"
1182
+ EARTHQUAKE = "earth"
1183
+ CHILLING_FROST = "frost"
1184
+ # Warrior skills
1185
+ BRUTAL_SMASH = "smash"
1186
+ DEFENSIVE_STANCE = "defensiveStance"
1187
+ VALOROUS_PRESENCE = "valorousPresence"
1188
+ INTIMIDATING_GAZE = "intimidate"
1189
+ # Rogue skills
1190
+ PICKPOCKET = "Pickpocket"
1191
+ BACKSTAB = "backStab"
1192
+ TOOLS_OF_THE_TRADE = "toolsOfTrade"
1193
+ STEALTH = "stealth"
1194
+ # Healer skills
1195
+ HEALING_LIGHT = "heal"
1196
+ PROTECTIVE_AURA = "protectAura"
1197
+ SEARING_BRIGHTNESS = "brightness"
1198
+ BLESSING = "healAll"
1199
+ # Transformation buffs
1200
+ SNOWBALL = "snowball"
1201
+ SPOOKY_SPARKLES = "spookySparkles"
1202
+ SEAFOAM = "seafoam"
1203
+ SHINY_SEED = "shinySeed"
1204
+ # Debuff potions
1205
+ SALT = "salt" # removes snowball buff
1206
+ OPAQUE_POTION = "opaquePotion" # removes spooky sparkles buff
1207
+ SAND = "sand" # removes seafoam buff
1208
+ PETAL_FREE_POTION = "petalFreePotion"
1209
+
1210
+
1211
+ class Direction(StrEnum):
1212
+ """Direction to score a task."""
1213
+
1214
+ UP = "up"
1215
+ DOWN = "down"
1216
+
1217
+
1218
+ class TaskPriority(Enum):
1219
+ """Task difficulties."""
1220
+
1221
+ TRIVIAL = 0.1
1222
+ EASY = 1
1223
+ MEDIUM = 1.5
1224
+ HARD = 2