2023-10-22 00:39:40 +00:00
|
|
|
from typing import Literal
|
|
|
|
from . import cloudkit_pb2
|
2023-10-21 19:53:13 +00:00
|
|
|
import uuid
|
2023-10-22 00:39:40 +00:00
|
|
|
import dataclasses
|
|
|
|
import typing
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
@dataclasses.dataclass
|
|
|
|
class Record:
|
|
|
|
name: uuid.UUID
|
|
|
|
type: str
|
|
|
|
fields: dict[str, typing.Any]
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
def build_record_save_request(
|
|
|
|
record: Record,
|
|
|
|
container: str,
|
|
|
|
sandbox: bool = False,
|
|
|
|
database: Literal["PUBLIC"] | Literal["PRIVATE"] | Literal["SHARED"] = "PUBLIC",
|
|
|
|
zone: str = "_defaultZone",
|
|
|
|
owner: str = "_defaultOwner",
|
|
|
|
):
|
|
|
|
MAGIC_BYTES = b"\xfe\x03"
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
hardware_id = uuid.uuid4() # Generate a new hardware ID for each request?
|
|
|
|
operation_uuid = uuid.uuid4() # Generate a new operation UUID for each request?
|
|
|
|
record_id = uuid.uuid4() # Generate a new record ID for each request?
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request = cloudkit_pb2.RequestOperation()
|
|
|
|
request.header.applicationContainer = container
|
|
|
|
request.header.applicationContainerEnvironment = cloudkit_pb2.RequestOperation.Header.ContainerEnvironment.SANDBOX if sandbox else cloudkit_pb2.RequestOperation.Header.ContainerEnvironment.PRODUCTION
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.header.deviceHardwareID = str(hardware_id).upper()
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
if database == "PUBLIC":
|
|
|
|
request.header.targetDatabase = cloudkit_pb2.RequestOperation.Header.Database.PUBLIC_DB
|
|
|
|
elif database == "PRIVATE":
|
|
|
|
request.header.targetDatabase = cloudkit_pb2.RequestOperation.Header.Database.PRIVATE_DB
|
|
|
|
elif database == "SHARED":
|
|
|
|
request.header.targetDatabase = cloudkit_pb2.RequestOperation.Header.Database.SHARED_DB
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.header.isolationLevel = cloudkit_pb2.RequestOperation.Header.IsolationLevel.ZONE
|
2023-10-21 19:53:13 +00:00
|
|
|
|
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.request.operationUUID = str(operation_uuid).upper()
|
|
|
|
request.request.type = cloudkit_pb2.Operation.Type.RECORD_SAVE_TYPE
|
|
|
|
request.request.last = True
|
2023-10-21 19:53:13 +00:00
|
|
|
|
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.recordSaveRequest.record.recordIdentifier.value.name = str(record_id).upper()
|
|
|
|
request.recordSaveRequest.record.recordIdentifier.value.type = cloudkit_pb2.Identifier.Type.RECORD
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.value.name = zone
|
|
|
|
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.value.type = cloudkit_pb2.Identifier.Type.RECORD_ZONE
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.ownerIdentifier.name = owner
|
|
|
|
request.recordSaveRequest.record.recordIdentifier.zoneIdentifier.ownerIdentifier.type = cloudkit_pb2.Identifier.Type.USER
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
request.recordSaveRequest.record.type.name = record.type
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
for key, value in record.fields.items():
|
|
|
|
request.recordSaveRequest.record.recordField.append(cloudkit_pb2.Record.Field())
|
|
|
|
request.recordSaveRequest.record.recordField[-1].identifier.name = key
|
|
|
|
request.recordSaveRequest.record.recordField[-1].value.type = cloudkit_pb2.Record.Field.Value.Type.STRING_TYPE
|
|
|
|
request.recordSaveRequest.record.recordField[-1].value.stringValue = value
|
2023-10-21 19:53:13 +00:00
|
|
|
|
2023-10-22 00:39:40 +00:00
|
|
|
return MAGIC_BYTES + request.SerializeToString()
|