artemis-model 0.1.80__py3-none-any.whl → 0.1.86__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.
- artemis_model/__init__.py +1 -0
- artemis_model/auth.py +9 -0
- artemis_model/device.py +78 -0
- {artemis_model-0.1.80.dist-info → artemis_model-0.1.86.dist-info}/METADATA +2 -2
- {artemis_model-0.1.80.dist-info → artemis_model-0.1.86.dist-info}/RECORD +6 -5
- {artemis_model-0.1.80.dist-info → artemis_model-0.1.86.dist-info}/WHEEL +1 -1
artemis_model/__init__.py
CHANGED
artemis_model/auth.py
CHANGED
@@ -63,6 +63,15 @@ class UserAccountMixin(TimeStampMixin):
|
|
63
63
|
disabled_reason: Mapped[Optional[str]] = mapped_column(nullable=True)
|
64
64
|
is_onboarded: Mapped[bool] = mapped_column(default=False)
|
65
65
|
|
66
|
+
|
67
|
+
@declared_attr
|
68
|
+
def devices(cls) -> Mapped[list["Device"]]:
|
69
|
+
return relationship(
|
70
|
+
"Device",
|
71
|
+
secondary="device_user_assoc", # Directly reference the association table
|
72
|
+
back_populates="users",
|
73
|
+
)
|
74
|
+
|
66
75
|
@declared_attr
|
67
76
|
def login_histories(cls) -> Mapped["LoginHistory"]:
|
68
77
|
return relationship("LoginHistory", back_populates="account")
|
artemis_model/device.py
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
import enum
|
2
|
+
import uuid
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
from sqlalchemy import JSON, UUID, Enum, ForeignKey
|
6
|
+
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
7
|
+
from sqlalchemy.ext.declarative import declared_attr
|
8
|
+
from sqlalchemy.ext.associationproxy import AssociationProxy, association_proxy
|
9
|
+
|
10
|
+
from artemis_model.base import CustomSyncBase, CustomBase, TimeStampMixin
|
11
|
+
|
12
|
+
|
13
|
+
class DeviceControlMode(enum.Enum):
|
14
|
+
PLAYER = "player"
|
15
|
+
CONTROL = "control"
|
16
|
+
|
17
|
+
|
18
|
+
class DeviceMixin(TimeStampMixin):
|
19
|
+
"""
|
20
|
+
Represents a Jukebox device that can be controlled by multiple users.
|
21
|
+
"""
|
22
|
+
id: Mapped[uuid.UUID] = mapped_column(
|
23
|
+
UUID(as_uuid=True), primary_key=True, default=uuid.uuid4
|
24
|
+
)
|
25
|
+
device_id: Mapped[str] = mapped_column(nullable=False, unique=True, index=True)
|
26
|
+
name: Mapped[str] = mapped_column(nullable=False) # e.g., "Living Room Jukebox"
|
27
|
+
control_mode: Mapped[DeviceControlMode] = mapped_column(Enum(DeviceControlMode), nullable=True)
|
28
|
+
last_seen: Mapped[datetime | None] = mapped_column(nullable=True)
|
29
|
+
version: Mapped[int] = mapped_column(default=0)
|
30
|
+
device_specs: Mapped[JSON] = mapped_column(JSON, nullable=True)
|
31
|
+
|
32
|
+
@declared_attr
|
33
|
+
def device_user_assoc(cls) -> Mapped[list["DeviceUserAssoc"]]:
|
34
|
+
return relationship(cascade="all, delete-orphan")
|
35
|
+
|
36
|
+
@declared_attr
|
37
|
+
def user_ids(cls) -> Mapped[list["UserAccount"] | None]:
|
38
|
+
return association_proxy(
|
39
|
+
"device_user_assoc",
|
40
|
+
"user",
|
41
|
+
creator=lambda u: DeviceUserAssoc(user_id=u),
|
42
|
+
)
|
43
|
+
|
44
|
+
@declared_attr
|
45
|
+
def users(cls) -> Mapped[list["UserAccount"]]:
|
46
|
+
return relationship(
|
47
|
+
secondary="device_user_assoc",
|
48
|
+
viewonly=True
|
49
|
+
)
|
50
|
+
|
51
|
+
|
52
|
+
class DeviceSync(CustomSyncBase, DeviceMixin):
|
53
|
+
pass
|
54
|
+
|
55
|
+
|
56
|
+
class Device(CustomBase, DeviceMixin):
|
57
|
+
pass
|
58
|
+
|
59
|
+
|
60
|
+
class DeviceUserAssocMixin(TimeStampMixin):
|
61
|
+
"""
|
62
|
+
Association table for many-to-many relationship between UserAccount and Device.
|
63
|
+
"""
|
64
|
+
|
65
|
+
device_id: Mapped[uuid.UUID] = mapped_column(
|
66
|
+
ForeignKey("device.id"), primary_key=True, nullable=False
|
67
|
+
)
|
68
|
+
user_id: Mapped[uuid.UUID] = mapped_column(
|
69
|
+
ForeignKey("user_account.id"), primary_key=True, nullable=False
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
class DeviceUserAssocSync(CustomSyncBase, DeviceUserAssocMixin):
|
74
|
+
pass
|
75
|
+
|
76
|
+
|
77
|
+
class DeviceUserAssoc(CustomBase, DeviceUserAssocMixin):
|
78
|
+
pass
|
@@ -1,9 +1,10 @@
|
|
1
|
-
artemis_model/__init__.py,sha256=
|
1
|
+
artemis_model/__init__.py,sha256=ppr3Y8tA0RIhszLWNEIL2eIXzj8ho833nbrejsXPuMk,735
|
2
2
|
artemis_model/album.py,sha256=cnjrE0catTK24uWTrAoRcZUQB3CPt5l8s9PeM2sxLrc,2103
|
3
3
|
artemis_model/artist.py,sha256=Mx2bnl7bxqm2ELjDIePGFfIkQU_DbnfOTc507dzh14g,1577
|
4
|
-
artemis_model/auth.py,sha256=
|
4
|
+
artemis_model/auth.py,sha256=aJc7G1Uf5zpRXE5ULEoVKcICm45uahhJzb2xhB2yPhM,4340
|
5
5
|
artemis_model/base.py,sha256=21Isonytb_iWfmde4u8LiU6a27h7mkgnwncTAKi9ezY,6768
|
6
6
|
artemis_model/category.py,sha256=jhCZrK-LxPmc0pXmVifAZWdCENssBTzdTmC3nqqZc6s,1761
|
7
|
+
artemis_model/device.py,sha256=B9H2X6GOtuUcgSMo0jUIf4GHlR36DhL0eBqy7QYhDqY,2375
|
7
8
|
artemis_model/dj_set.py,sha256=-0rU2xOAJ4vecite8yKFmp9yFLPZurFrdFmYAjPHtso,3848
|
8
9
|
artemis_model/genre.py,sha256=oMs1ZZfr0SZWmWzW9PEPuaNcatfeIx53nk5M3DPodrQ,1615
|
9
10
|
artemis_model/location.py,sha256=T6TlUCXxGyicYtb39dw7XjbCSNECZnMPYahxtOtyEiE,4687
|
@@ -17,6 +18,6 @@ artemis_model/setting.py,sha256=McWbeDZP45km3VSSwP1BgAmmjO4qCL0pTnOmJVAz0WI,1265
|
|
17
18
|
artemis_model/track.py,sha256=x8BHKDZl9uQmQH6DWpzH-SEsfecLghOBdBT7qXgN3d0,3865
|
18
19
|
artemis_model/user.py,sha256=ZtZVwavSPoQmYM1_MarMULy-DJa2pH482G_G8su0b6c,2211
|
19
20
|
artemis_model/zone.py,sha256=iGRUtzUwKh9LHT3MOfzzg1DnkPBts_ZBzZVTi2EmIgs,2282
|
20
|
-
artemis_model-0.1.
|
21
|
-
artemis_model-0.1.
|
22
|
-
artemis_model-0.1.
|
21
|
+
artemis_model-0.1.86.dist-info/METADATA,sha256=Ruxd_li94elI2qUbqKx5C2gttLU4gmTr1owPz9BIQkA,3402
|
22
|
+
artemis_model-0.1.86.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
23
|
+
artemis_model-0.1.86.dist-info/RECORD,,
|